Skip to content

Conversation

@aomarks
Copy link
Member

@aomarks aomarks commented Feb 20, 2025

This PR introduces # as the new and preferred way to delimit the package and script portions of a dependency specifier, by way of a new dependency specifier parser. The : delimiter will remain supported indefinitely.

The goal of the new parser, and the new # delimiter, is to prepare for adding a number of new features to dependency specifiers, such as #23 (but see dependency-parser.ts for the actual list, the syntax has changed, I will update the issue). None of the new features are implemented in this PR, they will come in followups.

# was chosen as the new preferred delimiter because : is extremely common in npm script names, whereas # is uncommon in both paths and npm script names. This will allow us to differentiate between npmpackage:script (which becomes npmpackage#script) and localscript:withcolon. # is also the delimiter used by Turborepo, which seems like a slightly nice alignment.

@aomarks aomarks requested a review from rictic February 20, 2025 04:46
@aomarks aomarks changed the title New dependency specifier parser and introduction of # delimiter New dependency parser and introduce # delimiter Feb 20, 2025
Comment on lines +64 to +65
* | `<dependencies>:build` | All dependency "build" scripts ... |
* | `../broken:build` | ... except for the specific one in the "broken" folder. |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* | `<dependencies>:build` | All dependency "build" scripts ... |
* | `../broken:build` | ... except for the specific one in the "broken" folder. |
* | `<dependencies>#build` | All dependency "build" scripts ... |
* | `!../broken#build` | ... except for the specific one in the "broken" folder. |

Comment on lines +159 to +160
// Note this can be range can be longer than the length of `string`, since it
// includes escapes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably needs reflow

Suggested change
// Note this can be range can be longer than the length of `string`, since it
// includes escapes.
// Note the range can be longer than the length of `string`, since it
// includes escapes.

range: {offset: 0, length: 0},
},
script: script.value,
inverted,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm wondering if being inverted will ever make sense if the package kind this "this", so it might be disallowed by the parser?
perhaps we might have a wider special script value or support wildcards in script names where inversion by a specific script name only could make sense.

// path. We should support that edge case with backslash escaping.
const firstColonIdx = dependency.value.indexOf(':');
if (firstColonIdx === -1) {
const parsed = parseDependency(dependency.value);
Copy link
Collaborator

@augustjk augustjk Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a few lines above here i can't directly comment on but the jsdoc for this method mentions special syntax like "$WORKSPACES", which can be updated to <workspaces>.

Comment on lines +252 to +273
[
String.raw`./pkg\*#scr\*`,
String.raw`PPPPPPP_SSSSS`,
{
package: {kind: 'path', path: './pkg*'},
script: {kind: 'name', name: 'scr*'},
},
],
[
String.raw`./pkg\{foo,bar}#scr\{foo,bar}`,
String.raw`PPPPPPPPPPPPPPP_SSSSSSSSSSSSS`,
{
package: {
kind: 'path',
path: './pkg{foo,bar}',
},
script: {
kind: 'name',
name: 'scr{foo,bar}',
},
},
],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if/when * and {,} expands are supported, they wouldn't actually require backslash escapes, would they? these tests are simply demonstrating handling of unnecessary escapes?

],
[
String.raw`\./scr`,
String.raw`_SSSSS`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the leading \ for escaping considered part of the range?

Comment on lines +118 to +125
[
String.raw`\./scr`,
String.raw`_SSSSS`,
{
package: {kind: 'this'},
script: {kind: 'name', name: './scr'},
},
],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps an extra test case where leading escaped period \. with a # or : delimiter makes the first segment be interpreted as an npm package?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants