diff --git a/lib/node-gyp.js b/lib/node-gyp.js index 26fcb2ee49..dafce99d49 100644 --- a/lib/node-gyp.js +++ b/lib/node-gyp.js @@ -133,24 +133,25 @@ class Gyp extends EventEmitter { // other tools. // The `npm_package_config_node_gyp_` prefix will take precedence over // `npm_config_` keys. - const npmConfigPrefix = 'npm_config_' - const npmPackageConfigPrefix = 'npm_package_config_node_gyp_' + const npmConfigPrefix = /^npm_config_/i + const npmPackageConfigPrefix = /^npm_package_config_node_gyp_/i const configEnvKeys = Object.keys(process.env) - .filter((k) => k.startsWith(npmConfigPrefix) || k.startsWith(npmPackageConfigPrefix)) + .filter((k) => npmConfigPrefix.test(k) || npmPackageConfigPrefix.test(k)) // sort so that npm_package_config_node_gyp_ keys come last and will override - .sort((a) => a.startsWith(npmConfigPrefix) ? -1 : 1) + .sort((a) => npmConfigPrefix.test(a) ? -1 : 1) for (const key of configEnvKeys) { // add the user-defined options to the config - const name = key.startsWith(npmConfigPrefix) - ? key.substring(npmConfigPrefix.length) - : key.substring(npmPackageConfigPrefix.length) + const name = npmConfigPrefix.test(key) + ? key.replace(npmConfigPrefix, '') + : key.replace(npmPackageConfigPrefix, '') // gyp@741b7f1 enters an infinite loop when it encounters // zero-length options so ensure those don't get through. if (name) { // convert names like force_process_config to force-process-config - this.opts[name.replaceAll('_', '-')] = process.env[key] + // and convert to lowercase + this.opts[name.replaceAll('_', '-').toLowerCase()] = process.env[key] } } diff --git a/test/test-options.js b/test/test-options.js index 8ea616fd1a..e14f827d56 100644 --- a/test/test-options.js +++ b/test/test-options.js @@ -30,6 +30,9 @@ describe('options', function () { process.env.npm_config_y = '41' // Package config should take precedence over npm_config_ keys. process.env.npm_package_config_node_gyp_y = '42' + // All configs should be case-insensitive. + process.env.NPM_PACKAGE_CONFIG_NODE_GYP_XX = 'value' + process.env.NPM_CONFIG_YY = 'value' // loglevel does not get added to opts but will change the logger's level. process.env.npm_config_loglevel = 'silly' @@ -41,10 +44,12 @@ describe('options', function () { assert.strictEqual(log.logger.level.id, 'silly') - assert.deepStrictEqual(Object.keys(g.opts).sort(), [...keys, 'argv', 'x', 'y', 'foo'].sort()) + assert.deepStrictEqual(Object.keys(g.opts).sort(), [...keys, 'argv', 'x', 'y', 'foo', 'xx', 'yy'].sort()) assert.strictEqual(g.opts['x'], '42') assert.strictEqual(g.opts['y'], '42') assert.strictEqual(g.opts['foo'], '42') + assert.strictEqual(g.opts['xx'], 'value') + assert.strictEqual(g.opts['yy'], 'value') }) it('options with spaces in environment', () => {