-
Notifications
You must be signed in to change notification settings - Fork 0
Conversation
There doesn't appear to be a package.json |
Ok, it appears that the package.json with all dependencies included is in the initial commit - it would be nicer to have the dependencies as part of this PR |
src/index.ts
Outdated
const pack = tar.pack() | ||
|
||
return Promise.all( | ||
Promise.resolve(fs.readdir(dirPath)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably nicer to use Promise.promisify
for this once rather than having to convert the promise every time we call an mz/fs
function
src/index.ts
Outdated
public buildDir(dirPath: string, buildOpts: Object, hooks: Plugin.IBuildHooks): Promise<NodeJS.ReadableStream> { | ||
const pack = tar.pack() | ||
|
||
return Promise.all( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like you're doing a Promise.all
over a single promise argument? I'm guessing this is either a leftover or something got dropped by accident
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, that was from when I was mapping over the synchronous fs functions.
src/index.ts
Outdated
|
||
this.layers = [] | ||
|
||
if (hooks == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can add the default to the func declaration, eg
public createBuildStream(buildOpts: Object, hooks: Plugin.IBuildHooks = {}): NodeJS.ReadWriteStream {
src/index.ts
Outdated
if (hook in hooks) { | ||
// Spread the arguments onto the callback function | ||
const fn = hooks[hook] | ||
if (fn !== undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using _.isFunction(fn)
probably makes more sense
src/index.ts
Outdated
* @returns {any} The return value of the function, or nothing if the | ||
* function does not exist or does not provide a return value | ||
*/ | ||
private callHook = (hooks: Plugin.IBuildHooks, hook: string, ...args: any[]) : any => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the =
meant to be in here?
Yeah with the package.json I wasn't sure because I wanted it there for @hedss' versionist to merge this PR but wasn't sure going through another PR made any sense. Both ways felt a bit janky tbh. |
lib/plugin.d.ts
Outdated
* Because of this the minimum recommended registered hooks are buildSuccess and buildFailure, | ||
* but this is not enforced, or required. | ||
*/ | ||
export interface IBuildHooks { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @pimterry has pointed out in another review (which I'm really sorry, I can't find), the denoted way to define interfaces is without the I
. And in fact, MS recommend you don't:
microsoft/TypeScript-Handbook#121
Personally, I don't mind. But if we prefix I
for interfaces, then are we going to use shortened HN elsewhere? I think this probably needs to be specific in the TS spec. (though for some reason I thought I had put it in there).
And sorry this comment is so late!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I shouldn't have been listening to the default tslint config. I don't like to prefix them with I
anyway :).
5655d56
to
a12a325
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TSwise, I think it looks ok (apart from my one comment, which applies in quite a few places).
@pimterry will probably have more. :)
src/example/project-type.ts
Outdated
private templateContent: string = '' | ||
|
||
public provideEntry(stream: NodeJS.ReadableStream, header: any): boolean { | ||
// Check if this is a file we need to be able to generate the dockerfile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the consensus was we were going to allow implicit typing where possible, so as this method always returns a boolean, you won't need it declared in the signature.
Same is true elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous discussion: balena-io-modules/balena-procbots#5 (comment). I think the conclusion is:
- Definitely skip it (do implicit typing) if it's very obvious (
let x = new X()
) - Probably type things explicitly otherwise, to taste.
I think method return types are one case though where explicit types are particularly often useful though, and we should be including them. If you explicitly specify this return type, TypeScript checks every path through the method, and guarantees they all always return booleans. Easy to end up with an accidental implicit return or the wrong return type otherwise.
src/example/project-type.ts
Outdated
private templateContent: string = '' | ||
|
||
public provideEntry(stream: NodeJS.ReadableStream, header: any): boolean { | ||
// Check if this is a file we need to be able to generate the dockerfile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous discussion: balena-io-modules/balena-procbots#5 (comment). I think the conclusion is:
- Definitely skip it (do implicit typing) if it's very obvious (
let x = new X()
) - Probably type things explicitly otherwise, to taste.
I think method return types are one case though where explicit types are particularly often useful though, and we should be including them. If you explicitly specify this return type, TypeScript checks every path through the method, and guarantees they all always return booleans. Easy to end up with an accidental implicit return or the wrong return type otherwise.
src/example/app.ts
Outdated
console.log(`Image Id: ${imageId}`) | ||
console.log(`Image layers: ${JSON.stringify(layers, null, ' ')}`) | ||
}, | ||
buildFailure: (error: Error) : void => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: spacing for return types isn't consistent. Compare ) : void
here with ): void
above. Tiny point, and I don't really mind which way we go, but it'd be nice to pick a single style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's completely by accident :/ I was going for ): type
every time. The example code is being taken out in favour of a nice README anyway, but definitely need to watch out for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the conversation, LGTM apart from the other two points @pimterry raises.
src/plugin.d.ts
Outdated
/** | ||
* Index signature | ||
*/ | ||
[key: string]: ((...args: any[]) => any) | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's this index signature for? Is it because you want to support arbitrary other new hooks, and you don't know what they are somehow, or is it just because callHook won't compile otherwise?
If the former, fine, if the latter, you should be able to do this more tidily and statically safely with constant string literals. Here's a typescript playground that sort of demonstrates the idea.
src/tests/tests.ts
Outdated
|
||
// In general we don't want output, until we do. | ||
// call with `env DISPLAY_TEST_OUTPUT=1 npm test` to display output | ||
const dockerPath = process.env.DOCKER_PATH ? process.env.DOCKER_PATH : '/var/run/docker.sock' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this could just be process.env.DOCKER_PATH || '/var/run/docker.sock'
b826a0b
to
99b79b7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move the tests from /src/tests
to /tests
please, I expect /src
to only contain actual source code for the module (unless the /src/tests
is a typescript convention, @pimterry?)
src/utils.ts
Outdated
} | ||
|
||
const extractArrowMessage = (message: string): string | undefined => { | ||
const arrowTest = /^\s*-+>\s*(.+)/i |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need for the i
- there's nothing that is affected by case-sensitivity
src/builder.ts
Outdated
return fn.apply(null, args) | ||
} | ||
} | ||
return undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you explicity return undefined
, but in other places I see you just return
, it would be nice to be consistent (personally I prefer return
) - is this covered by the TS style guide?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, yeah I'll need to be consistent with this. The style guide unfortunately isn't ready but it was becoming a blocker. I don't mind going back through and doing a style overhaul, but I want to get the main semantics done.
src/builder.ts
Outdated
const relPath = path.join(dirPath, file) | ||
return Promise.all([file, fs.stat(relPath), fs.readFile(relPath)]) | ||
}) | ||
.map((fileInfo: any[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know the types for this will be [string, fs.Stats, Buffer]
- is there any reason we can't be explicit?
src/builder.ts
Outdated
const pack = tar.pack() | ||
|
||
return this.readdirBluebird(dirPath) | ||
.map((file: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you indent this to show more clearly that it's nested as part of the return
statement, rather than chaining directly from it eg with the current indentation I expect return(something).map().map()
semantics with a nested chain I would expect return (something.map().map()...)
semantics - maybe it's just me but it does feel like a decent styling
A clearer example might be that the current version feels to me a bit like
fn(this.readdirBluebird(dirPath)
.map((file: string) => {
})
.map()
)
src/builder.ts
Outdated
*/ | ||
public createBuildStream(buildOpts: Object, hooks: Plugin.BuildHooks = {}): NodeJS.ReadWriteStream { | ||
|
||
const instance = this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's common to use const self = this
for self-references
src/builder.ts
Outdated
constructor(dockerOpts: Dockerode.DockerOptions) { | ||
this.docker = new Dockerode(dockerOpts) | ||
|
||
// Promisify individual functions, to keep type information |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this meant to be // TODO:
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that's a classic case of comments not keeping up to date with code, nice catch. I actually struggled with getting promisification and TS to work nicely, and this seemed to be the best trade-off.
lib/builder.d.ts
Outdated
@@ -0,0 +1,64 @@ | |||
/// <reference types="node" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this file actually needed? Wouldn't TS dependants just point to the .ts
source directly in order to have types direct from the source code (and also be able to use "go to definition", etc), cc @pimterry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll prefix this comment by saying I've been piecing together the way to package up a TS library from various examples around the web so I'm not 100% that this is the way it should be done.
That said, it seems like the advantage to doing it this way is that the library can be consumed from plain JS, (and therefore all derivatives) and then if the library is being consumed from TS, the compiler will pull in the .d.ts
files in addition. It just means AFAIK that changes aren't needed to allow it to work out-of-the-box in both JS and TS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use:
"main": "lib/index.js",
"types": "src/index.ts",
and it should work as I described
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, nice! :)
build.sh
Outdated
@@ -0,0 +1,14 @@ | |||
#!/bin/bash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid bash-only building, it makes this module a bit trickier to use on windows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm not keen on that myself, definitely going to change it to something like a gruntfile, I've just never looked into it.
The |
package.json
Outdated
"test": "echo \"Error: no test specified\" && exit 1" | ||
"start": "", | ||
"build": "./build.sh", | ||
"test": "node_modules/.bin/mocha -r ts-node/register src/tests/tests.ts" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change node_modules/.bin/mocha
to just mocha
, it will be automatically pointed to the correct node_modules path by npm
There's definitely ways to have the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the js versions of the tests need to be committed? With the typescript loader I think the tests should be able to be run directly without having to write the js to disk
tsconfig.json
Outdated
@@ -12,6 +11,7 @@ | |||
}, | |||
"exclude": [ | |||
"node_modules", | |||
"lib" | |||
"lib", | |||
"tests" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonky indentation here
package.json
Outdated
"description": "A containerised builder which interacts with the docker remote API to perform builds.", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"types": "srcr/index.ts", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
srcr
-> src
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow that's really weird, I wonder why the imported types were working from an external module... strange. Anyway, nice catch!
fc7158d
to
365c437
Compare
* Created plugin based architecture which modules users can hook into * Add tests * Add gulpfile * Add README * Add deps to package.json Signed-off-by: Cameron Diver <cameron@resin.io>
Last PR was closed by GH due to a force push (sorry!) so this PR is actually the previous, with comments addressed.
Last PR: #1