fix(use): do not throw on invalid `packageManager` (#663)

This commit is contained in:
Antoine du Hamel 2025-02-28 19:20:09 +01:00 committed by GitHub
parent bb16184b7b
commit 4be72f6941
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 9 deletions

View File

@ -293,19 +293,20 @@ export class Engine {
}
case `Found`: {
if (result.spec.name !== locator.name) {
const spec = result.getSpec();
if (spec.name !== locator.name) {
if (transparent) {
if (typeof locator.reference === `function`)
fallbackDescriptor.range = await locator.reference();
debugUtils.log(`Falling back to ${fallbackDescriptor.name}@${fallbackDescriptor.range} in a ${result.spec.name}@${result.spec.range} project`);
debugUtils.log(`Falling back to ${fallbackDescriptor.name}@${fallbackDescriptor.range} in a ${spec.name}@${spec.range} project`);
return fallbackDescriptor;
} else {
throw new UsageError(`This project is configured to use ${result.spec.name} because ${result.target} has a "packageManager" field`);
throw new UsageError(`This project is configured to use ${spec.name} because ${result.target} has a "packageManager" field`);
}
} else {
debugUtils.log(`Using ${result.spec.name}@${result.spec.range} as defined in project manifest ${result.target}`);
return result.spec;
debugUtils.log(`Using ${spec.name}@${spec.range} as defined in project manifest ${result.target}`);
return spec;
}
}
}

View File

@ -19,7 +19,7 @@ export abstract class BaseCommand extends Command<Context> {
throw new UsageError(`The local project doesn't feature a 'packageManager' field - please specify the package manager to pack, or update the manifest to reference it`);
default: {
return [lookup.spec];
return [lookup.getSpec()];
}
}
}

View File

@ -42,7 +42,7 @@ export class PrepareCommand extends Command<Context> {
throw new UsageError(`The local project doesn't feature a 'packageManager' field - please specify the package manager to pack, or update the manifest to reference it`);
default: {
specs.push(lookup.spec);
specs.push(lookup.getSpec());
}
}
}

View File

@ -75,7 +75,7 @@ export async function setLocalPackageManager(cwd: string, info: PreparedPackageM
export type LoadSpecResult =
| {type: `NoProject`, target: string}
| {type: `NoSpec`, target: string}
| {type: `Found`, target: string, spec: Descriptor};
| {type: `Found`, target: string, getSpec: () => Descriptor};
export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
let nextCwd = initialCwd;
@ -124,6 +124,7 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
return {
type: `Found`,
target: selection.manifestPath,
spec: parseSpec(rawPmSpec, path.relative(initialCwd, selection.manifestPath)),
// Lazy-loading it so we do not throw errors on commands that do not need valid spec.
getSpec: () => parseSpec(rawPmSpec, path.relative(initialCwd, selection.manifestPath)),
};
}

View File

@ -70,4 +70,50 @@ describe(`UseCommand`, () => {
});
});
});
describe(`should not care if packageManager is set to an invalid value`, () => {
for (const {description, packageManager} of [
{
description: `when a version range is given`,
packageManager: `yarn@1.x`,
},
{
description: `when only the pm name is given`,
packageManager: `yarn`,
},
{
description: `when the version is missing`,
packageManager: `yarn@`,
},
{
description: `when the field is not a string`,
packageManager: [],
},
]) {
it(description, async () => {
await xfs.mktempPromise(async cwd => {
await xfs.writeJsonPromise(ppath.join(cwd, `package.json`), {
packageManager,
license: `MIT`, // To avoid warning
});
await expect(runCli(cwd, [`use`, `yarn@1.22.4`])).resolves.toMatchObject({
exitCode: 0,
stderr: ``,
stdout: expect.stringMatching(/^Installing yarn@1\.22\.4 in the project\.\.\.\n\nyarn install v1\.22\.4\ninfo No lockfile found\.\n(.*\n)+Done in \d+\.\d+s\.\n$/),
});
await expect(xfs.readJsonPromise(ppath.join(cwd, `package.json`))).resolves.toMatchObject({
packageManager: `yarn@1.22.4+sha512.a1833b862fe52169bd6c2a033045a07df5bc6a23595c259e675fed1b2d035ab37abe6ce309720abb6636d68f03615054b6292dc0a70da31c8697fda228b50d18`,
});
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
exitCode: 0,
stdout: `1.22.4\n`,
stderr: ``,
});
});
});
}
});
});