From ab99f751908b242f0bbdbad7efa9c27fa13118be Mon Sep 17 00:00:00 2001 From: Alexey Kuzmin Date: Mon, 5 Oct 2020 18:49:30 +0200 Subject: [PATCH] Adds support for --ignore-cpu in yarn add --- CONTRIBUTING.md | 2 +- __tests__/package-compatibility.js | 46 ++++++++++++++----- .../pkg-tests-specs/sources/basic.js | 26 ++++++++++- src/cli/commands/config.js | 1 + src/cli/commands/install.js | 6 +++ src/cli/index.js | 4 +- src/config.js | 3 ++ src/package-compatibility.js | 16 ++++--- 8 files changed, 83 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd9e73703d..0f806f58f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1 @@ -Please see https://yarnpkg.com/org/contributing/ \ No newline at end of file +Please see https://classic.yarnpkg.com/org/contributing/ \ No newline at end of file diff --git a/__tests__/package-compatibility.js b/__tests__/package-compatibility.js index c681c398fd..e73ca18971 100644 --- a/__tests__/package-compatibility.js +++ b/__tests__/package-compatibility.js @@ -20,13 +20,28 @@ test('ignore semver prerelease semantics for yarn', () => { expect(testEngine('yarn', '^1.3.0', {yarn: '1.4.1-20180208.2355'}, true)).toEqual(true); }); +test('shouldCheck returns false if the manifest does not specify any requirements', () => { + expect(shouldCheck({}, {ignorePlatform: false, ignoreEngines: false, ignoreCpu: false})).toBe(false); + + expect( + shouldCheck( + { + os: [], + cpu: [], + engines: {}, + }, + {ignorePlatform: false, ignoreEngines: false, ignoreCpu: false}, + ), + ).toBe(false); +}); + test('shouldCheck returns true if ignorePlatform is false and the manifest specifies an os or cpu requirement', () => { expect( shouldCheck( { os: ['darwin'], }, - {ignorePlatform: false, ignoreEngines: false}, + {ignorePlatform: false, ignoreEngines: false, ignoreCpu: false}, ), ).toBe(true); @@ -35,29 +50,38 @@ test('shouldCheck returns true if ignorePlatform is false and the manifest speci { cpu: ['i32'], }, - {ignorePlatform: false, ignoreEngines: false}, + {ignorePlatform: false, ignoreEngines: false, ignoreCpu: false}, ), ).toBe(true); +}); - expect(shouldCheck({}, {ignorePlatform: false, ignoreEngines: false})).toBe(false); +test('shouldCheck returns false if the manifest specifies an os or cpu requirement but ignorePlatform is true', () => { + expect( + shouldCheck( + { + os: ['darwin'], + }, + {ignorePlatform: true, ignoreEngines: false, ignoreCpu: false}, + ), + ).toBe(false); expect( shouldCheck( { - os: [], - cpu: [], + cpu: ['i32'], }, - {ignorePlatform: false, ignoreEngines: false}, + {ignorePlatform: true, ignoreEngines: false, ignoreCpu: false}, ), ).toBe(false); +}); +test('shouldCheck returns false if the manifest specifies a cpu requirement but ignoreCpu is true', () => { expect( shouldCheck( { cpu: ['i32'], - os: ['darwin'], }, - {ignorePlatform: true, ignoreEngines: false}, + {ignorePlatform: false, ignoreEngines: false, ignoreCpu: true}, ), ).toBe(false); }); @@ -68,18 +92,16 @@ test('shouldCheck returns true if ignoreEngines is false and the manifest specif { engines: {node: '>= 10'}, }, - {ignorePlatform: false, ignoreEngines: false}, + {ignorePlatform: false, ignoreEngines: false, ignoreCpu: false}, ), ).toBe(true); - expect(shouldCheck({}, {ignorePlatform: false, ignoreEngines: false})).toBe(false); - expect( shouldCheck( { engines: {node: '>= 10'}, }, - {ignorePlatform: false, ignoreEngines: true}, + {ignorePlatform: false, ignoreEngines: true, ignoreCpu: false}, ), ).toBe(false); }); diff --git a/packages/pkg-tests/pkg-tests-specs/sources/basic.js b/packages/pkg-tests/pkg-tests-specs/sources/basic.js index 46de091cee..74449b7418 100644 --- a/packages/pkg-tests/pkg-tests-specs/sources/basic.js +++ b/packages/pkg-tests/pkg-tests-specs/sources/basic.js @@ -405,6 +405,30 @@ module.exports = (makeTemporaryEnv: PackageDriver) => { ), ); + test( + `it should not fail if the environment does not satisfy the cpu architecture but ignore cpu is true`, + makeTemporaryEnv( + { + cpu: ['unicorn'], + }, + async ({path, run, source}) => { + await run(`install`, '--ignore-cpu'); + }, + ), + ); + + test( + `it should not fail if the environment does not satisfy the cpu architecture but ignore platform is true`, + makeTemporaryEnv( + { + cpu: ['unicorn'], + }, + async ({path, run, source}) => { + await run(`install`, '--ignore-platform'); + }, + ), + ); + test( `it should fail if the environment does not satisfy the engine requirements`, makeTemporaryEnv( @@ -420,7 +444,7 @@ module.exports = (makeTemporaryEnv: PackageDriver) => { ); test( - `it should not fail if the environment does not satisfy the os and cpu architecture but ignore platform is true`, + `it should not fail if the environment does not satisfy the os platform but ignore platform is true`, makeTemporaryEnv( { os: ['unicorn'], diff --git a/src/cli/commands/config.js b/src/cli/commands/config.js index d884c2c39e..03fabfdee6 100644 --- a/src/cli/commands/config.js +++ b/src/cli/commands/config.js @@ -20,6 +20,7 @@ const CONFIG_KEYS = [ 'linkFolder', 'offline', 'binLinks', + 'ignoreCpu', 'ignorePlatform', 'ignoreScripts', 'disablePrepublish', diff --git a/src/cli/commands/install.js b/src/cli/commands/install.js index bbe044fc35..c884e1d598 100644 --- a/src/cli/commands/install.js +++ b/src/cli/commands/install.js @@ -55,6 +55,7 @@ export type InstallCwdRequest = { type Flags = { // install har: boolean, + ignoreCpu: boolean, ignorePlatform: boolean, ignoreEngines: boolean, ignoreOptional: boolean, @@ -136,6 +137,7 @@ function normalizeFlags(config: Config, rawFlags: Object): Flags { const flags = { // install har: !!rawFlags.har, + ignoreCpu: !!rawFlags.ignoreCpu, ignorePlatform: !!rawFlags.ignorePlatform, ignoreEngines: !!rawFlags.ignoreEngines, ignoreScripts: !!rawFlags.ignoreScripts, @@ -170,6 +172,10 @@ function normalizeFlags(config: Config, rawFlags: Object): Flags { flags.ignoreScripts = true; } + if (config.getOption('ignore-cpu')) { + flags.ignoreCpu = true; + } + if (config.getOption('ignore-platform')) { flags.ignorePlatform = true; } diff --git a/src/cli/index.js b/src/cli/index.js index a7937a317a..c074e7f1b0 100644 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -86,7 +86,8 @@ export async function main({ commander.option('--json', 'format Yarn log messages as lines of JSON (see jsonlines.org)'); commander.option('--ignore-scripts', "don't run lifecycle scripts"); commander.option('--har', 'save HAR output of network traffic'); - commander.option('--ignore-platform', 'ignore platform checks'); + commander.option('--ignore-cpu', 'ignore CPU check'); + commander.option('--ignore-platform', 'ignore platform ("os" and "cpu") checks'); commander.option('--ignore-engines', 'ignore engines check'); commander.option('--ignore-optional', 'ignore optional dependencies'); commander.option('--force', 'install and build packages even if they were built before, overwrite lockfile'); @@ -539,6 +540,7 @@ export async function main({ binLinks: commander.binLinks, preferOffline: commander.preferOffline, captureHar: commander.har, + ignoreCpu: commander.ignoreCpu, ignorePlatform: commander.ignorePlatform, ignoreEngines: commander.ignoreEngines, ignoreScripts: commander.ignoreScripts, diff --git a/src/config.js b/src/config.js index caf3d247af..b4428dd506 100644 --- a/src/config.js +++ b/src/config.js @@ -38,6 +38,7 @@ export type ConfigOptions = { enableMetaFolder?: boolean, linkFileDependencies?: boolean, captureHar?: boolean, + ignoreCpu?: boolean, ignoreScripts?: boolean, ignorePlatform?: boolean, ignoreEngines?: boolean, @@ -117,6 +118,7 @@ export default class Config { enableMetaFolder: boolean; enableLockfileVersions: boolean; linkFileDependencies: boolean; + ignoreCpu: boolean; ignorePlatform: boolean; binLinks: boolean; updateChecksums: boolean; @@ -474,6 +476,7 @@ export default class Config { this.plugnplayUnplugged = []; this.plugnplayPurgeUnpluggedPackages = false; + this.ignoreCpu = !!opts.ignoreCpu; this.ignorePlatform = !!opts.ignorePlatform; this.ignoreScripts = !!opts.ignoreScripts; diff --git a/src/package-compatibility.js b/src/package-compatibility.js index d380b44a70..22d275a5af 100644 --- a/src/package-compatibility.js +++ b/src/package-compatibility.js @@ -133,7 +133,7 @@ export function checkOne(info: Manifest, config: Config, ignoreEngines: boolean) pushError(reporter.lang('incompatibleOS', process.platform)); } - if (shouldCheckCpu(cpu, config.ignorePlatform) && !isValidArch(cpu)) { + if (shouldCheckCpu(cpu, config.ignorePlatform, config.ignoreCpu) && !isValidArch(cpu)) { pushError(reporter.lang('incompatibleCPU', process.arch)); } @@ -167,8 +167,12 @@ export function check(infos: Array, config: Config, ignoreEngines: boo } } -function shouldCheckCpu(cpu: $PropertyType, ignorePlatform: boolean): boolean %checks { - return !ignorePlatform && Array.isArray(cpu) && cpu.length > 0; +function shouldCheckCpu( + cpu: $PropertyType, + ignorePlatform: boolean, + ignoreCpu: boolean, +): boolean %checks { + return !(ignorePlatform || ignoreCpu) && Array.isArray(cpu) && cpu.length > 0; } function shouldCheckPlatform(os: $PropertyType, ignorePlatform: boolean): boolean %checks { @@ -176,15 +180,15 @@ function shouldCheckPlatform(os: $PropertyType, ignorePlatform: } function shouldCheckEngines(engines: $PropertyType, ignoreEngines: boolean): boolean %checks { - return !ignoreEngines && typeof engines === 'object'; + return !ignoreEngines && typeof engines === 'object' && Object.keys(engines).length > 0; } export function shouldCheck( manifest: PartialManifest, - options: {ignoreEngines: boolean, ignorePlatform: boolean}, + options: {ignoreEngines: boolean, ignorePlatform: boolean, ignoreCpu: boolean}, ): boolean { return ( - shouldCheckCpu(manifest.cpu, options.ignorePlatform) || + shouldCheckCpu(manifest.cpu, options.ignorePlatform, options.ignoreCpu) || shouldCheckPlatform(manifest.os, options.ignorePlatform) || shouldCheckEngines(manifest.engines, options.ignoreEngines) );