diff --git a/CHANGELOG.md b/CHANGELOG.md index 33aab2a233..642a7afbda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa [#6983](https://github.com/yarnpkg/yarn/pull/6983) - [**Micha Reiser**](https://github.com/MichaReiser) +- Run the engines check before executing `run` scripts. + + [#7013](https://github.com/yarnpkg/yarn/issues/7013) - [**Eloy DurĂ¡n**](https://github.com/alloy) + ## 1.14.0 - Improves PnP compatibility with Node 6 diff --git a/src/cli/commands/install.js b/src/cli/commands/install.js index f273b5d3ed..e4aa6f3ea1 100644 --- a/src/cli/commands/install.js +++ b/src/cli/commands/install.js @@ -744,7 +744,7 @@ export class Install { async checkCompatibility(): Promise { const {manifest} = await this.fetchRequestFromCwd(); - await compatibility.checkOne({_reference: {}, ...manifest}, this.config, this.flags.ignoreEngines); + await compatibility.checkOne(manifest, this.config, this.flags.ignoreEngines); } async persistChanges(): Promise { diff --git a/src/cli/commands/run.js b/src/cli/commands/run.js index 66fbaaff09..49a0270b8a 100644 --- a/src/cli/commands/run.js +++ b/src/cli/commands/run.js @@ -6,6 +6,7 @@ import {execCommand, makeEnv} from '../../util/execute-lifecycle-script.js'; import {dynamicRequire} from '../../util/dynamic-require.js'; import {MessageError} from '../../errors.js'; import {registries} from '../../resolvers/index.js'; +import {checkOne as checkCompatibility} from '../../package-compatibility.js'; import * as fs from '../../util/fs.js'; import * as constants from '../../constants.js'; @@ -118,6 +119,13 @@ export async function run(config: Config, reporter: Reporter, flags: Object, arg } if (cmds.length) { + const ignoreEngines = !!(flags.ignoreEngines || config.getOption('ignore-engines')); + try { + await checkCompatibility(pkg, config, ignoreEngines); + } catch (err) { + throw err instanceof MessageError ? new MessageError(reporter.lang('cannotRunWithIncompatibleEnv')) : err; + } + // Disable wrapper in executed commands process.env.YARN_WRAP_OUTPUT = 'false'; for (const [stage, cmd] of cmds) { diff --git a/src/package-compatibility.js b/src/package-compatibility.js index 7ba68615d3..145f931094 100644 --- a/src/package-compatibility.js +++ b/src/package-compatibility.js @@ -8,7 +8,6 @@ import {entries} from './util/misc.js'; import {version as yarnVersion} from './util/yarn-version.js'; import {satisfiesWithPrereleases} from './util/semver.js'; -const invariant = require('invariant'); const semver = require('semver'); const VERSIONS = Object.assign({}, process.versions, { @@ -111,9 +110,8 @@ export function checkOne(info: Manifest, config: Config, ignoreEngines: boolean) const pushError = msg => { const ref = info._reference; - invariant(ref, 'expected package reference'); - if (ref.optional) { + if (ref && ref.optional) { ref.ignore = true; ref.incompatible = true; diff --git a/src/reporters/lang/en.js b/src/reporters/lang/en.js index fdd512fdd6..816446cdfd 100644 --- a/src/reporters/lang/en.js +++ b/src/reporters/lang/en.js @@ -229,11 +229,12 @@ const messages = { nodeGypAutoInstallFailed: 'Failed to auto-install node-gyp. Please run "yarn global add node-gyp" manually. Error: $0', - foundIncompatible: 'Found incompatible module', + foundIncompatible: 'Found incompatible module.', incompatibleEngine: 'The engine $0 is incompatible with this module. Expected version $1. Got $2', incompatibleCPU: 'The CPU architecture $0 is incompatible with this module.', incompatibleOS: 'The platform $0 is incompatible with this module.', invalidEngine: 'The engine $0 appears to be invalid.', + cannotRunWithIncompatibleEnv: 'Commands cannot run with an incompatible environment.', optionalCompatibilityExcluded: '$0 is an optional dependency and failed compatibility check. Excluding it from installation.',