-
Notifications
You must be signed in to change notification settings - Fork 0
Add stream event listener argument to resolveInput() #29
Conversation
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.
See issue #28 for a description of what this PR intends to achieve.
@@ -0,0 +1,4009 @@ | |||
{ |
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.
To recap / confirm the recommended practice, it is desirable to add package-lock files to libraries (such as resin-bundle-resolve) but not to "apps" installed by users (such as balena-cli); is this right?
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 the opposite @pdcastro , we definitely want them in apps, but we don't care as much in libraries. That being said, having them in libraries too can be useful to ensure a consistent CI build.
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.
But there was a good reason why balena-cli
does not commit package-lock.json
(it is in .gitignore
), while the libs imported by the CLI can/should have package-lock.json
files. @thgreasi, you might remember what the reason was... I think it was to do with we not having control over the customer's environment -- like, package-lock.json
was ignored (?) in some cases or platforms (?), so we wanted the CI to try installing the latest versions of whatever is in package.json
-- but I am not able to fully justify it to myself. :-)
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 believe @Page- also has some theories on this too.
dockerfile?: string, | ||
): Readable { |
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.
tar.Pack implements the Readable interface, so this should be a "safe" change. Some callers of resolveInput were doing explicit cast from Pack to Readable, and this change avoids the need 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.
It used to be that the typings were incompatible iirc, but if it's all working well now then I agree this is worth it.
@@ -7,7 +7,7 @@ | |||
"declaration": true, | |||
"pretty": true, | |||
"removeComments": true, | |||
"skipLibCheck": true, |
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.
Needed because tsc
was failing in type checks for the strict-event-emitter-types
package. The skipLibCheck
flag is used in many other balena packages.
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.
Yep, should definitely be included.
const extract = tar.extract(); | ||
const pack = tar.pack(); | ||
for (const event of Object.keys(resolveListeners) as Array< |
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 should be able to do:
for (const event of Object.keys(resolveListeners) as Array< | |
for (const event in resolveListeners) |
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.
If I write it like that (in
and no type cast), then on the following line I get a compiler error:
src/index.ts:75:21 - error TS7017: Element implicitly has an 'any' type because type 'ResolveListeners' has no index signature.
75 const listeners = resolveListeners[event] || [];
Also, the in
operator iterates over all of the object's prototype chain's properties (which in some cases results in the linter warning that the for loop needs an if
test for "own properties"), while Object.keys()
returns the keys for the object's own properties only.
const listeners = resolveListeners[event] || []; | ||
for (const listener of listeners) { | ||
pack.on(event, listener); | ||
} |
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 already have lodash imported here so this could be
_.each(resolveListeners, (cbs, event) => _.each(cbs, cb => pack.on(event, cb)))
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.
If I do it like that, then the compiler errors:
src/index.ts:83:36 - error TS2345: Argument of type 'number | ((chunk: string | Buffer) => void) | ((e: Error) => void) | ((...items: (() => void)[]) ...' is not assignable to parameter of type 'Function'.
Type 'number' is not assignable to type 'Function'.
83 _.each(cbs, cb => pack.on(event, cb)),
Also:
npm run prettify
expands it to a minimum of 3 lines of code, so the one-liner temptation is partially spoiled.- I find the nested callbacks slightly harder to read than the nested for loops (one needs to be familiar with lodash's callback arguments...).
I can however reduce one line of code by removing the const listeners
variable declaration:
for (const event of Object.keys(resolveListeners) as Array<
keyof ResolveListeners
>) {
for (const listener of resolveListeners[event] || []) {
pack.on(event, listener);
}
}
300ea2f
to
e3df60b
Compare
export function resolveInput( | ||
bundle: Bundle, | ||
resolvers: Resolver[], | ||
resolveListeners: ResolveListeners, |
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 added argument is the reason for a major version bump.
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.
Why not put it last and make it optional?
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.
Yes, I thought about making it optional, it could be done. But then I considered that not providing this argument and thus potentially ignoring error events is "almost certainly a bug" and the function interface should discourage it. Adding this argument is the main purpose of this PR. Before this change, there wasn't a foolproof way of providing an error handler for the stream events. Making this arg optional would be like making the improvement optional...
e3df60b
to
a61834b
Compare
src/index.ts
Outdated
}); | ||
}); | ||
entry.stream.pipe(newEntryStream); | ||
await newEntryStreamPromise; |
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.
The ~10 lines above (newEntryStreamPromise
) were necessary to avoid a tar-stream
limitation by which it is only possible to pipe to one pack.entry
at a time -- so it's necessary to wait for the 'finish' event on one entry before moving on to the next entry. Some resin-builder
tests were failing with the tar-stream error "Error: already piping an entry"
. More details here: mafintosh/tar-stream#24 (comment)
)) || specifiedFileResolver; | ||
} catch (error) { | ||
console.log('resin-bundle-resolve extract entry -> error', error); | ||
pack.emit('error', error); |
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.
Some errors thrown in stream listeners were not being caught, so I added the try-catch above and "forwarded" the errors through pack.emit('error')
.
'resin-bundle-resolve extract on finish calling pack.finalize()', | ||
); | ||
pack.finalize(); | ||
} |
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.
Some errors thrown in stream listeners were not being caught and pack.finalize()
not called, so I added the try-catch-finally above and "forwarded" the errors through pack.emit('error')
.
a61834b
to
f5c2d7b
Compare
0142f33
to
f8de286
Compare
(semver 'major' change because this commit makes the resolveInput function incompatible with previous major versions by adding a new required argument.) Change-type: major Signed-off-by: Paulo Castro <paulo@balena.io>
f8de286
to
811ceba
Compare
Resolves: #28
Change-type: major
Signed-off-by: Paulo Castro paulo@balena.io