| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | 'use strict';/** * Module exports. */module.exports = exports;/** * Module dependencies. */// load mocking control function for accessing s3 via https. the function is a noop always returning// false if not mocking.exports.mockS3Http = require('./util/s3_setup').get_mockS3Http();exports.mockS3Http('on');const mocking = exports.mockS3Http('get');const fs = require('fs');const path = require('path');const nopt = require('nopt');const log = require('npmlog');log.disableProgress();const napi = require('./util/napi.js');const EE = require('events').EventEmitter;const inherits = require('util').inherits;const cli_commands = [  'clean',  'install',  'reinstall',  'build',  'rebuild',  'package',  'testpackage',  'publish',  'unpublish',  'info',  'testbinary',  'reveal',  'configure'];const aliases = {};// differentiate node-pre-gyp's logs from npm'slog.heading = 'node-pre-gyp';if (mocking) {  log.warn(`mocking s3 to ${process.env.node_pre_gyp_mock_s3}`);}// this is a getter to avoid circular reference warnings with node v14.Object.defineProperty(exports, 'find', {  get: function() {    return require('./pre-binding').find;  },  enumerable: true});// in the following, "my_module" is using node-pre-gyp to// prebuild and install pre-built binaries. "main_module"// is using "my_module".//// "bin/node-pre-gyp" invokes Run() without a path. the// expectation is that the working directory is the package// root "my_module". this is true because in all cases npm is// executing a script in the context of "my_module".//// "pre-binding.find()" is executed by "my_module" but in the// context of "main_module". this is because "main_module" is// executing and requires "my_module" which is then executing// "pre-binding.find()" via "node-pre-gyp.find()", so the working// directory is that of "main_module".//// that's why "find()" must pass the path to package.json.//function Run({ package_json_path = './package.json', argv }) {  this.package_json_path = package_json_path;  this.commands = {};  const self = this;  cli_commands.forEach((command) => {    self.commands[command] = function(argvx, callback) {      log.verbose('command', command, argvx);      return require('./' + command)(self, argvx, callback);    };  });  this.parseArgv(argv);  // this is set to true after the binary.host property was set to  // either staging_host or production_host.  this.binaryHostSet = false;}inherits(Run, EE);exports.Run = Run;const proto = Run.prototype;/** * Export the contents of the package.json. */proto.package = require('../package.json');/** * nopt configuration definitions */proto.configDefs = {  help: Boolean,     // everywhere  arch: String,      // 'configure'  debug: Boolean,    // 'build'  directory: String, // bin  proxy: String,     // 'install'  loglevel: String  // everywhere};/** * nopt shorthands */proto.shorthands = {  release: '--no-debug',  C: '--directory',  debug: '--debug',  j: '--jobs',  silent: '--loglevel=silent',  silly: '--loglevel=silly',  verbose: '--loglevel=verbose'};/** * expose the command aliases for the bin file to use. */proto.aliases = aliases;/** * Parses the given argv array and sets the 'opts', 'argv', * 'command', and 'package_json' properties. */proto.parseArgv = function parseOpts(argv) {  this.opts = nopt(this.configDefs, this.shorthands, argv);  this.argv = this.opts.argv.remain.slice();  const commands = this.todo = [];  // create a copy of the argv array with aliases mapped  argv = this.argv.map((arg) => {    // is this an alias?    if (arg in this.aliases) {      arg = this.aliases[arg];    }    return arg;  });  // process the mapped args into "command" objects ("name" and "args" props)  argv.slice().forEach((arg) => {    if (arg in this.commands) {      const args = argv.splice(0, argv.indexOf(arg));      argv.shift();      if (commands.length > 0) {        commands[commands.length - 1].args = args;      }      commands.push({ name: arg, args: [] });    }  });  if (commands.length > 0) {    commands[commands.length - 1].args = argv.splice(0);  }  // if a directory was specified package.json is assumed to be relative  // to it.  let package_json_path = this.package_json_path;  if (this.opts.directory) {    package_json_path = path.join(this.opts.directory, package_json_path);  }  this.package_json = JSON.parse(fs.readFileSync(package_json_path));  // expand commands entries for multiple napi builds  this.todo = napi.expand_commands(this.package_json, this.opts, commands);  // support for inheriting config env variables from npm  const npm_config_prefix = 'npm_config_';  Object.keys(process.env).forEach((name) => {    if (name.indexOf(npm_config_prefix) !== 0) return;    const val = process.env[name];    if (name === npm_config_prefix + 'loglevel') {      log.level = val;    } else {      // add the user-defined options to the config      name = name.substring(npm_config_prefix.length);      // avoid npm argv clobber already present args      // which avoids problem of 'npm test' calling      // script that runs unique npm install commands      if (name === 'argv') {        if (this.opts.argv &&             this.opts.argv.remain &&             this.opts.argv.remain.length) {          // do nothing        } else {          this.opts[name] = val;        }      } else {        this.opts[name] = val;      }    }  });  if (this.opts.loglevel) {    log.level = this.opts.loglevel;  }  log.resume();};/** * allow the binary.host property to be set at execution time. * * for this to take effect requires all the following to be true. * - binary is a property in package.json * - binary.host is falsey * - binary.staging_host is not empty * - binary.production_host is not empty * * if any of the previous checks fail then the function returns an empty string * and makes no changes to package.json's binary property. * * * if command is "publish" then the default is set to "binary.staging_host" * if command is not "publish" the the default is set to "binary.production_host" * * if the command-line option '--s3_host' is set to "staging" or "production" then * "binary.host" is set to the specified "staging_host" or "production_host". if * '--s3_host' is any other value an exception is thrown. * * if '--s3_host' is not present then "binary.host" is set to the default as above. * * this strategy was chosen so that any command other than "publish" uses "production" * as the default without requiring any command-line options but that "publish" requires * '--s3_host production_host' to be specified in order to *really* publish. publishing * to staging can be done freely without worrying about disturbing any production releases. */proto.setBinaryHostProperty = function(command) {  if (this.binaryHostSet) {    return this.package_json.binary.host;  }  const p = this.package_json;  // don't set anything if host is present. it must be left blank to trigger this.  if (!p || !p.binary || p.binary.host) {    return '';  }  // and both staging and production must be present. errors will be reported later.  if (!p.binary.staging_host || !p.binary.production_host) {    return '';  }  let target = 'production_host';  if (command === 'publish') {    target = 'staging_host';  }  // the environment variable has priority over the default or the command line. if  // either the env var or the command line option are invalid throw an error.  const npg_s3_host = process.env.node_pre_gyp_s3_host;  if (npg_s3_host === 'staging' || npg_s3_host === 'production') {    target = `${npg_s3_host}_host`;  } else if (this.opts['s3_host'] === 'staging' || this.opts['s3_host'] === 'production') {    target = `${this.opts['s3_host']}_host`;  } else if (this.opts['s3_host'] || npg_s3_host) {    throw new Error(`invalid s3_host ${this.opts['s3_host'] || npg_s3_host}`);  }  p.binary.host = p.binary[target];  this.binaryHostSet = true;  return p.binary.host;};/** * Returns the usage instructions for node-pre-gyp. */proto.usage = function usage() {  const str = [    '',    '  Usage: node-pre-gyp <command> [options]',    '',    '  where <command> is one of:',    cli_commands.map((c) => {      return '    - ' + c + ' - ' + require('./' + c).usage;    }).join('\n'),    '',    'node-pre-gyp@' + this.version + '  ' + path.resolve(__dirname, '..'),    'node@' + process.versions.node  ].join('\n');  return str;};/** * Version number getter. */Object.defineProperty(proto, 'version', {  get: function() {    return this.package.version;  },  enumerable: true});
 |