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
to do this).
### `corepack install <-g,--global> [--all] [... name@version]`
### `corepack install <-g,--global> [--all] [... name[@<version>]]`
| 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
`packageManager` field.
### `corepack pack [--all] [... name@version]`
### `corepack pack [--all] [... name[@<version>]]`
| 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
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
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
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
`corepack use {name}@latest` call.
`corepack use {name}@latest` call (or simply `corepack use {name}`).
## Environment Variables

View File

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

Binary file not shown.

Binary file not shown.