Skip to content

Commit d27f603

Browse files
committed
fix(use): do not throw on invalid packageManager
1 parent f75e1a7 commit d27f603

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

sources/specUtils.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,16 @@ function parsePackageJSON(packageJSONContent: CorepackPackageJSON) {
132132
}
133133

134134
export async function setLocalPackageManager(cwd: string, info: PreparedPackageManagerInfo) {
135-
const lookup = await loadSpec(cwd);
135+
const lookup = await loadSpec(cwd, true);
136136

137137
const content = lookup.type !== `NoProject`
138138
? await fs.promises.readFile((lookup as FoundSpecResult).envFilePath ?? lookup.target, `utf8`)
139139
: ``;
140140

141141
let previousPackageManager: string;
142142
let newContent: string;
143-
if ((lookup as FoundSpecResult).envFilePath) {
144-
const envKey = `COREPACK_DEV_ENGINES_${(lookup as FoundSpecResult).spec.name.toUpperCase()}`;
143+
if ((lookup as FoundSpecResult).envFilePath && (lookup as FoundSpecResult).range) {
144+
const envKey = `COREPACK_DEV_ENGINES_${(lookup as FoundSpecResult).range!.name.toUpperCase()}`;
145145
const index = content.lastIndexOf(`\n${envKey}=`) + 1;
146146

147147
if (index === 0 && !content.startsWith(`${envKey}=`))
@@ -168,13 +168,13 @@ export async function setLocalPackageManager(cwd: string, info: PreparedPackageM
168168
};
169169
}
170170

171-
type FoundSpecResult = {type: `Found`, target: string, spec: Descriptor, range?: Descriptor, envFilePath?: string};
172-
export type LoadSpecResult =
171+
type FoundSpecResult<SkipSpecParsing extends boolean = true> = {type: `Found`, target: string, spec: SkipSpecParsing extends true ? undefined : Descriptor, range?: Descriptor, envFilePath?: string};
172+
export type LoadSpecResult<SkipSpecParsing extends boolean> =
173173
| {type: `NoProject`, target: string}
174174
| {type: `NoSpec`, target: string}
175-
| FoundSpecResult;
175+
| FoundSpecResult<SkipSpecParsing>;
176176

177-
export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
177+
export async function loadSpec<SkipSpecParsing extends boolean = false>(initialCwd: string, skipSpecParsing?: SkipSpecParsing): Promise<LoadSpecResult<SkipSpecParsing>> {
178178
let nextCwd = initialCwd;
179179
let currCwd = ``;
180180

@@ -258,10 +258,12 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
258258
type: `Found`,
259259
target: selection.manifestPath,
260260
envFilePath,
261-
spec: parseSpec(rawPmSpec, path.relative(initialCwd, selection.manifestPath)),
262261
range: selection.data.devEngines?.packageManager?.version && {
263262
name: selection.data.devEngines.packageManager.name,
264263
range: selection.data.devEngines.packageManager.version,
265264
},
265+
spec: skipSpecParsing ?
266+
(undefined as SkipSpecParsing extends true ? undefined : never) :
267+
parseSpec(rawPmSpec, path.relative(initialCwd, selection.manifestPath)) as SkipSpecParsing extends true ? never : ReturnType<typeof parseSpec>,
266268
};
267269
}

tests/Use.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,50 @@ describe(`UseCommand`, () => {
144144
});
145145
});
146146
});
147+
148+
describe(`should not care if packageManager is set to an invalid value`, () => {
149+
for (const {description, packageManager} of [
150+
{
151+
description: `when a version range is given`,
152+
packageManager: `[email protected]`,
153+
},
154+
{
155+
description: `when only the pm name is given`,
156+
packageManager: `yarn`,
157+
},
158+
{
159+
description: `when the version is missing`,
160+
packageManager: `yarn@`,
161+
},
162+
{
163+
description: `when the field is not a string`,
164+
packageManager: [],
165+
},
166+
]) {
167+
it(description, async () => {
168+
await xfs.mktempPromise(async cwd => {
169+
await xfs.writeJsonPromise(ppath.join(cwd, `package.json`), {
170+
packageManager,
171+
license: `MIT`, // To avoid warning
172+
});
173+
174+
await expect(runCli(cwd, [`use`, `[email protected]`])).resolves.toMatchObject({
175+
exitCode: 0,
176+
stderr: ``,
177+
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$/),
178+
});
179+
180+
await expect(xfs.readJsonPromise(ppath.join(cwd, `package.json`))).resolves.toMatchObject({
181+
packageManager: `[email protected]+sha512.a1833b862fe52169bd6c2a033045a07df5bc6a23595c259e675fed1b2d035ab37abe6ce309720abb6636d68f03615054b6292dc0a70da31c8697fda228b50d18`,
182+
});
183+
184+
await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({
185+
exitCode: 0,
186+
stdout: `1.22.4\n`,
187+
stderr: ``,
188+
});
189+
});
190+
});
191+
}
192+
});
147193
});

0 commit comments

Comments
 (0)