diff --git a/sources/commands/Base.ts b/sources/commands/Base.ts index 01139766b..78556f292 100644 --- a/sources/commands/Base.ts +++ b/sources/commands/Base.ts @@ -37,7 +37,7 @@ export abstract class BaseCommand extends Command { async setLocalPackageManager(info: PreparedPackageManagerInfo) { const lookup = await specUtils.loadSpec(this.context.cwd); - const content = lookup.target !== `NoProject` + const content = lookup.type !== `NoProject` ? await fs.promises.readFile(lookup.target, `utf8`) : ``; diff --git a/sources/commands/Use.ts b/sources/commands/Use.ts index aa75db9ae..13c96b4ae 100644 --- a/sources/commands/Use.ts +++ b/sources/commands/Use.ts @@ -16,7 +16,7 @@ export class UseCommand extends BaseCommand { `, examples: [[ `Configure the project to use the latest Yarn release`, - `corepack use 'yarn@*'`, + `corepack use yarn`, ]], }); diff --git a/sources/specUtils.ts b/sources/specUtils.ts index e52f200ba..dcf51f9b3 100644 --- a/sources/specUtils.ts +++ b/sources/specUtils.ts @@ -3,6 +3,7 @@ import fs from 'fs'; import path from 'path'; import semver from 'semver'; +import {NodeError} from './nodeUtils'; import {Descriptor, Locator, isSupportedPackageManager} from './types'; const nodeModulesRegExp = /[\\/]node_modules[\\/](@[^\\/]*[\\/])?([^@\\/][^\\/]*)$/; @@ -96,10 +97,13 @@ export async function loadSpec(initialCwd: string): Promise { continue; const manifestPath = path.join(currCwd, `package.json`); - if (!fs.existsSync(manifestPath)) - continue; - - const content = await fs.promises.readFile(manifestPath, `utf8`); + let content: string; + try { + content = await fs.promises.readFile(manifestPath, `utf8`); + } catch (err) { + if ((err as NodeError)?.code === `ENOENT`) continue; + throw err; + } let data; try { diff --git a/tests/Use.test.ts b/tests/Use.test.ts index e9a58d414..10deef19e 100644 --- a/tests/Use.test.ts +++ b/tests/Use.test.ts @@ -13,6 +13,7 @@ describe(`UseCommand`, () => { it(`should set the package manager in the current project`, async () => { await xfs.mktempPromise(async cwd => { await xfs.writeJsonPromise(ppath.join(cwd, `package.json`), { + packageManager: `yarn@1.0.0`, }); await expect(runCli(cwd, [`use`, `yarn@1.22.4`])).resolves.toMatchObject({ @@ -29,4 +30,37 @@ describe(`UseCommand`, () => { }); }); }); + + it(`should create a package.json if absent`, async () => { + await xfs.mktempPromise(async cwd => { + await expect(runCli(cwd, [`use`, `yarn@1.22.4`])).resolves.toMatchObject({ + exitCode: 0, + stderr: `warning package.json: No license field\nwarning No license field\n`, + }); + + await expect(xfs.readJsonPromise(ppath.join(cwd, `package.json`))).resolves.toMatchObject({ + packageManager: `yarn@1.22.4+sha256.bc5316aa110b2f564a71a3d6e235be55b98714660870c5b6b2d2d3f12587fb58`, + }); + + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + exitCode: 0, + stdout: `1.22.4\n`, + stderr: ``, + }); + + // Ensure Corepack is able to detect package.json in parent directory + const subfolder = ppath.join(cwd, `subfolder`); + await xfs.mkdirPromise(subfolder); + + await expect(runCli(subfolder, [`use`, `yarn@2.2.2`])).resolves.toMatchObject({ + exitCode: 0, + stderr: ``, + }); + await expect(runCli(cwd, [`yarn`, `--version`])).resolves.toMatchObject({ + exitCode: 0, + stdout: `2.2.2\n`, + stderr: ``, + }); + }); + }); }); diff --git a/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-1.dat b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-1.dat new file mode 100644 index 000000000..e090a6232 Binary files /dev/null and b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-1.dat differ diff --git a/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-2.dat b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-2.dat new file mode 100644 index 000000000..b03652e61 Binary files /dev/null and b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-2.dat differ diff --git a/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-3.dat b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-3.dat new file mode 100644 index 000000000..b7dbe0ac0 Binary files /dev/null and b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-3.dat differ diff --git a/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-4.dat b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-4.dat new file mode 100644 index 000000000..b03652e61 Binary files /dev/null and b/tests/nock/WyEcK5FmdvhvOqnb2mHi5A-4.dat differ