Sync deps and engines with npm (#2770)

* feat!: update `engines.node` to `^14.17.0 || ^16.13.0 || >=18.0.0`

* deps: nopt@^7.0.0

* feat: replace npmlog with proc-log

* deps: standard@17.0.0 and fix linting errors

* deps: which@3.0.0
- this also promiisifies the build command

* deps: glob@8.0.3

* feat: drop rimraf dependency

* fix: use fs/promises in favor of fs.promises
This commit is contained in:
Luke Karrys 2023-06-20 06:44:18 -07:00 committed by GitHub
parent 33391db3a0
commit 192eec2aca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 536 additions and 418 deletions

View file

@ -6,7 +6,7 @@ process.title = 'node-gyp'
const envPaths = require('env-paths')
const gyp = require('../')
const log = require('npmlog')
const log = require('../lib/log')
const os = require('os')
/**
@ -14,11 +14,11 @@ const os = require('os')
*/
const prog = gyp()
var completed = false
let completed = false
prog.parseArgv(process.argv)
prog.devDir = prog.opts.devdir
var homeDir = os.homedir()
const homeDir = os.homedir()
if (prog.devDir) {
prog.devDir = prog.devDir.replace(/^~/, homeDir)
} else if (homeDir) {
@ -48,11 +48,11 @@ log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform,
* Change dir if -C/--directory was passed.
*/
var dir = prog.opts.directory
const dir = prog.opts.directory
if (dir) {
var fs = require('fs')
const fs = require('fs')
try {
var stat = fs.statSync(dir)
const stat = fs.statSync(dir)
if (stat.isDirectory()) {
log.info('chdir', dir)
process.chdir(dir)
@ -69,7 +69,7 @@ if (dir) {
}
function run () {
var command = prog.todo.shift()
const command = prog.todo.shift()
if (!command) {
// done!
completed = true
@ -86,7 +86,7 @@ function run () {
return process.exit(1)
}
if (command.name === 'list') {
var versions = arguments[1]
const versions = arguments[1]
if (versions.length > 0) {
versions.forEach(function (version) {
console.log(version)
@ -120,7 +120,7 @@ process.on('uncaughtException', function (err) {
function errorMessage () {
// copied from npm's lib/utils/error-handler.js
var os = require('os')
const os = require('os')
log.error('System', os.type() + ' ' + os.release())
log.error('command', process.argv
.map(JSON.stringify).join(' '))

View file

@ -1,14 +1,15 @@
'use strict'
const fs = require('graceful-fs')
const fs = require('graceful-fs').promises
const { promisify } = require('util')
const path = require('path')
const glob = require('glob')
const log = require('npmlog')
const glob = promisify(require('glob'))
const log = require('./log')
const which = require('which')
const win = process.platform === 'win32'
function build (gyp, argv, callback) {
var platformMake = 'make'
async function build (gyp, argv) {
let platformMake = 'make'
if (process.platform === 'aix') {
platformMake = 'gmake'
} else if (process.platform === 'os400') {
@ -21,33 +22,34 @@ function build (gyp, argv, callback) {
})
}
var makeCommand = gyp.opts.make || process.env.MAKE || platformMake
var command = win ? 'msbuild' : makeCommand
var jobs = gyp.opts.jobs || process.env.JOBS
var buildType
var config
var arch
var nodeDir
var guessedSolution
const makeCommand = gyp.opts.make || process.env.MAKE || platformMake
let command = win ? 'msbuild' : makeCommand
const jobs = gyp.opts.jobs || process.env.JOBS
let buildType
let config
let arch
let nodeDir
let guessedSolution
loadConfigGypi()
await loadConfigGypi()
/**
* Load the "config.gypi" file that was generated during "configure".
*/
function loadConfigGypi () {
var configPath = path.resolve('build', 'config.gypi')
fs.readFile(configPath, 'utf8', function (err, data) {
if (err) {
async function loadConfigGypi () {
let data
try {
const configPath = path.resolve('build', 'config.gypi')
data = await fs.readFile(configPath, 'utf8')
} catch (err) {
if (err.code === 'ENOENT') {
callback(new Error('You must run `node-gyp configure` first!'))
throw new Error('You must run `node-gyp configure` first!')
} else {
callback(err)
throw err
}
return
}
config = JSON.parse(data.replace(/#.+\n/, ''))
// get the 'arch', 'buildType', and 'nodeDir' vars from the config
@ -67,67 +69,56 @@ function build (gyp, argv, callback) {
log.verbose('node dev dir', nodeDir)
if (win) {
findSolutionFile()
await findSolutionFile()
} else {
doWhich()
await doWhich()
}
})
}
/**
* On Windows, find the first build/*.sln file.
*/
function findSolutionFile () {
glob('build/*.sln', function (err, files) {
if (err) {
return callback(err)
}
async function findSolutionFile () {
const files = await glob('build/*.sln')
if (files.length === 0) {
return callback(new Error('Could not find *.sln file. Did you run "configure"?'))
throw new Error('Could not find *.sln file. Did you run "configure"?')
}
guessedSolution = files[0]
log.verbose('found first Solution file', guessedSolution)
doWhich()
})
await doWhich()
}
/**
* Uses node-which to locate the msbuild / make executable.
*/
function doWhich () {
async function doWhich () {
// On Windows use msbuild provided by node-gyp configure
if (win) {
if (!config.variables.msbuild_path) {
return callback(new Error(
'MSBuild is not set, please run `node-gyp configure`.'))
throw new Error('MSBuild is not set, please run `node-gyp configure`.')
}
command = config.variables.msbuild_path
log.verbose('using MSBuild:', command)
doBuild()
await doBuild()
return
}
// First make sure we have the build command in the PATH
which(command, function (err, execPath) {
if (err) {
// Some other error or 'make' not found on Unix, report that to the user
callback(err)
return
}
const execPath = await which(command)
log.verbose('`which` succeeded for `' + command + '`', execPath)
doBuild()
})
await doBuild()
}
/**
* Actually spawn the process and compile the module.
*/
function doBuild () {
async function doBuild () {
// Enable Verbose build
var verbose = log.levels[log.level] <= log.levels.verbose
var j
const verbose = log.logger.isVisible('verbose')
let j
if (!win && verbose) {
argv.push('V=1')
@ -147,9 +138,11 @@ function build (gyp, argv, callback) {
// Convert .gypi config target_arch to MSBuild /Platform
// Since there are many ways to state '32-bit Intel', default to it.
// N.B. msbuild's Condition string equality tests are case-insensitive.
var archLower = arch.toLowerCase()
var p = archLower === 'x64' ? 'x64'
: (archLower === 'arm' ? 'ARM'
const archLower = arch.toLowerCase()
const p = archLower === 'x64'
? 'x64'
: (archLower === 'arm'
? 'ARM'
: (archLower === 'arm64' ? 'ARM64' : 'Win32'))
argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
if (jobs) {
@ -179,7 +172,7 @@ function build (gyp, argv, callback) {
if (win) {
// did the user specify their own .sln file?
var hasSln = argv.some(function (arg) {
const hasSln = argv.some(function (arg) {
return path.extname(arg) === '.sln'
})
if (!hasSln) {
@ -194,20 +187,20 @@ function build (gyp, argv, callback) {
log.verbose('bin symlinks', `adding symlinks (such as Python), at "${buildBinsDir}", to PATH`)
}
var proc = gyp.spawn(command, argv)
proc.on('exit', onExit)
}
function onExit (code, signal) {
const proc = gyp.spawn(command, argv)
await new Promise((resolve, reject) => proc.on('exit', (code, signal) => {
if (code !== 0) {
return callback(new Error('`' + command + '` failed with exit code: ' + code))
return reject(new Error('`' + command + '` failed with exit code: ' + code))
}
if (signal) {
return callback(new Error('`' + command + '` got signal: ' + signal))
return reject(new Error('`' + command + '` got signal: ' + signal))
}
callback()
resolve()
}))
}
}
module.exports = build
module.exports = function (gyp, argv, callback) {
build(gyp, argv).then(callback.bind(undefined, null), callback)
}
module.exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'

View file

@ -1,15 +1,17 @@
'use strict'
const rm = require('rimraf')
const log = require('npmlog')
const fs = require('fs/promises')
const log = require('./log')
function clean (gyp, argv, callback) {
async function clean (gyp, argv) {
// Remove the 'build' dir
var buildDir = 'build'
const buildDir = 'build'
log.verbose('clean', 'removing "%s" directory', buildDir)
rm(buildDir, callback)
await fs.rm(buildDir, { recursive: true, force: true })
}
module.exports = clean
module.exports = function (gyp, argv, callback) {
clean(gyp, argv).then(callback.bind(undefined, null), callback)
}
module.exports.usage = 'Removes any generated build files and the "out" dir'

View file

@ -2,26 +2,27 @@
const fs = require('graceful-fs')
const path = require('path')
const log = require('npmlog')
const log = require('./log')
const os = require('os')
const processRelease = require('./process-release')
const win = process.platform === 'win32'
const findNodeDirectory = require('./find-node-directory')
const createConfigGypi = require('./create-config-gypi')
const msgFormat = require('util').format
var findPython = require('./find-python')
const findPython = require('./find-python')
let findVisualStudio
if (win) {
var findVisualStudio = require('./find-visualstudio')
findVisualStudio = require('./find-visualstudio')
}
function configure (gyp, argv, callback) {
var python
var buildDir = path.resolve('build')
var buildBinsDir = path.join(buildDir, 'node_gyp_bins')
var configNames = ['config.gypi', 'common.gypi']
var configs = []
var nodeDir
var release = processRelease(argv, gyp, process.version, process.release)
let python
const buildDir = path.resolve('build')
const buildBinsDir = path.join(buildDir, 'node_gyp_bins')
const configNames = ['config.gypi', 'common.gypi']
const configs = []
let nodeDir
const release = processRelease(argv, gyp, process.version, process.release)
findPython(gyp.opts.python, function (err, found) {
if (err) {
@ -129,11 +130,11 @@ function configure (gyp, argv, callback) {
}
function findConfigs () {
var name = configNames.shift()
const name = configNames.shift()
if (!name) {
return runGyp()
}
var fullPath = path.resolve(name)
const fullPath = path.resolve(name)
log.verbose(name, 'checking for gypi file: %s', fullPath)
fs.stat(fullPath, function (err) {
@ -175,11 +176,13 @@ function configure (gyp, argv, callback) {
// For AIX and z/OS we need to set up the path to the exports file
// which contains the symbols needed for linking.
var nodeExpFile
let nodeExpFile
let nodeRootDir
let candidates
let logprefix = 'find exports file'
if (process.platform === 'aix' || process.platform === 'os390' || process.platform === 'os400') {
var ext = process.platform === 'os390' ? 'x' : 'exp'
var nodeRootDir = findNodeDirectory()
var candidates
const ext = process.platform === 'os390' ? 'x' : 'exp'
nodeRootDir = findNodeDirectory()
if (process.platform === 'aix' || process.platform === 'os400') {
candidates = [
@ -202,12 +205,11 @@ function configure (gyp, argv, callback) {
})
}
var logprefix = 'find exports file'
nodeExpFile = findAccessibleSync(logprefix, nodeRootDir, candidates)
if (nodeExpFile !== undefined) {
log.verbose(logprefix, 'Found exports file: %s', nodeExpFile)
} else {
var msg = msgFormat('Could not find node.%s file in %s', ext, nodeRootDir)
const msg = msgFormat('Could not find node.%s file in %s', ext, nodeRootDir)
log.error(logprefix, 'Could not find exports file')
return callback(new Error(msg))
}
@ -215,11 +217,11 @@ function configure (gyp, argv, callback) {
// For z/OS we need to set up the path to zoslib include directory,
// which contains headers included in v8config.h.
var zoslibIncDir
let zoslibIncDir
if (process.platform === 'os390') {
logprefix = "find zoslib's zos-base.h:"
let msg
var zoslibIncPath = process.env.ZOSLIB_INCLUDES
let zoslibIncPath = process.env.ZOSLIB_INCLUDES
if (zoslibIncPath) {
zoslibIncPath = findAccessibleSync(logprefix, zoslibIncPath, ['zos-base.h'])
if (zoslibIncPath === undefined) {
@ -252,22 +254,22 @@ function configure (gyp, argv, callback) {
}
// this logic ported from the old `gyp_addon` python file
var gypScript = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py')
var addonGypi = path.resolve(__dirname, '..', 'addon.gypi')
var commonGypi = path.resolve(nodeDir, 'include/node/common.gypi')
const gypScript = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py')
const addonGypi = path.resolve(__dirname, '..', 'addon.gypi')
let commonGypi = path.resolve(nodeDir, 'include/node/common.gypi')
fs.stat(commonGypi, function (err) {
if (err) {
commonGypi = path.resolve(nodeDir, 'common.gypi')
}
var outputDir = 'build'
let outputDir = 'build'
if (win) {
// Windows expects an absolute path
outputDir = buildDir
}
var nodeGypDir = path.resolve(__dirname, '..')
const nodeGypDir = path.resolve(__dirname, '..')
var nodeLibFile = path.join(nodeDir,
let nodeLibFile = path.join(nodeDir,
!gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)',
release.name + '.lib')
@ -309,13 +311,13 @@ function configure (gyp, argv, callback) {
argv.unshift(gypScript)
// make sure python uses files that came with this particular node package
var pypath = [path.join(__dirname, '..', 'gyp', 'pylib')]
const pypath = [path.join(__dirname, '..', 'gyp', 'pylib')]
if (process.env.PYTHONPATH) {
pypath.push(process.env.PYTHONPATH)
}
process.env.PYTHONPATH = pypath.join(win ? ';' : ':')
var cp = gyp.spawn(python, argv)
const cp = gyp.spawn(python, argv)
cp.on('exit', onCpExit)
})
}
@ -336,10 +338,11 @@ function configure (gyp, argv, callback) {
* readable.
*/
function findAccessibleSync (logprefix, dir, candidates) {
for (var next = 0; next < candidates.length; next++) {
var candidate = path.resolve(dir, candidates[next])
for (let next = 0; next < candidates.length; next++) {
const candidate = path.resolve(dir, candidates[next])
let fd
try {
var fd = fs.openSync(candidate, 'r')
fd = fs.openSync(candidate, 'r')
} catch (e) {
// this candidate was not found or not readable, do nothing
log.silly(logprefix, 'Could not open %s: %s', candidate, e.message)
@ -355,6 +358,6 @@ function findAccessibleSync (logprefix, dir, candidates) {
module.exports = configure
module.exports.test = {
findAccessibleSync: findAccessibleSync
findAccessibleSync
}
module.exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module'

View file

@ -1,7 +1,7 @@
'use strict'
const fs = require('graceful-fs')
const log = require('npmlog')
const log = require('./log')
const path = require('path')
function parseConfigGypi (config) {
@ -142,6 +142,6 @@ async function createConfigGypi ({ gyp, buildDir, nodeDir, vsInfo }) {
module.exports = createConfigGypi
module.exports.test = {
parseConfigGypi: parseConfigGypi,
getCurrentConfigGypi: getCurrentConfigGypi
parseConfigGypi,
getCurrentConfigGypi
}

View file

@ -1,7 +1,7 @@
'use strict'
const path = require('path')
const log = require('npmlog')
const log = require('./log')
function findNodeDirectory (scriptLocation, processObj) {
// set dirname and process if not passed in
@ -14,10 +14,10 @@ function findNodeDirectory (scriptLocation, processObj) {
}
// Have a look to see what is above us, to try and work out where we are
var npmParentDirectory = path.join(scriptLocation, '../../../..')
const npmParentDirectory = path.join(scriptLocation, '../../../..')
log.verbose('node-gyp root', 'npm_parent_directory is ' +
path.basename(npmParentDirectory))
var nodeRootDir = ''
let nodeRootDir = ''
log.verbose('node-gyp root', 'Finding node root directory')
if (path.basename(npmParentDirectory) === 'deps') {
@ -41,8 +41,8 @@ function findNodeDirectory (scriptLocation, processObj) {
} else {
// We don't know where we are, try working it out from the location
// of the node binary
var nodeDir = path.dirname(processObj.execPath)
var directoryUp = path.basename(nodeDir)
const nodeDir = path.dirname(processObj.execPath)
const directoryUp = path.basename(nodeDir)
if (directoryUp === 'bin') {
nodeRootDir = path.join(nodeDir, '..')
} else if (directoryUp === 'Release' || directoryUp === 'Debug') {

View file

@ -1,11 +1,10 @@
'use strict'
const log = require('npmlog')
const log = require('./log')
const semver = require('semver')
const cp = require('child_process')
const extend = require('util')._extend // eslint-disable-line
const win = process.platform === 'win32'
const logWithPrefix = require('./util').logWithPrefix
const systemDrive = process.env.SystemDrive || 'C:'
const username = process.env.USERNAME || process.env.USER || getOsUserInfo()
@ -46,7 +45,7 @@ function PythonFinder (configPython, callback) {
}
PythonFinder.prototype = {
log: logWithPrefix(log, 'find Python'),
log: log.withPrefix('find Python'),
argsExecutable: ['-c', 'import sys; print(sys.executable);'],
argsVersion: ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);'],
semverRange: '>=3.6.0',
@ -54,7 +53,7 @@ PythonFinder.prototype = {
// These can be overridden for testing:
execFile: cp.execFile,
env: process.env,
win: win,
win,
pyLauncher: 'py.exe',
winDefaultLocations: winDefaultLocationsArray,
@ -69,7 +68,7 @@ PythonFinder.prototype = {
// Ignore errors, keep trying until Python is found.
findPython: function findPython () {
const SKIP = 0; const FAIL = 1
var toCheck = getChecks.apply(this)
const toCheck = getChecks.apply(this)
function getChecks () {
if (this.env.NODE_GYP_FORCE_PYTHON) {
@ -85,7 +84,7 @@ PythonFinder.prototype = {
}]
}
var checks = [
const checks = [
{
before: () => {
if (!this.configPython) {
@ -128,7 +127,7 @@ PythonFinder.prototype = {
]
if (this.win) {
for (var i = 0; i < this.winDefaultLocations.length; ++i) {
for (let i = 0; i < this.winDefaultLocations.length; ++i) {
const location = this.winDefaultLocations[i]
checks.push({
before: () => {
@ -181,9 +180,9 @@ PythonFinder.prototype = {
// Will exit the Python finder on success.
// If on Windows, run in a CMD shell to support BAT/CMD launchers.
checkCommand: function checkCommand (command, errorCallback) {
var exec = command
var args = this.argsExecutable
var shell = false
let exec = command
let args = this.argsExecutable
let shell = false
if (this.win) {
// Arguments have to be manually quoted
exec = `"${exec}"`
@ -250,7 +249,7 @@ PythonFinder.prototype = {
this.addLog(`- version is "${version}"`)
const range = new semver.Range(this.semverRange)
var valid = false
let valid = false
try {
valid = range.test(version)
} catch (err) {
@ -272,9 +271,9 @@ PythonFinder.prototype = {
// Run an executable or shell command, trimming the output.
run: function run (exec, args, shell, callback) {
var env = extend({}, this.env)
const env = extend({}, this.env)
env.TERM = 'dumb'
const opts = { env: env, shell: shell }
const opts = { env, shell }
this.log.silly('execFile: exec = %j', exec)
this.log.silly('execFile: args = %j', args)
@ -306,7 +305,8 @@ PythonFinder.prototype = {
fail: function fail () {
const errorLog = this.errorLog.join('\n')
const pathExample = this.win ? 'C:\\Path\\To\\python.exe'
const pathExample = this.win
? 'C:\\Path\\To\\python.exe'
: '/path/to/pythonexecutable'
// For Windows 80 col console, use up to the column before the one marked
// with X (total 79 chars including logger prefix, 58 chars usable here):
@ -333,12 +333,12 @@ PythonFinder.prototype = {
}
function findPython (configPython, callback) {
var finder = new PythonFinder(configPython, callback)
const finder = new PythonFinder(configPython, callback)
finder.findPython()
}
module.exports = findPython
module.exports.test = {
PythonFinder: PythonFinder,
findPython: findPython
PythonFinder,
findPython
}

View file

@ -1,10 +1,9 @@
'use strict'
const log = require('npmlog')
const log = require('./log')
const execFile = require('child_process').execFile
const fs = require('fs')
const path = require('path').win32
const logWithPrefix = require('./util').logWithPrefix
const regSearchKeys = require('./util').regSearchKeys
function findVisualStudio (nodeSemver, configMsvsVersion, callback) {
@ -22,9 +21,9 @@ function VisualStudioFinder (nodeSemver, configMsvsVersion, callback) {
}
VisualStudioFinder.prototype = {
log: logWithPrefix(log, 'find VS'),
log: log.withPrefix('find VS'),
regSearchKeys: regSearchKeys,
regSearchKeys,
// Logs a message at verbose level, but also saves it to be displayed later
// at error level if an error occurs. This should help diagnose the problem.
@ -126,10 +125,10 @@ VisualStudioFinder.prototype = {
// Invoke the PowerShell script to get information about Visual Studio 2017
// or newer installations
findVisualStudio2017OrNewer: function findVisualStudio2017OrNewer (cb) {
var ps = path.join(process.env.SystemRoot, 'System32',
const ps = path.join(process.env.SystemRoot, 'System32',
'WindowsPowerShell', 'v1.0', 'powershell.exe')
var csFile = path.join(__dirname, 'Find-VisualStudio.cs')
var psArgs = [
const csFile = path.join(__dirname, 'Find-VisualStudio.cs')
const psArgs = [
'-ExecutionPolicy',
'Unrestricted',
'-NoProfile',
@ -138,7 +137,7 @@ VisualStudioFinder.prototype = {
]
this.log.silly('Running', ps, psArgs)
var child = execFile(ps, psArgs, { encoding: 'utf8' },
const child = execFile(ps, psArgs, { encoding: 'utf8' },
(err, stdout, stderr) => {
this.parseData(err, stdout, stderr, cb)
})
@ -161,7 +160,7 @@ VisualStudioFinder.prototype = {
return failPowershell()
}
var vsInfo
let vsInfo
try {
vsInfo = JSON.parse(stdout)
} catch (e) {
@ -178,7 +177,7 @@ VisualStudioFinder.prototype = {
vsInfo = vsInfo.map((info) => {
this.log.silly(`processing installation: "${info.path}"`)
info.path = path.resolve(info.path)
var ret = this.getVersionInfo(info)
const ret = this.getVersionInfo(info)
ret.path = info.path
ret.msBuild = this.getMSBuild(info, ret.versionYear)
ret.toolset = this.getToolset(info, ret.versionYear)
@ -199,7 +198,7 @@ VisualStudioFinder.prototype = {
// Sort to place newer versions first
vsInfo.sort((a, b) => b.versionYear - a.versionYear)
for (var i = 0; i < vsInfo.length; ++i) {
for (let i = 0; i < vsInfo.length; ++i) {
const info = vsInfo[i]
this.addLog(`checking VS${info.versionYear} (${info.version}) found ` +
`at:\n"${info.path}"`)
@ -245,7 +244,7 @@ VisualStudioFinder.prototype = {
return {}
}
this.log.silly('- version match = %j', match)
var ret = {
const ret = {
version: info.version,
versionMajor: parseInt(match[1], 10),
versionMinor: parseInt(match[2], 10)
@ -327,7 +326,7 @@ VisualStudioFinder.prototype = {
const win10SDKPrefix = 'Microsoft.VisualStudio.Component.Windows10SDK.'
const win11SDKPrefix = 'Microsoft.VisualStudio.Component.Windows11SDK.'
var Win10or11SDKVer = 0
let Win10or11SDKVer = 0
info.packages.forEach((pkg) => {
if (!pkg.startsWith(win10SDKPrefix) && !pkg.startsWith(win11SDKPrefix)) {
return
@ -458,6 +457,6 @@ VisualStudioFinder.prototype = {
module.exports = findVisualStudio
module.exports.test = {
VisualStudioFinder: VisualStudioFinder,
findVisualStudio: findVisualStudio
VisualStudioFinder,
findVisualStudio
}

View file

@ -9,7 +9,7 @@ const path = require('path')
const util = require('util')
const stream = require('stream')
const crypto = require('crypto')
const log = require('npmlog')
const log = require('./log')
const semver = require('semver')
const fetch = require('make-fetch-happen')
const processRelease = require('./process-release')

View file

@ -1,10 +1,10 @@
'use strict'
const fs = require('graceful-fs')
const log = require('npmlog')
const log = require('./log')
function list (gyp, args, callback) {
var devDir = gyp.devDir
const devDir = gyp.devDir
log.verbose('list', 'using node-gyp dir:', devDir)
fs.readdir(devDir, onreaddir)

165
lib/log.js Normal file
View file

@ -0,0 +1,165 @@
'use strict'
const procLog = require('proc-log')
const { format } = require('util')
// helper to emit log messages with a predefined prefix
const logLevels = Object.keys(procLog).filter((k) => typeof procLog[k] === 'function')
const withPrefix = (prefix) => logLevels.reduce((acc, level) => {
acc[level] = (...args) => procLog[level](prefix, ...args)
return acc
}, {})
// very basic ansi color generator
const COLORS = {
wrap: (str, colors) => {
const codes = colors.filter(c => typeof c === 'number')
return `\x1b[${codes.join(';')}m${str}\x1b[0m`
},
inverse: 7,
fg: {
black: 30,
red: 31,
green: 32,
yellow: 33,
blue: 34,
magenta: 35,
cyan: 36,
white: 37
},
bg: {
black: 40,
red: 41,
green: 42,
yellow: 43,
blue: 44,
magenta: 45,
cyan: 46,
white: 47
}
}
class Logger {
#buffer = []
#paused = null
#level = null
#stream = null
// ordered from loudest to quietest
#levels = [{
id: 'silly',
display: 'sill',
style: { inverse: true }
}, {
id: 'verbose',
display: 'verb',
style: { fg: 'cyan', bg: 'black' }
}, {
id: 'info',
style: { fg: 'green' }
}, {
id: 'http',
style: { fg: 'green', bg: 'black' }
}, {
id: 'notice',
style: { fg: 'cyan', bg: 'black' }
}, {
id: 'warn',
display: 'WARN',
style: { fg: 'black', bg: 'yellow' }
}, {
id: 'error',
display: 'ERR!',
style: { fg: 'red', bg: 'black' }
}]
constructor () {
process.on('log', (...args) => this.#onLog(...args))
this.#levels = new Map(this.#levels.map((level, index) => [level.id, { ...level, index }]))
this.level = 'info'
this.stream = process.stderr
procLog.pause()
}
get stream () {
return this.#stream
}
set stream (stream) {
this.#stream = stream
}
get level () {
return this.#levels.get(this.#level) ?? null
}
set level (level) {
this.#level = this.#levels.get(level)?.id ?? null
}
isVisible (level) {
return this.level?.index <= this.#levels.get(level)?.index ?? -1
}
#onLog (...args) {
const [level] = args
if (level === 'pause') {
this.#paused = true
return
}
if (level === 'resume') {
this.#paused = false
this.#buffer.forEach((b) => this.#log(...b))
this.#buffer.length = 0
return
}
if (this.#paused) {
this.#buffer.push(args)
return
}
this.#log(...args)
}
#color (str, { fg, bg, inverse }) {
if (!this.#stream?.isTTY) {
return str
}
return COLORS.wrap(str, [
COLORS.fg[fg],
COLORS.bg[bg],
inverse && COLORS.inverse
])
}
#log (levelId, msgPrefix, ...args) {
if (!this.isVisible(levelId) || typeof this.#stream?.write !== 'function') {
return
}
const level = this.#levels.get(levelId)
const prefixParts = [
this.#color('gyp', { fg: 'white', bg: 'black' }),
this.#color(level.display ?? level.id, level.style)
]
if (msgPrefix) {
prefixParts.push(this.#color(msgPrefix, { fg: 'magenta' }))
}
const prefix = prefixParts.join(' ').trim() + ' '
const lines = format(...args).split(/\r?\n/).map(l => prefix + l.trim())
this.#stream.write(lines.join('\n') + '\n')
}
}
module.exports = {
logger: new Logger(),
withPrefix,
...procLog
}

View file

@ -2,7 +2,7 @@
const path = require('path')
const nopt = require('nopt')
const log = require('npmlog')
const log = require('./log')
const childProcess = require('child_process')
const EE = require('events').EventEmitter
const inherits = require('util').inherits
@ -22,15 +22,12 @@ const aliases = {
rm: 'remove'
}
// differentiate node-gyp's logs from npm's
log.heading = 'gyp'
function gyp () {
return new Gyp()
}
function Gyp () {
var self = this
const self = this
this.devDir = ''
this.commands = {}
@ -44,7 +41,7 @@ function Gyp () {
}
inherits(Gyp, EE)
exports.Gyp = Gyp
var proto = Gyp.prototype
const proto = Gyp.prototype
/**
* Export the contents of the package.json.
@ -108,7 +105,7 @@ proto.parseArgv = function parseOpts (argv) {
this.opts = nopt(this.configDefs, this.shorthands, argv)
this.argv = this.opts.argv.remain.slice()
var commands = this.todo = []
const commands = this.todo = []
// create a copy of the argv array with aliases mapped
argv = this.argv.map(function (arg) {
@ -122,7 +119,7 @@ proto.parseArgv = function parseOpts (argv) {
// process the mapped args into "command" objects ("name" and "args" props)
argv.slice().forEach(function (arg) {
if (arg in this.commands) {
var args = argv.splice(0, argv.indexOf(arg))
const args = argv.splice(0, argv.indexOf(arg))
argv.shift()
if (commands.length > 0) {
commands[commands.length - 1].args = args
@ -135,14 +132,14 @@ proto.parseArgv = function parseOpts (argv) {
}
// support for inheriting config env variables from npm
var npmConfigPrefix = 'npm_config_'
const npmConfigPrefix = 'npm_config_'
Object.keys(process.env).forEach(function (name) {
if (name.indexOf(npmConfigPrefix) !== 0) {
return
}
var val = process.env[name]
const val = process.env[name]
if (name === npmConfigPrefix + 'loglevel') {
log.level = val
log.logger.level = val
} else {
// add the user-defined options to the config
name = name.substring(npmConfigPrefix.length)
@ -159,7 +156,7 @@ proto.parseArgv = function parseOpts (argv) {
}, this)
if (this.opts.loglevel) {
log.level = this.opts.loglevel
log.logger.level = this.opts.loglevel
}
log.resume()
}
@ -175,7 +172,7 @@ proto.spawn = function spawn (command, args, opts) {
if (!opts.silent && !opts.stdio) {
opts.stdio = [0, 1, 2]
}
var cp = childProcess.spawn(command, args, opts)
const cp = childProcess.spawn(command, args, opts)
log.info('spawn', command)
log.info('spawn args', args)
return cp
@ -186,7 +183,7 @@ proto.spawn = function spawn (command, args, opts) {
*/
proto.usage = function usage () {
var str = [
const str = [
'',
' Usage: node-gyp <command> [options]',
'',

View file

@ -1,11 +1,11 @@
/* eslint-disable node/no-deprecated-api */
/* eslint-disable n/no-deprecated-api */
'use strict'
const semver = require('semver')
const url = require('url')
const path = require('path')
const log = require('npmlog')
const log = require('./log')
// versions where -headers.tar.gz started shipping
const headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42'
@ -17,29 +17,28 @@ const bitsreV3 = /\/win-(x86|ia32|x64)\// // io.js v3.x.x shipped with "ia32" bu
// file names. Inputs come from command-line switches (--target, --dist-url),
// `process.version` and `process.release` where it exists.
function processRelease (argv, gyp, defaultVersion, defaultRelease) {
var version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion
var versionSemver = semver.parse(version)
var overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl
var isDefaultVersion
var isNamedForLegacyIojs
var name
var distBaseUrl
var baseUrl
var libUrl32
var libUrl64
var libUrlArm64
var tarballUrl
var canGetHeaders
let version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion
const versionSemver = semver.parse(version)
let overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl
let isNamedForLegacyIojs
let name
let distBaseUrl
let baseUrl
let libUrl32
let libUrl64
let libUrlArm64
let tarballUrl
let canGetHeaders
if (!versionSemver) {
// not a valid semver string, nothing we can do
return { version: version }
return { version }
}
// flatten version into String
version = versionSemver.version
// defaultVersion should come from process.version so ought to be valid semver
isDefaultVersion = version === semver.parse(defaultVersion).version
const isDefaultVersion = version === semver.parse(defaultVersion).version
// can't use process.release if we're using --target=x.y.z
if (!isDefaultVersion) {
@ -101,11 +100,11 @@ function processRelease (argv, gyp, defaultVersion, defaultRelease) {
}
return {
version: version,
version,
semver: versionSemver,
name: name,
baseUrl: baseUrl,
tarballUrl: tarballUrl,
name,
baseUrl,
tarballUrl,
shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'),
versionDir: (name !== 'node' ? name + '-' : '') + version,
ia32: {
@ -128,8 +127,8 @@ function normalizePath (p) {
}
function resolveLibUrl (name, defaultUrl, arch, versionMajor) {
var base = url.resolve(defaultUrl, './')
var hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl))
const base = url.resolve(defaultUrl, './')
const hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl))
if (!hasLibUrl) {
// let's assume it's a baseUrl then

View file

@ -1,46 +1,45 @@
'use strict'
const fs = require('fs')
const rm = require('rimraf')
const fs = require('fs/promises')
const path = require('path')
const log = require('npmlog')
const log = require('./log')
const semver = require('semver')
function remove (gyp, argv, callback) {
var devDir = gyp.devDir
async function remove (gyp, argv) {
const devDir = gyp.devDir
log.verbose('remove', 'using node-gyp dir:', devDir)
// get the user-specified version to remove
var version = argv[0] || gyp.opts.target
let version = argv[0] || gyp.opts.target
log.verbose('remove', 'removing target version:', version)
if (!version) {
return callback(new Error('You must specify a version number to remove. Ex: "' + process.version + '"'))
throw new Error('You must specify a version number to remove. Ex: "' + process.version + '"')
}
var versionSemver = semver.parse(version)
const versionSemver = semver.parse(version)
if (versionSemver) {
// flatten the version Array into a String
version = versionSemver.version
}
var versionPath = path.resolve(gyp.devDir, version)
const versionPath = path.resolve(gyp.devDir, version)
log.verbose('remove', 'removing development files for version:', version)
// first check if its even installed
fs.stat(versionPath, function (err) {
if (err) {
try {
await fs.stat(versionPath)
} catch (err) {
if (err.code === 'ENOENT') {
callback(null, 'version was already uninstalled: ' + version)
} else {
callback(err)
return 'version was already uninstalled: ' + version
}
return
}
// Go ahead and delete the dir
rm(versionPath, callback)
})
throw err
}
module.exports = exports = remove
await fs.rm(versionPath, { recursive: true, force: true })
}
module.exports = function (gyp, argv, callback) {
remove(gyp, argv).then(callback.bind(undefined, null), callback)
}
module.exports.usage = 'Removes the node development files for the specified version'

View file

@ -1,22 +1,9 @@
'use strict'
const log = require('npmlog')
const log = require('./log')
const execFile = require('child_process').execFile
const path = require('path')
function logWithPrefix (log, prefix) {
function setPrefix (logFunction) {
return (...args) => logFunction.apply(null, [ prefix, ...args ]) // eslint-disable-line
}
return {
silly: setPrefix(log.silly),
verbose: setPrefix(log.verbose),
info: setPrefix(log.info),
warn: setPrefix(log.warn),
error: setPrefix(log.error)
}
}
function regGetValue (key, value, addOpts, cb) {
const outReValue = value.replace(/\W/g, '.')
const outRe = new RegExp(`^\\s+${outReValue}\\s+REG_\\w+\\s+(\\S.*)$`, 'im')
@ -45,7 +32,7 @@ function regGetValue (key, value, addOpts, cb) {
}
function regSearchKeys (keys, value, addOpts, cb) {
var i = 0
let i = 0
const search = () => {
log.silly('reg-search', 'looking for %j in %j', value, keys[i])
regGetValue(keys[i], value, addOpts, (err, res) => {
@ -58,7 +45,6 @@ function regSearchKeys (keys, value, addOpts, cb) {
}
module.exports = {
logWithPrefix: logWithPrefix,
regGetValue: regGetValue,
regSearchKeys: regSearchKeys
regGetValue,
regSearchKeys
}

View file

@ -24,25 +24,24 @@
"dependencies": {
"env-paths": "^2.2.0",
"exponential-backoff": "^3.1.1",
"glob": "^7.1.4",
"glob": "^8.0.3",
"graceful-fs": "^4.2.6",
"make-fetch-happen": "^11.0.3",
"nopt": "^6.0.0",
"npmlog": "^6.0.0",
"rimraf": "^3.0.2",
"nopt": "^7.0.0",
"proc-log": "^3.0.0",
"semver": "^7.3.5",
"tar": "^6.1.2",
"which": "^2.0.2"
"which": "^3.0.0"
},
"engines": {
"node": "^12.13 || ^14.13 || >=16"
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
},
"devDependencies": {
"bindings": "^1.5.0",
"mocha": "^10.2.0",
"nan": "^2.14.2",
"require-inject": "^1.4.4",
"standard": "^14.3.4"
"standard": "^17.0.0"
},
"scripts": {
"lint": "standard */*.js test/**/*.js",

View file

@ -12,7 +12,7 @@ function startsWith (str, search, pos) {
}
function processExecSync (file, args, options) {
var child, error, timeout, tmpdir, command
let error, command
command = makeCommand(file, args)
/*
@ -22,10 +22,10 @@ function processExecSync (file, args, options) {
options = options || {}
// init timeout
timeout = Date.now() + options.timeout
const timeout = Date.now() + options.timeout
// init tmpdir
var osTempBase = '/tmp'
var os = determineOS()
let osTempBase = '/tmp'
const os = determineOS()
osTempBase = '/tmp'
if (process.env.TMP) {
@ -36,7 +36,7 @@ function processExecSync (file, args, options) {
osTempBase += '/'
}
tmpdir = osTempBase + 'processExecSync.' + Date.now() + Math.random()
const tmpdir = osTempBase + 'processExecSync.' + Date.now() + Math.random()
fs.mkdirSync(tmpdir)
// init command
@ -49,13 +49,13 @@ function processExecSync (file, args, options) {
}
// init child
child = childProcess.exec(command, options)
const child = childProcess.exec(command, options)
var maxTry = 100000 // increases the test time by 6 seconds on win-2016-node-0.10
var tryCount = 0
const maxTry = 100000 // increases the test time by 6 seconds on win-2016-node-0.10
let tryCount = 0
while (tryCount < maxTry) {
try {
var x = fs.readFileSync(tmpdir + '/status')
const x = fs.readFileSync(tmpdir + '/status')
if (x.toString() === '0') {
break
}
@ -87,10 +87,10 @@ function processExecSync (file, args, options) {
}
function makeCommand (file, args) {
var command, quote
let command, quote
command = file
if (args.length > 0) {
for (var i in args) {
for (const i in args) {
command = command + ' '
if (args[i][0] === '-') {
command = command + args[i]
@ -112,8 +112,8 @@ function makeCommand (file, args) {
}
function determineOS () {
var os = ''
var tmpVar = ''
let os = ''
let tmpVar = ''
if (process.env.OSTYPE) {
tmpVar = process.env.OSTYPE
} else if (process.env.OS) {

View file

@ -6,7 +6,7 @@ const server = http.createServer(handler)
const port = +process.argv[2]
const prefix = process.argv[3]
const upstream = process.argv[4]
var calls = 0
let calls = 0
server.listen(port)
@ -15,7 +15,7 @@ function handler (req, res) {
throw new Error('request url [' + req.url + '] does not start with [' + prefix + ']')
}
var upstreamUrl = upstream + req.url.substring(prefix.length)
const upstreamUrl = upstream + req.url.substring(prefix.length)
https.get(upstreamUrl, function (ures) {
ures.on('end', function () {
if (++calls === 2) {

View file

@ -15,24 +15,24 @@ function runHello (hostProcess) {
if (!hostProcess) {
hostProcess = process.execPath
}
var testCode = "console.log(require('hello_world').hello())"
const testCode = "console.log(require('hello_world').hello())"
return execFileSync(hostProcess, ['-e', testCode], { cwd: __dirname }).toString()
}
function getEncoding () {
var code = 'import locale;print(locale.getdefaultlocale()[1])'
const code = 'import locale;print(locale.getdefaultlocale()[1])'
return execFileSync('python', ['-c', code]).toString().trim()
}
function checkCharmapValid () {
var data
let data
try {
data = execFileSync('python', ['fixtures/test-charmap.py'],
{ cwd: __dirname })
} catch (err) {
return false
}
var lines = data.toString().trim().split('\n')
const lines = data.toString().trim().split('\n')
return lines.pop() === 'True'
}
@ -41,10 +41,10 @@ describe('addon', function () {
it('build simple addon', function (done) {
// Set the loglevel otherwise the output disappears when run via 'npm test'
var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose']
var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
var logLines = stderr.toString().trim().split(/\r?\n/)
var lastLine = logLines[logLines.length - 1]
const cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose']
const proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
const logLines = stderr.toString().trim().split(/\r?\n/)
const lastLine = logLines[logLines.length - 1]
assert.strictEqual(err, null)
assert.strictEqual(lastLine, 'gyp info ok', 'should end in ok')
assert.strictEqual(runHello().trim(), 'world')
@ -59,13 +59,13 @@ describe('addon', function () {
return this.skip('python console app can\'t encode non-ascii character.')
}
var testDirNames = {
const testDirNames = {
cp936: '文件夹',
cp1252: 'Latīna',
cp932: 'フォルダ'
}
// Select non-ascii characters by current encoding
var testDirName = testDirNames[getEncoding()]
const testDirName = testDirNames[getEncoding()]
// If encoding is UTF-8 or other then no need to test
if (!testDirName) {
return this.skip('no need to test')
@ -73,17 +73,17 @@ describe('addon', function () {
this.timeout(300000)
var data
var configPath = path.join(addonPath, 'build', 'config.gypi')
let data
const configPath = path.join(addonPath, 'build', 'config.gypi')
try {
data = fs.readFileSync(configPath, 'utf8')
} catch (err) {
assert.fail(err)
return
}
var config = JSON.parse(data.replace(/#.+\n/, ''))
var nodeDir = config.variables.nodedir
var testNodeDir = path.join(addonPath, testDirName)
const config = JSON.parse(data.replace(/#.+\n/, ''))
const nodeDir = config.variables.nodedir
const testNodeDir = path.join(addonPath, testDirName)
// Create symbol link to path with non-ascii characters
try {
fs.symlinkSync(nodeDir, testNodeDir, 'dir')
@ -99,7 +99,7 @@ describe('addon', function () {
}
}
var cmd = [
const cmd = [
nodeGyp,
'rebuild',
'-C',
@ -107,15 +107,15 @@ describe('addon', function () {
'--loglevel=verbose',
'-nodedir=' + testNodeDir
]
var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
const proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
try {
fs.unlink(testNodeDir)
} catch (err) {
assert.fail(err)
}
var logLines = stderr.toString().trim().split(/\r?\n/)
var lastLine = logLines[logLines.length - 1]
const logLines = stderr.toString().trim().split(/\r?\n/)
const lastLine = logLines[logLines.length - 1]
assert.strictEqual(err, null)
assert.strictEqual(lastLine, 'gyp info ok', 'should end in ok')
assert.strictEqual(runHello().trim(), 'world')
@ -133,13 +133,13 @@ describe('addon', function () {
this.timeout(300000)
var notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath))
const notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath))
fs.copyFileSync(process.execPath, notNodePath)
var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose']
var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
var logLines = stderr.toString().trim().split(/\r?\n/)
var lastLine = logLines[logLines.length - 1]
const cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose']
const proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
const logLines = stderr.toString().trim().split(/\r?\n/)
const lastLine = logLines[logLines.length - 1]
assert.strictEqual(err, null)
assert.strictEqual(lastLine, 'gyp info ok', 'should end in ok')
assert.strictEqual(runHello(notNodePath).trim(), 'world')

View file

@ -5,6 +5,7 @@ const assert = require('assert')
const path = require('path')
const devDir = require('./common').devDir()
const gyp = require('../lib/node-gyp')
const log = require('../lib/log')
const requireInject = require('require-inject')
const configure = requireInject('../lib/configure', {
'graceful-fs': {
@ -21,17 +22,17 @@ const configure = requireInject('../lib/configure', {
}
})
log.logger.stream = null
const EXPECTED_PYPATH = path.join(__dirname, '..', 'gyp', 'pylib')
const SEPARATOR = process.platform === 'win32' ? ';' : ':'
const SPAWN_RESULT = cb => ({ on: function () { cb() } })
require('npmlog').level = 'warn'
describe('configure-python', function () {
it('configure PYTHONPATH with no existing env', function (done) {
delete process.env.PYTHONPATH
var prog = gyp()
const prog = gyp()
prog.parseArgv([])
prog.spawn = function () {
assert.strictEqual(process.env.PYTHONPATH, EXPECTED_PYPATH)
@ -42,15 +43,15 @@ describe('configure-python', function () {
})
it('configure PYTHONPATH with existing env of one dir', function (done) {
var existingPath = path.join('a', 'b')
const existingPath = path.join('a', 'b')
process.env.PYTHONPATH = existingPath
var prog = gyp()
const prog = gyp()
prog.parseArgv([])
prog.spawn = function () {
assert.strictEqual(process.env.PYTHONPATH, [EXPECTED_PYPATH, existingPath].join(SEPARATOR))
var dirs = process.env.PYTHONPATH.split(SEPARATOR)
const dirs = process.env.PYTHONPATH.split(SEPARATOR)
assert.deepStrictEqual(dirs, [EXPECTED_PYPATH, existingPath])
return SPAWN_RESULT(done)
@ -60,17 +61,17 @@ describe('configure-python', function () {
})
it('configure PYTHONPATH with existing env of multiple dirs', function (done) {
var pythonDir1 = path.join('a', 'b')
var pythonDir2 = path.join('b', 'c')
var existingPath = [pythonDir1, pythonDir2].join(SEPARATOR)
const pythonDir1 = path.join('a', 'b')
const pythonDir2 = path.join('b', 'c')
const existingPath = [pythonDir1, pythonDir2].join(SEPARATOR)
process.env.PYTHONPATH = existingPath
var prog = gyp()
const prog = gyp()
prog.parseArgv([])
prog.spawn = function () {
assert.strictEqual(process.env.PYTHONPATH, [EXPECTED_PYPATH, existingPath].join(SEPARATOR))
var dirs = process.env.PYTHONPATH.split(SEPARATOR)
const dirs = process.env.PYTHONPATH.split(SEPARATOR)
assert.deepStrictEqual(dirs, [EXPECTED_PYPATH, pythonDir1, pythonDir2])
return SPAWN_RESULT(done)

View file

@ -2,7 +2,7 @@
const { describe, it, after } = require('mocha')
const assert = require('assert')
const fs = require('fs')
const fs = require('fs/promises')
const path = require('path')
const util = require('util')
const http = require('http')
@ -10,12 +10,11 @@ const https = require('https')
const install = require('../lib/install')
const semver = require('semver')
const devDir = require('./common').devDir()
const rimraf = require('rimraf')
const gyp = require('../lib/node-gyp')
const log = require('npmlog')
const log = require('../lib/log')
const certs = require('./fixtures/certs')
log.level = 'warn'
log.logger.stream = null
describe('download', function () {
it('download over http', async function () {
@ -43,12 +42,12 @@ describe('download', function () {
const cacontents = certs['ca.crt']
const cert = certs['server.crt']
const key = certs['server.key']
await fs.promises.writeFile(cafile, cacontents, 'utf8')
await fs.writeFile(cafile, cacontents, 'utf8')
const ca = await install.test.readCAFile(cafile)
assert.strictEqual(ca.length, 1)
const options = { ca: ca, cert: cert, key: key }
const options = { ca, cert, key }
const server = https.createServer(options, (req, res) => {
assert.strictEqual(req.headers['user-agent'], `node-gyp v42 (node ${process.version})`)
res.end('ok')
@ -56,7 +55,7 @@ describe('download', function () {
after(async () => {
await new Promise((resolve) => server.close(resolve))
await fs.promises.unlink(cafile)
await fs.unlink(cafile)
})
server.on('clientError', (err) => { throw err })
@ -149,9 +148,9 @@ describe('download', function () {
it('check certificate splitting', async function () {
const cafile = path.join(__dirname, 'fixtures/ca-bundle.crt')
const cacontents = certs['ca-bundle.crt']
await fs.promises.writeFile(cafile, cacontents, 'utf8')
await fs.writeFile(cafile, cacontents, 'utf8')
after(async () => {
await fs.promises.unlink(cafile)
await fs.unlink(cafile)
})
const cas = await install.test.readCAFile(path.join(__dirname, 'fixtures/ca-bundle.crt'))
assert.strictEqual(cas.length, 2)
@ -171,7 +170,7 @@ describe('download', function () {
this.timeout(300000)
const expectedDir = path.join(devDir, process.version.replace(/^v/, ''))
await util.promisify(rimraf)(expectedDir)
await fs.rm(expectedDir, { recursive: true, force: true })
const prog = gyp()
prog.parseArgv([])
@ -179,10 +178,10 @@ describe('download', function () {
log.level = 'warn'
await util.promisify(install)(prog, [])
const data = await fs.promises.readFile(path.join(expectedDir, 'installVersion'), 'utf8')
const data = await fs.readFile(path.join(expectedDir, 'installVersion'), 'utf8')
assert.strictEqual(data, '11\n', 'correct installVersion')
const list = await fs.promises.readdir(path.join(expectedDir, 'include/node'))
const list = await fs.readdir(path.join(expectedDir, 'include/node'))
assert.ok(list.includes('common.gypi'))
assert.ok(list.includes('config.gypi'))
assert.ok(list.includes('node.h'))
@ -194,7 +193,7 @@ describe('download', function () {
assert.ok(list.includes('v8.h'))
assert.ok(list.includes('zlib.h'))
const lines = (await fs.promises.readFile(path.join(expectedDir, 'include/node/node_version.h'), 'utf8')).split('\n')
const lines = (await fs.readFile(path.join(expectedDir, 'include/node/node_version.h'), 'utf8')).split('\n')
// extract the 3 version parts from the defines to build a valid version string and
// and check them against our current env version

View file

@ -11,7 +11,7 @@ const configure = requireInject('../lib/configure', {
if (readableFiles.some(function (f) { return f === path })) {
return 0
} else {
var error = new Error('ENOENT - not found')
const error = new Error('ENOENT - not found')
throw error
}
}
@ -30,44 +30,44 @@ const readableFiles = [
describe('find-accessible-sync', function () {
it('find accessible - empty array', function () {
var candidates = []
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = []
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, undefined)
})
it('find accessible - single item array, readable', function () {
var candidates = [readableFile]
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = [readableFile]
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, path.resolve(dir, readableFile))
})
it('find accessible - single item array, readable in subdir', function () {
var candidates = [readableFileInDir]
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = [readableFileInDir]
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, path.resolve(dir, readableFileInDir))
})
it('find accessible - single item array, unreadable', function () {
var candidates = ['unreadable_file']
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = ['unreadable_file']
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, undefined)
})
it('find accessible - multi item array, no matches', function () {
var candidates = ['non_existent_file', 'unreadable_file']
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = ['non_existent_file', 'unreadable_file']
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, undefined)
})
it('find accessible - multi item array, single match', function () {
var candidates = ['non_existent_file', readableFile]
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = ['non_existent_file', readableFile]
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, path.resolve(dir, readableFile))
})
it('find accessible - multi item array, return first match', function () {
var candidates = ['non_existent_file', anotherReadableFile, readableFile]
var found = configure.test.findAccessibleSync('test', dir, candidates)
const candidates = ['non_existent_file', anotherReadableFile, readableFile]
const found = configure.test.findAccessibleSync('test', dir, candidates)
assert.strictEqual(found, path.resolve(dir, anotherReadableFile))
})
})

View file

@ -13,8 +13,8 @@ describe('find-node-directory', function () {
// in a build tree where npm is installed in
// .... /deps/npm
it('test find-node-directory - node install', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
for (let next = 0; next < platforms.length; next++) {
const processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
assert.strictEqual(
findNodeDirectory('/x/deps/npm/node_modules/node-gyp/lib', processObj),
path.join('/x'))
@ -27,8 +27,8 @@ describe('find-node-directory', function () {
// .... /lib/node_modules/npm or .../node_modules/npm
// depending on the patform
it('test find-node-directory - node build', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
for (let next = 0; next < platforms.length; next++) {
const processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
if (platforms[next] === 'win32') {
assert.strictEqual(
findNodeDirectory('/y/node_modules/npm/node_modules/node-gyp/lib',
@ -44,8 +44,8 @@ describe('find-node-directory', function () {
// we should find the directory based on the execPath
// for node and match because it was in the bin directory
it('test find-node-directory - node in bin directory', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
for (let next = 0; next < platforms.length; next++) {
const processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
assert.strictEqual(
findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj),
path.join('/x/y'))
@ -55,8 +55,8 @@ describe('find-node-directory', function () {
// we should find the directory based on the execPath
// for node and match because it was in the Release directory
it('test find-node-directory - node in build release dir', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj
for (let next = 0; next < platforms.length; next++) {
let processObj
if (platforms[next] === 'win32') {
processObj = { execPath: '/x/y/Release/node', platform: platforms[next] }
} else {
@ -75,8 +75,8 @@ describe('find-node-directory', function () {
// we should find the directory based on the execPath
// for node and match because it was in the Debug directory
it('test find-node-directory - node in Debug release dir', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj
for (let next = 0; next < platforms.length; next++) {
let processObj
if (platforms[next] === 'win32') {
processObj = { execPath: '/a/b/Debug/node', platform: platforms[next] }
} else {
@ -92,8 +92,8 @@ describe('find-node-directory', function () {
// we should not find it as it will not match based on the execPath nor
// the directory from which the script is running
it('test find-node-directory - not found', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj = { execPath: '/x/y/z/y', platform: next }
for (let next = 0; next < platforms.length; next++) {
const processObj = { execPath: '/x/y/z/y', platform: next }
assert.strictEqual(findNodeDirectory('/a/b/c/d', processObj), '')
}
})
@ -105,8 +105,8 @@ describe('find-node-directory', function () {
// same test as above but make sure additional directory entries
// don't cause an issue
it('test find-node-directory - node install', function () {
for (var next = 0; next < platforms.length; next++) {
var processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
for (let next = 0; next < platforms.length; next++) {
const processObj = { execPath: '/x/y/bin/node', platform: platforms[next] }
assert.strictEqual(
findNodeDirectory('/x/y/z/a/b/c/deps/npm/node_modules/node-gyp/lib',
processObj), path.join('/x/y/z/a/b/c'))

View file

@ -8,13 +8,11 @@ const findPython = require('../lib/find-python')
const execFile = require('child_process').execFile
const PythonFinder = findPython.test.PythonFinder
require('npmlog').level = 'warn'
describe('find-python', function () {
it('find python', function () {
findPython.test.findPython(null, function (err, found) {
assert.strictEqual(err, null)
var proc = execFile(found, ['-V'], function (err, stdout, stderr) {
const proc = execFile(found, ['-V'], function (err, stdout, stderr) {
assert.strictEqual(err, null)
assert.ok(/Python 3/.test(stdout))
assert.strictEqual(stderr, '')
@ -29,7 +27,7 @@ describe('find-python', function () {
console.error(Error(`Property ${property} should not have been accessed.`))
process.abort()
}
var descriptor = {
const descriptor = {
configurable: false,
enumerable: false,
get: fail,
@ -42,18 +40,10 @@ describe('find-python', function () {
PythonFinder.apply(this, arguments)
}
TestPythonFinder.prototype = Object.create(PythonFinder.prototype)
// Silence npmlog - remove for debugging
TestPythonFinder.prototype.log = {
silly: () => {},
verbose: () => {},
info: () => {},
warn: () => {},
error: () => {}
}
delete TestPythonFinder.prototype.env.NODE_GYP_FORCE_PYTHON
it('find python - python', function () {
var f = new TestPythonFinder('python', done)
const f = new TestPythonFinder('python', done)
f.execFile = function (program, args, opts, cb) {
f.execFile = function (program, args, opts, cb) {
poison(f, 'execFile')
@ -75,7 +65,7 @@ describe('find-python', function () {
})
it('find python - python too old', function () {
var f = new TestPythonFinder(null, done)
const f = new TestPythonFinder(null, done)
f.execFile = function (program, args, opts, cb) {
if (/sys\.executable/.test(args[args.length - 1])) {
cb(null, '/path/python')
@ -94,7 +84,7 @@ describe('find-python', function () {
})
it('find python - no python', function () {
var f = new TestPythonFinder(null, done)
const f = new TestPythonFinder(null, done)
f.execFile = function (program, args, opts, cb) {
if (/sys\.executable/.test(args[args.length - 1])) {
cb(new Error('not found'))
@ -113,7 +103,7 @@ describe('find-python', function () {
})
it('find python - no python2, no python, unix', function () {
var f = new TestPythonFinder(null, done)
const f = new TestPythonFinder(null, done)
f.checkPyLauncher = assert.fail
f.win = false
@ -133,7 +123,7 @@ describe('find-python', function () {
})
it('find python - no python, use python launcher', function () {
var f = new TestPythonFinder(null, done)
const f = new TestPythonFinder(null, done)
f.win = true
f.execFile = function (program, args, opts, cb) {
@ -165,7 +155,7 @@ describe('find-python', function () {
})
it('find python - no python, no python launcher, good guess', function () {
var f = new TestPythonFinder(null, done)
const f = new TestPythonFinder(null, done)
f.win = true
const expectedProgram = f.winDefaultLocations[0]
@ -191,7 +181,7 @@ describe('find-python', function () {
})
it('find python - no python, no python launcher, bad guess', function () {
var f = new TestPythonFinder(null, done)
const f = new TestPythonFinder(null, done)
f.win = true
f.execFile = function (program, args, opts, cb) {

View file

@ -16,7 +16,7 @@ function poison (object, property) {
console.error(Error(`Property ${property} should not have been accessed.`))
process.abort()
}
var descriptor = {
const descriptor = {
configurable: false,
enumerable: false,
get: fail,
@ -27,14 +27,6 @@ function poison (object, property) {
function TestVisualStudioFinder () { VisualStudioFinder.apply(this, arguments) }
TestVisualStudioFinder.prototype = Object.create(VisualStudioFinder.prototype)
// Silence npmlog - remove for debugging
TestVisualStudioFinder.prototype.log = {
silly: () => {},
verbose: () => {},
info: () => {},
warn: () => {},
error: () => {}
}
describe('find-visualstudio', function () {
it('VS2013', function () {
@ -56,7 +48,7 @@ describe('find-visualstudio', function () {
finder.parseData(new Error(), '', '', cb)
}
finder.regSearchKeys = (keys, value, addOpts, cb) => {
for (var i = 0; i < keys.length; ++i) {
for (let i = 0; i < keys.length; ++i) {
const fullName = `${keys[i]}\\${value}`
switch (fullName) {
case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
@ -93,7 +85,7 @@ describe('find-visualstudio', function () {
finder.parseData(null, data, '', cb)
}
finder.regSearchKeys = (keys, value, addOpts, cb) => {
for (var i = 0; i < keys.length; ++i) {
for (let i = 0; i < keys.length; ++i) {
const fullName = `${keys[i]}\\${value}`
switch (fullName) {
case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
@ -127,7 +119,7 @@ describe('find-visualstudio', function () {
finder.parseData(new Error(), '', '', cb)
}
finder.regSearchKeys = (keys, value, addOpts, cb) => {
for (var i = 0; i < keys.length; ++i) {
for (let i = 0; i < keys.length; ++i) {
const fullName = `${keys[i]}\\${value}`
switch (fullName) {
case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':
@ -439,7 +431,7 @@ describe('find-visualstudio', function () {
finder.parseData(null, data, '', cb)
}
finder.regSearchKeys = (keys, value, addOpts, cb) => {
for (var i = 0; i < keys.length; ++i) {
for (let i = 0; i < keys.length; ++i) {
const fullName = `${keys[i]}\\${value}`
switch (fullName) {
case 'HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7\\14.0':

View file

@ -1,20 +1,17 @@
'use strict'
const { describe, it, after } = require('mocha')
const { rm } = require('fs/promises')
const assert = require('assert')
const path = require('path')
const os = require('os')
const util = require('util')
const { test: { download, install } } = require('../lib/install')
const rimraf = require('rimraf')
const gyp = require('../lib/node-gyp')
const log = require('npmlog')
const semver = require('semver')
const stream = require('stream')
const streamPipeline = util.promisify(stream.pipeline)
log.level = 'error' // we expect a warning
describe('install', function () {
it('EACCES retry once', async () => {
const fs = {
@ -65,11 +62,11 @@ describe('install', function () {
}
after(async () => {
await util.promisify(rimraf)(devDir)
await rm(devDir, { recursive: true, force: true })
})
const expectedDir = path.join(devDir, process.version.replace(/^v/, ''))
await util.promisify(rimraf)(expectedDir)
await rm(expectedDir, { recursive: true, force: true })
await Promise.all([
install(fs, prog, []),
@ -95,7 +92,6 @@ describe('install', function () {
prog.parseArgv([])
prog.devDir = devDir
prog.opts.ensure = true
log.level = 'warn'
await parallelInstallsTest(this, fs, devDir, prog)
})
@ -110,7 +106,6 @@ describe('install', function () {
prog.parseArgv([])
prog.devDir = devDir
prog.opts.ensure = false
log.level = 'warn'
await parallelInstallsTest(this, fs, devDir, prog)
})
@ -125,7 +120,6 @@ describe('install', function () {
prog.parseArgv([])
prog.devDir = devDir
prog.opts.tarball = path.join(devDir, 'node-headers.tar.gz')
log.level = 'warn'
await streamPipeline(
(await download(prog, `https://nodejs.org/dist/${process.version}/node-${process.version}.tar.gz`)).body,

View file

@ -6,7 +6,7 @@ const processRelease = require('../lib/process-release')
describe('process-release', function () {
it('test process release - process.version = 0.8.20', function () {
var release = processRelease([], { opts: {} }, 'v0.8.20', null)
const release = processRelease([], { opts: {} }, 'v0.8.20', null)
assert.strictEqual(release.semver.version, '0.8.20')
delete release.semver
@ -25,7 +25,7 @@ describe('process-release', function () {
})
it('test process release - process.version = 0.10.21', function () {
var release = processRelease([], { opts: {} }, 'v0.10.21', null)
const release = processRelease([], { opts: {} }, 'v0.10.21', null)
assert.strictEqual(release.semver.version, '0.10.21')
delete release.semver
@ -45,7 +45,7 @@ describe('process-release', function () {
// prior to -headers.tar.gz
it('test process release - process.version = 0.12.9', function () {
var release = processRelease([], { opts: {} }, 'v0.12.9', null)
const release = processRelease([], { opts: {} }, 'v0.12.9', null)
assert.strictEqual(release.semver.version, '0.12.9')
delete release.semver
@ -65,7 +65,7 @@ describe('process-release', function () {
// prior to -headers.tar.gz
it('test process release - process.version = 0.10.41', function () {
var release = processRelease([], { opts: {} }, 'v0.10.41', null)
const release = processRelease([], { opts: {} }, 'v0.10.41', null)
assert.strictEqual(release.semver.version, '0.10.41')
delete release.semver
@ -85,7 +85,7 @@ describe('process-release', function () {
// has -headers.tar.gz
it('test process release - process.release ~ node@0.10.42', function () {
var release = processRelease([], { opts: {} }, 'v0.10.42', null)
const release = processRelease([], { opts: {} }, 'v0.10.42', null)
assert.strictEqual(release.semver.version, '0.10.42')
delete release.semver
@ -105,7 +105,7 @@ describe('process-release', function () {
// has -headers.tar.gz
it('test process release - process.release ~ node@0.12.10', function () {
var release = processRelease([], { opts: {} }, 'v0.12.10', null)
const release = processRelease([], { opts: {} }, 'v0.12.10', null)
assert.strictEqual(release.semver.version, '0.12.10')
delete release.semver
@ -124,7 +124,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@4.1.23', function () {
var release = processRelease([], { opts: {} }, 'v4.1.23', {
const release = processRelease([], { opts: {} }, 'v4.1.23', {
name: 'node',
headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz'
})
@ -146,7 +146,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@4.1.23 / corp build', function () {
var release = processRelease([], { opts: {} }, 'v4.1.23', {
const release = processRelease([], { opts: {} }, 'v4.1.23', {
name: 'node',
headersUrl: 'https://some.custom.location/node-v4.1.23-headers.tar.gz'
})
@ -168,7 +168,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@12.8.0 Windows', function () {
var release = processRelease([], { opts: {} }, 'v12.8.0', {
const release = processRelease([], { opts: {} }, 'v12.8.0', {
name: 'node',
sourceUrl: 'https://nodejs.org/download/release/v12.8.0/node-v12.8.0.tar.gz',
headersUrl: 'https://nodejs.org/download/release/v12.8.0/node-v12.8.0-headers.tar.gz',
@ -192,7 +192,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@12.8.0 Windows ARM64', function () {
var release = processRelease([], { opts: {} }, 'v12.8.0', {
const release = processRelease([], { opts: {} }, 'v12.8.0', {
name: 'node',
sourceUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/node-v12.8.0.tar.gz',
headersUrl: 'https://unofficial-builds.nodejs.org/download/release/v12.8.0/node-v12.8.0-headers.tar.gz',
@ -216,7 +216,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@4.1.23 --target=0.10.40', function () {
var release = processRelease([], { opts: { target: '0.10.40' } }, 'v4.1.23', {
const release = processRelease([], { opts: { target: '0.10.40' } }, 'v4.1.23', {
name: 'node',
headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz'
})
@ -238,7 +238,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@4.1.23 --dist-url=https://foo.bar/baz', function () {
var release = processRelease([], { opts: { 'dist-url': 'https://foo.bar/baz' } }, 'v4.1.23', {
const release = processRelease([], { opts: { 'dist-url': 'https://foo.bar/baz' } }, 'v4.1.23', {
name: 'node',
headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz'
})
@ -260,7 +260,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ frankenstein@4.1.23', function () {
var release = processRelease([], { opts: {} }, 'v4.1.23', {
const release = processRelease([], { opts: {} }, 'v4.1.23', {
name: 'frankenstein',
headersUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23-headers.tar.gz'
})
@ -282,7 +282,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ frankenstein@4.1.23 --dist-url=http://foo.bar/baz/', function () {
var release = processRelease([], { opts: { 'dist-url': 'http://foo.bar/baz/' } }, 'v4.1.23', {
const release = processRelease([], { opts: { 'dist-url': 'http://foo.bar/baz/' } }, 'v4.1.23', {
name: 'frankenstein',
headersUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23.tar.gz'
})
@ -304,7 +304,7 @@ describe('process-release', function () {
})
it('test process release - process.release ~ node@4.0.0-rc.4', function () {
var release = processRelease([], { opts: {} }, 'v4.0.0-rc.4', {
const release = processRelease([], { opts: {} }, 'v4.0.0-rc.4', {
name: 'node',
headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz'
})
@ -328,7 +328,7 @@ describe('process-release', function () {
it('test process release - process.release ~ node@4.0.0-rc.4 passed as argv[0]', function () {
// note the missing 'v' on the arg, it should normalise when checking
// whether we're on the default or not
var release = processRelease(['4.0.0-rc.4'], { opts: {} }, 'v4.0.0-rc.4', {
const release = processRelease(['4.0.0-rc.4'], { opts: {} }, 'v4.0.0-rc.4', {
name: 'node',
headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz'
})
@ -352,7 +352,7 @@ describe('process-release', function () {
it('test process release - process.release ~ node@4.0.0-rc.4 - bogus string passed as argv[0]', function () {
// additional arguments can be passed in on the commandline that should be ignored if they
// are not specifying a valid version @ position 0
var release = processRelease(['this is no version!'], { opts: {} }, 'v4.0.0-rc.4', {
const release = processRelease(['this is no version!'], { opts: {} }, 'v4.0.0-rc.4', {
name: 'node',
headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz'
})
@ -376,7 +376,7 @@ describe('process-release', function () {
it('test process release - NODEJS_ORG_MIRROR', function () {
process.env.NODEJS_ORG_MIRROR = 'http://foo.bar'
var release = processRelease([], { opts: {} }, 'v4.1.23', {
const release = processRelease([], { opts: {} }, 'v4.1.23', {
name: 'node',
headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz'
})