feat: add support for rangeless commands (#338)

This diff makes it possible to run the CLI commands without an explicit range, in which case we use an implicit `*`, e.g.: `corepack install -g yarn`.
This commit is contained in:
Maël Nison 2023-12-29 13:00:38 +01:00 committed by GitHub
parent 0717c6af89
commit 9bee415081
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 29 additions and 10 deletions

View File

@ -177,7 +177,7 @@ This command doesn't change the global version used when running the package
manager from outside the project (use the \`-g,--global\` flag if you wish manager from outside the project (use the \`-g,--global\` flag if you wish
to do this). to do this).
### `corepack install <-g,--global> [--all] [... name@version]` ### `corepack install <-g,--global> [--all] [... name[@<version>]]`
| Option | Description | | Option | Description |
| --------------------- | ------------------------------------------ | | --------------------- | ------------------------------------------ |
@ -189,7 +189,7 @@ Package managers thus installed will be configured as the new default when
calling their respective binaries outside of projects defining the calling their respective binaries outside of projects defining the
`packageManager` field. `packageManager` field.
### `corepack pack [--all] [... name@version]` ### `corepack pack [--all] [... name[@<version>]]`
| Option | Description | | Option | Description |
| --------------------- | ------------------------------------------ | | --------------------- | ------------------------------------------ |
@ -200,7 +200,7 @@ calling their respective binaries outside of projects defining the
Download the selected package managers and store them inside a tarball Download the selected package managers and store them inside a tarball
suitable for use with `corepack install -g`. suitable for use with `corepack install -g`.
### `corepack use <name@version>` ### `corepack use <name[@<version>]>`
When run, this command will retrieve the latest release matching the provided When run, this command will retrieve the latest release matching the provided
descriptor, assign it to the project's package.json file, and automatically descriptor, assign it to the project's package.json file, and automatically
@ -215,7 +215,7 @@ it.
Unlike `corepack use` this command doesn't take a package manager name nor a Unlike `corepack use` this command doesn't take a package manager name nor a
version range, as it will always select the latest available version from the version range, as it will always select the latest available version from the
same major line. Should you need to upgrade to a new major, use an explicit same major line. Should you need to upgrade to a new major, use an explicit
`corepack use {name}@latest` call. `corepack use {name}@latest` call (or simply `corepack use {name}`).
## Environment Variables ## Environment Variables

View File

@ -11,16 +11,16 @@ export function parseSpec(raw: unknown, source: string, {enforceExactVersion = t
if (typeof raw !== `string`) if (typeof raw !== `string`)
throw new UsageError(`Invalid package manager specification in ${source}; expected a string`); throw new UsageError(`Invalid package manager specification in ${source}; expected a string`);
const match = raw.match(/^(?!_)(.+)@(.+)$/); const match = raw.match(/^(?!_)([^@]+)(?:@(.+))?$/);
if (match === null || (enforceExactVersion && !semver.valid(match[2]))) if (match === null || (enforceExactVersion && (!match[2] || !semver.valid(match[2]))))
throw new UsageError(`Invalid package manager specification in ${source}; expected a semver version${enforceExactVersion ? `` : `, range, or tag`}`); throw new UsageError(`Invalid package manager specification in ${source} (${raw}); expected a semver version${enforceExactVersion ? `` : `, range, or tag`}`);
if (!isSupportedPackageManager(match[1])) if (!isSupportedPackageManager(match[1]))
throw new UsageError(`Unsupported package manager specification (${match})`); throw new UsageError(`Unsupported package manager specification (${match})`);
return { return {
name: match[1], name: match[1],
range: match[2], range: match[2] ?? `*`,
}; };
} }
@ -57,7 +57,7 @@ export async function findProjectSpec(initialCwd: string, locator: Locator, {tra
case `NoProject`: case `NoProject`:
case `NoSpec`: { case `NoSpec`: {
return fallbackLocator; return fallbackLocator;
} break; }
case `Found`: { case `Found`: {
if (result.spec.name !== locator.name) { if (result.spec.name !== locator.name) {
@ -69,7 +69,7 @@ export async function findProjectSpec(initialCwd: string, locator: Locator, {tra
} else { } else {
return result.spec; return result.spec;
} }
} break; }
} }
} }
} }

View File

@ -267,6 +267,25 @@ it(`should allow to call "corepack install -g" with a tag`, async () => {
}); });
}); });
it(`should allow to call "corepack install -g" without any range`, async () => {
await xfs.mktempPromise(async cwd => {
await expect(runCli(cwd, [`install`, `-g`, `yarn`])).resolves.toMatchObject({
exitCode: 0,
stderr: ``,
});
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {
// empty package.json file
});
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
stdout: expect.not.stringMatching(/^[123]\./),
stderr: ``,
exitCode: 0,
});
});
});
it(`should allow to call "corepack install" without arguments within a configured project`, async () => { it(`should allow to call "corepack install" without arguments within a configured project`, async () => {
await xfs.mktempPromise(async cwd => { await xfs.mktempPromise(async cwd => {
await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), { await xfs.writeJsonPromise(ppath.join(cwd, `package.json` as Filename), {

Binary file not shown.

Binary file not shown.