Skip to content

Commit 82429c0

Browse files
authored
feat: Defaulting nodeVersion to system (#18732)
* Defaulting nodeVersion to system * try to fix system test * Rename arg parameters, fix system test in a much better way. * remove invalid comment * Add deprecation warning for the nodeVersion config. * Remove default value to avoid warning regardless of the presence of `nodeVersion` * More tests fixes 😅 * Updates to deprecation message * update node version in deprecation notice. * flex config file name that we tell consumers to update * simplify validateNoBreakingConfig options
1 parent e8ab12d commit 82429c0

File tree

18 files changed

+478
-158
lines changed

18 files changed

+478
-158
lines changed

cli/lib/exec/spawn.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ module.exports = {
8181
args = [args]
8282
}
8383

84-
args = [...args, '--cwd', process.cwd()]
84+
args = [...args, '--cwd', process.cwd(), '--userNodePath', process.execPath, '--userNodeVersion', process.versions.node]
8585

8686
_.defaults(options, {
8787
dev: false,

cli/test/lib/exec/spawn_spec.js

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const expect = require('chai').expect
1818
const snapshot = require('../../support/snapshot')
1919

2020
const cwd = process.cwd()
21+
const execPath = process.execPath
22+
const nodeVersion = process.versions.node
2123

2224
const defaultBinaryDir = '/default/binary/dir'
2325

@@ -98,6 +100,10 @@ describe('lib/exec/spawn', function () {
98100
'--foo',
99101
'--cwd',
100102
cwd,
103+
'--userNodePath',
104+
execPath,
105+
'--userNodeVersion',
106+
nodeVersion,
101107
], {
102108
detached: false,
103109
stdio: ['inherit', 'inherit', 'pipe'],
@@ -122,6 +128,10 @@ describe('lib/exec/spawn', function () {
122128
'--foo',
123129
'--cwd',
124130
cwd,
131+
'--userNodePath',
132+
execPath,
133+
'--userNodeVersion',
134+
nodeVersion,
125135
]
126136

127137
expect(args).to.deep.equal(['/path/to/cypress', expectedCliArgs])
@@ -142,6 +152,10 @@ describe('lib/exec/spawn', function () {
142152
'--foo',
143153
'--cwd',
144154
cwd,
155+
'--userNodePath',
156+
execPath,
157+
'--userNodeVersion',
158+
nodeVersion,
145159
], {
146160
detached: false,
147161
stdio: ['inherit', 'inherit', 'pipe'],
@@ -163,6 +177,10 @@ describe('lib/exec/spawn', function () {
163177
'--foo',
164178
'--cwd',
165179
cwd,
180+
'--userNodePath',
181+
execPath,
182+
'--userNodeVersion',
183+
nodeVersion,
166184
], {
167185
detached: false,
168186
stdio: ['inherit', 'inherit', 'pipe'],

packages/server/lib/config.ts

+31-19
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import origin from './util/origin'
1111
import * as settings from './util/settings'
1212
import Debug from 'debug'
1313
import pathHelpers from './util/path_helpers'
14-
import findSystemNode from './util/find_system_node'
1514

1615
const debug = Debug('cypress:server:config')
1716

@@ -63,14 +62,29 @@ const convertRelativeToAbsolutePaths = (projectRoot, obj, defaults = {}) => {
6362
, {})
6463
}
6564

66-
const validateNoBreakingConfig = (cfg) => {
67-
return _.each(breakingOptions, ({ name, errorKey, newName, isWarning }) => {
68-
if (_.has(cfg, name)) {
65+
const validateNoBreakingConfig = (config) => {
66+
breakingOptions.forEach(({ name, errorKey, newName, isWarning, value }) => {
67+
if (config.hasOwnProperty(name)) {
68+
if (value && config[name] !== value) {
69+
// Bail if a value is specified but the config does not have that value.
70+
return
71+
}
72+
6973
if (isWarning) {
70-
return errors.warning(errorKey, name, newName)
74+
return errors.warning(errorKey, {
75+
name,
76+
newName,
77+
value,
78+
configFile: config.configFile,
79+
})
7180
}
7281

73-
return errors.throw(errorKey, name, newName)
82+
return errors.throw(errorKey, {
83+
name,
84+
newName,
85+
value,
86+
configFile: config.configFile,
87+
})
7488
}
7589
})
7690
}
@@ -293,6 +307,8 @@ export function mergeDefaults (config: Record<string, any> = {}, options: Record
293307

294308
config = setParentTestsPaths(config)
295309

310+
config = setNodeBinary(config, options.args?.userNodePath, options.args?.userNodeVersion)
311+
296312
// validate config again here so that we catch
297313
// configuration errors coming from the CLI overrides
298314
// or env var overrides
@@ -305,7 +321,6 @@ export function mergeDefaults (config: Record<string, any> = {}, options: Record
305321
return setSupportFileAndFolder(config)
306322
.then(setPluginsFile)
307323
.then(setScaffoldPaths)
308-
.then(_.partialRight(setNodeBinary, options.onWarning))
309324
}
310325

311326
export function setResolvedConfigValues (config, defaults, resolved, options) {
@@ -453,22 +468,19 @@ export function resolveConfigValues (config, defaults, resolved = {}, options =
453468
}
454469

455470
// instead of the built-in Node process, specify a path to 3rd party Node
456-
export const setNodeBinary = Promise.method((obj, onWarning) => {
457-
if (obj.nodeVersion !== 'system') {
458-
obj.resolvedNodeVersion = process.versions.node
471+
export const setNodeBinary = (obj, userNodePath, userNodeVersion) => {
472+
// if execPath isn't found we weren't executed from the CLI and should used the bundled node version.
473+
if (userNodePath && userNodeVersion && obj.nodeVersion !== 'bundled') {
474+
obj.resolvedNodePath = userNodePath
475+
obj.resolvedNodeVersion = userNodeVersion
459476

460477
return obj
461478
}
462479

463-
return findSystemNode.findNodePathAndVersion()
464-
.then(({ path, version }) => {
465-
obj.resolvedNodePath = path
466-
obj.resolvedNodeVersion = version
467-
}).catch((err) => {
468-
onWarning(errors.get('COULD_NOT_FIND_SYSTEM_NODE', process.versions.node))
469-
obj.resolvedNodeVersion = process.versions.node
470-
}).return(obj)
471-
})
480+
obj.resolvedNodeVersion = process.versions.node
481+
482+
return obj
483+
}
472484

473485
export function setScaffoldPaths (obj) {
474486
obj = _.clone(obj)

packages/server/lib/config_options.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ export const options = [
151151
isInternal: true,
152152
}, {
153153
name: 'nodeVersion',
154-
defaultValue: 'default',
155-
validation: v.isOneOf('default', 'bundled', 'system'),
154+
validation: v.isOneOf('bundled', 'system'),
156155
}, {
157156
name: 'numTestsKeptInMemory',
158157
defaultValue: 50,
@@ -333,5 +332,15 @@ export const breakingOptions = [
333332
name: 'firefoxGcInterval',
334333
errorKey: 'FIREFOX_GC_INTERVAL_REMOVED',
335334
isWarning: true,
335+
}, {
336+
name: 'nodeVersion',
337+
value: 'system',
338+
errorKey: 'NODE_VERSION_DEPRECATION_SYSTEM',
339+
isWarning: true,
340+
}, {
341+
name: 'nodeVersion',
342+
value: 'bundled',
343+
errorKey: 'NODE_VERSION_DEPRECATION_BUNDLED',
344+
isWarning: true,
336345
},
337346
]

packages/server/lib/errors.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
633633
We found an invalid value in the file: ${chalk.blue(filePath)}
634634
635635
${chalk.yellow(arg2)}`
636-
// happens when there is an invalid config value returnes from the
636+
// happens when there is an invalid config value returned from the
637637
// project's plugins file like "cypress/plugins.index.js"
638638
case 'PLUGINS_CONFIG_VALIDATION_ERROR':
639639
filePath = `\`${arg1}\``
@@ -650,9 +650,9 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
650650
${chalk.yellow(arg1)}`
651651
case 'RENAMED_CONFIG_OPTION':
652652
return stripIndent`\
653-
The ${chalk.yellow(arg1)} configuration option you have supplied has been renamed.
653+
The ${chalk.yellow(arg1.name)} configuration option you have supplied has been renamed.
654654
655-
Please rename ${chalk.yellow(arg1)} to ${chalk.blue(arg2)}`
655+
Please rename ${chalk.yellow(arg1.name)} to ${chalk.blue(arg1.newName)}`
656656
case 'CANNOT_CONNECT_BASE_URL':
657657
return stripIndent`\
658658
Cypress failed to verify that your server is running.
@@ -932,7 +932,7 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
932932
You can safely remove this option from your config.`
933933
case 'EXPERIMENTAL_COMPONENT_TESTING_REMOVED':
934934
return stripIndent`\
935-
The ${chalk.yellow(`\`experimentalComponentTesting\``)} configuration option was removed in Cypress version \`7.0.0\`. Please remove this flag from \`cypress.json\`.
935+
The ${chalk.yellow(`\`experimentalComponentTesting\``)} configuration option was removed in Cypress version \`7.0.0\`. Please remove this flag from ${chalk.yellow(`\`${arg1.configFile}\``)}.
936936
937937
Cypress Component Testing is now a standalone command. You can now run your component tests with:
938938
@@ -1010,6 +1010,16 @@ const getMsgByType = function (type, arg1 = {}, arg2, arg3) {
10101010
${arg1 ? 'Try installing Node.js 64-bit and reinstalling Cypress to use the 64-bit build.'
10111011
: 'Consider upgrading to a 64-bit OS to continue using Cypress.'}
10121012
`
1013+
case 'NODE_VERSION_DEPRECATION_SYSTEM':
1014+
return stripIndent`\
1015+
Deprecation Warning: ${chalk.yellow(`\`${arg1.name}\``)} is currently set to ${chalk.yellow(`\`${arg1.value}\``)} in the ${chalk.yellow(`\`${arg1.configFile}\``)} configuration file. As of Cypress version \`9.0.0\` the default behavior of ${chalk.yellow(`\`${arg1.name}\``)} has changed to always use the version of Node used to start cypress via the cli.
1016+
Please remove the ${chalk.yellow(`\`${arg1.name}\``)} configuration option from ${chalk.yellow(`\`${arg1.configFile}\``)}.
1017+
`
1018+
case 'NODE_VERSION_DEPRECATION_BUNDLED':
1019+
return stripIndent`\
1020+
Deprecation Warning: ${chalk.yellow(`\`${arg1.name}\``)} is currently set to ${chalk.yellow(`\`${arg1.value}\``)} in the ${chalk.yellow(`\`${arg1.configFile}\``)} configuration file. As of Cypress version \`9.0.0\` the default behavior of ${chalk.yellow(`\`${arg1.name}\``)} has changed to always use the version of Node used to start cypress via the cli. When ${chalk.yellow(`\`${arg1.name}\``)} is set to ${chalk.yellow(`\`${arg1.value}\``)}, Cypress will use the version of Node bundled with electron. This can cause problems running certain plugins or integrations.
1021+
As the ${chalk.yellow(`\`${arg1.name}\``)} configuration option will be removed in a future release, it is recommended to remove the ${chalk.yellow(`\`${arg1.name}\``)} configuration option from ${chalk.yellow(`\`${arg1.configFile}\``)}.
1022+
`
10131023
default:
10141024
}
10151025
}

packages/server/lib/open_project.ts

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export interface LaunchArgs {
4242
testingType: Cypress.TestingType
4343
invokedFromCli: boolean
4444
os: PlatformName
45+
userNodePath?: string
46+
userNodeVersion?: string
4547

4648
onFocusTests?: () => any
4749
/**

packages/server/lib/util/args.js

+42-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,48 @@ const nestedObjectsInCurlyBracesRe = /\{(.+?)\}/g
1313
const nestedArraysInSquareBracketsRe = /\[(.+?)\]/g
1414
const everythingAfterFirstEqualRe = /=(.*)/
1515

16-
const allowList = 'appPath apiKey browser ci ciBuildId clearLogs config configFile cwd env execPath exit exitWithCode group headed inspectBrk key logs mode outputPath parallel ping port project proxySource quiet record reporter reporterOptions returnPkg runMode runProject smokeTest spec tag updating version testingType'.split(' ')
16+
const allowList = [
17+
'apiKey',
18+
'appPath',
19+
'browser',
20+
'ci',
21+
'ciBuildId',
22+
'clearLogs',
23+
'userNodePath',
24+
'userNodeVersion',
25+
'config',
26+
'configFile',
27+
'cwd',
28+
'env',
29+
'execPath',
30+
'exit',
31+
'exitWithCode',
32+
'group',
33+
'headed',
34+
'inspectBrk',
35+
'key',
36+
'logs',
37+
'mode',
38+
'outputPath',
39+
'parallel',
40+
'ping',
41+
'port',
42+
'project',
43+
'proxySource',
44+
'quiet',
45+
'record',
46+
'reporter',
47+
'reporterOptions',
48+
'returnPkg',
49+
'runMode',
50+
'runProject',
51+
'smokeTest',
52+
'spec',
53+
'tag',
54+
'testingType',
55+
'updating',
56+
'version',
57+
]
1758
// returns true if the given string has double quote character "
1859
// only at the last position.
1960
const hasStrayEndQuote = (s) => {
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
const debug = require('debug')('cypress:server:find_system_node')
2-
const execa = require('execa')
32
const fixPath = require('fix-path')
43
const Promise = require('bluebird')
54
const which = require('which')
65

7-
const NODE_VERSION_RE = /^v(\d+\.\d+\.\d+)/m
8-
96
/*
107
* Find the full path to a `node` binary on the current PATH.
118
* Note about fix-path:
@@ -41,44 +38,6 @@ function findNodeInFullPath () {
4138
})
4239
}
4340

44-
function findNodeVersionFromPath (path) {
45-
if (!path) {
46-
return Promise.resolve(null)
47-
}
48-
49-
return execa.stdout(path, ['-v'])
50-
.then((stdout) => {
51-
debug('node -v returned %o', { stdout })
52-
const matches = NODE_VERSION_RE.exec(stdout)
53-
54-
if (matches && matches.length === 2) {
55-
const version = matches[1]
56-
57-
debug('found Node version', { version })
58-
59-
return version
60-
}
61-
})
62-
.catch((err) => {
63-
debug('could not resolve Node version %o', { err })
64-
65-
throw err
66-
})
67-
}
68-
69-
function findNodePathAndVersion () {
70-
return findNodeInFullPath()
71-
.then((path) => {
72-
return findNodeVersionFromPath(path)
73-
.then((version) => {
74-
return {
75-
path, version,
76-
}
77-
})
78-
})
79-
}
80-
8141
module.exports = {
8242
findNodeInFullPath,
83-
findNodePathAndVersion,
8443
}

0 commit comments

Comments
 (0)