-
-
Notifications
You must be signed in to change notification settings - Fork 31
feat(utils): add shebang #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
utils/src/ast-grep/shebang.test.ts
Outdated
| it('should take the last shebang line if multiple exist on top of the code', () => { | ||
| const code = dedent` | ||
| #!/usr/bin/env node 1 | ||
| #!/usr/bin/env node 2 |
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 this is actually not the correct behaviour: I think it's first-wins (not last-wins). I couldn't quickly find an authoritative source specifying what happens, but a quick search pulls up many StackExchange answers all claiming this, as well as some blogs. I didn't find anything that claims anything else.
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 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, it's telling you all the ones after the first are invalid.
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.
so it's maybe an tree-sitter/ast-grep issue
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.
Maaaaybe? This shebang util is invalid until whatever the issue is is fixed 😥
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.
Hi, the issue comes from tree-sitter parser's implementation. The grammar only supports one single hashbang line. See
This is correct grammar according to the spec, https://tc39.es/ecma262/#sec-hashbang, the shebang appears only at the top of a module/script and should be only oneline. https://github.com/tc39/ecma262/pull/2816/changes
That said, the tree-sitter error recovery is treating the last hash_bang_line as correct instead of the first.
utils/src/ast-grep/shebang.ts
Outdated
| * @param root The root node to search. | ||
| * @returns The shebang line if found, otherwise null. | ||
| */ | ||
| export const getShebang = (root: SgRoot) => |
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 would probably add a second, optional arg for replacements so users can do it in one go like:
const sb = getShebang(…, { foo: 'bar' });instead of
const sbRaw = getShebang(…);
const sb = replaceNodeJsArgs(sbRaw, { foo: 'bar' });I would keep replaceNodeJsArgs as a separate function that getShebang calls internally when the second arg is present.
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 was designed like package.json utilizes:
/**
* Replace Node.js arguments in the "scripts" node of a package.json AST.
* @param packageJsonRootNode The root node of the package.json AST.
* @param argsToValues A record mapping arguments to their replacement values.
* @param edits An array to collect the edits made.
*/
export const replaceNodeJsArgs = (packageJsonRootNode: SgRoot, argsToValues: Record<string, 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.
Hmm? I don't understand
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 don't get your proposition here.
We will have twoo function called replaceNodeJsArgs one in shebang utility and the other in the package json utility which already exist and they will be called in different context but I want to have same signature for these functions for a better DX
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 the other one doesn't deal with replacements, then keeping the same signature doesn't really fit. If the other one does deal with replacements, then they should both do it 🙂
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.
IDK what is the best
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 was more of a nit; it's an additive change (non-breaking), so it could be addressed later.
Co-Authored-By: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
| */ | ||
| export const getShebang = (root: SgRoot) => | ||
| root.root().find({ | ||
| rule: { |
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 a reasonable fix here would be find the first hash_bang_line in the tree.
According to the grammar spec
There are several situations where the identification of lexical input elements is sensitive to the syntactic grammar context that is consuming the input elements. This requires multiple goal symbols for the lexical grammar. The InputElementHashbangOrRegExp goal is used at the start of a Script or Module.
Co-Authored-By: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
JakobJingleheimer
left a comment
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.
🙌

Description
Introducing new utilities to manage args in shebangs
Related issue
Related to #94