diff --git a/.travis.yml b/.travis.yml index 37bce07..4289264 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,11 @@ node_js: - 8 - 10 - 12 - - 14 \ No newline at end of file + - 14 + +jobs: + include: + - name: npm 7 + os: linux + node_js: 14 + before_install: npm i npm@7 -g diff --git a/log.js b/log.js index 707705c..be12d1d 100644 --- a/log.js +++ b/log.js @@ -1,4 +1,6 @@ var log = require('npmlog') +var fs = require('fs') +var path = require('path') module.exports = function (rc, env) { log.heading = 'prebuild-install' @@ -9,5 +11,15 @@ module.exports = function (rc, env) { log.level = env.npm_config_loglevel || 'notice' } + // Temporary workaround for npm 7 which swallows our output + if (process.env.npm_config_prebuild_install_logfile) { + var fp = path.resolve(process.env.npm_config_prebuild_install_logfile) + + log.on('log', function (msg) { + // Only for tests, don't care about performance + fs.appendFileSync(fp, [log.heading, msg.level, msg.prefix, msg.message].join(' ') + '\n') + }) + } + return log } diff --git a/test/skip-test.js b/test/skip-test.js index 30b3645..07cedce 100644 --- a/test/skip-test.js +++ b/test/skip-test.js @@ -5,31 +5,27 @@ var execFileSync = require('child_process').execFileSync var fs = require('fs') var tempy = require('tempy') // Locked to 0.2.1 for node 6 support var cleanEnv = require('./util/clean-env') - -// Old npm (v3?) doesn't support the mechanisms of this test var npm = process.platform === 'win32' ? 'npm.cmd' : 'npm' -var supported = execFileSync(npm, ['-v']).toString().match(/^(\d+)\./)[1] > 3 -supported && test('skips download in standalone package', function (t) { - run(t, 'standalone', '', function (code, logs) { - t.is(code, 1) - t.is(logs.pop(), 'prebuild-install info install installing standalone, skipping download.') +test('skips download in git dependency', function (t) { + // We're not testing this flag. Just that we do hit the code paths before it + run(t, 'git', '--build-from-source', function (logs) { + t.is(logs.pop(), 'prebuild-install info install installing from git repository, skipping download.') t.end() }) }) -supported && test('skips download in git dependency', function (t) { - run(t, 'git', '', function (code, logs) { - t.is(code, 1) - t.is(logs.pop(), 'prebuild-install info install installing from git repository, skipping download.') +test('does not skip download in normal dependency', function (t) { + // We're not testing this flag. Just that we don't hit the code paths before it + run(t, 'tarball', '--build-from-source', function (logs) { + t.is(logs.pop(), 'prebuild-install info install --build-from-source specified, not attempting download.') t.end() }) }) -supported && test('does not skip download in normal dependency', function (t) { +test('does not skip download in standalone package', function (t) { // We're not testing this flag. Just that we don't hit the code paths before it - run(t, 'tarball', '--build-from-source', function (code, logs) { - t.is(code, 1) + run(t, 'standalone', '--build-from-source', function (logs) { t.is(logs.pop(), 'prebuild-install info install --build-from-source specified, not attempting download.') t.end() }) @@ -37,17 +33,14 @@ supported && test('does not skip download in normal dependency', function (t) { function run (t, mode, args, cb) { var addon = tempy.directory() + var logfile = path.join(addon, 'prebuild-install.log') var cwd = addon writePackage(addon, { name: 'addon', version: '1.0.0', - dependencies: { - 'prebuild-install': 'file:' + path.dirname(__dirname) - }, scripts: { - // TODO: npm 7 cannot find "prebuild-install" command in tarball mode - install: 'prebuild-install ' + args + install: 'node ' + path.resolve(__dirname, '..', 'bin.js') + ' ' + args + ' || exit 0' } }) @@ -66,11 +59,22 @@ function run (t, mode, args, cb) { var env = Object.assign(cleanEnv(process.env), { // We shouldn't hit npm or github npm_config_registry: 'http://localhost:1234', - npm_config_addon_binary_host: 'http://localhost:1234' + npm_config_addon_binary_host: 'http://localhost:1234', + npm_config_prefer_offline: 'true', + npm_config_audit: 'false', + + // Temporary workaround for npm 7 which swallows our output + npm_config_prebuild_install_logfile: logfile, + npm_config_loglevel: 'info' }) - exec(npm + ' install --loglevel=info', { cwd, env, encoding: 'utf8' }, function (err, stdout, stderr) { - cb(err && err.code, logs(stderr)) + exec(npm + ' install', { cwd, env }, function (err) { + t.ifError(err, 'no install error') + + fs.readFile(logfile, 'utf8', function (err, data) { + t.ifError(err, 'no read error') + cb(logs(data)) + }) }) } @@ -85,9 +89,18 @@ function prepareGit (cwd) { execFileSync('git', ['add', 'package.json'], { cwd, stdio: 'ignore' }) execFileSync('git', ['commit', '-m', 'test'], { cwd, stdio: 'ignore' }) + if (process.platform === 'win32' && npmVersion() >= 7) { + // Otherwise results in invalid url error + return 'git+file:///' + cwd + } + return 'git+file://' + cwd } +function npmVersion () { + return parseInt(execFileSync(npm, ['-v']).toString()) +} + function prepareTarball (cwd) { // Packs to -.tgz execFileSync(npm, ['pack'], { cwd, stdio: 'ignore' }) @@ -96,9 +109,13 @@ function prepareTarball (cwd) { } function logs (stderr) { - return (stderr || '').split(/\r?\n/).filter(isOurs) + return (stderr || '').split(/\r?\n/).filter(isOurs).map(stripPrefix) } function isOurs (line) { - return /^prebuild-install /.test(line) + return /^(npm ERR! )?prebuild-install /.test(line) +} + +function stripPrefix (line) { + return line.replace(/^npm ERR! /, '') } diff --git a/util.js b/util.js index e16d94f..db358c9 100644 --- a/util.js +++ b/util.js @@ -88,15 +88,20 @@ function tempFile (cached) { } function packageOrigin (env, pkg) { + // npm <= 6: metadata is stored on disk in node_modules + if (pkg._from) { + return pkg._from + } + + // npm 7: metadata is exposed to environment by arborist if (env.npm_package_from) { - // npm 7: metadata is exposed to environment by arborist - // TODO: seems undefined atm (npm 7.0.2) + // NOTE: seems undefined atm (npm 7.0.2) return env.npm_package_from } - if (pkg._from) { - // npm <= 6: metadata is stored on disk in node_modules - return pkg._from + if (env.npm_package_resolved) { + // NOTE: not sure about the difference with _from, but it's all we have + return env.npm_package_resolved } }