123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- "use strict";
- const log = require("npmlog");
- const runScript = require("npm-lifecycle");
- const npmConf = require("@lerna/npm-conf");
- module.exports.runLifecycle = runLifecycle;
- module.exports.createRunner = createRunner;
- /**
- * @typedef {object} LifecycleConfig
- * @property {typeof log} [log]
- * @property {boolean} [ignorePrepublish]
- * @property {boolean} [ignoreScripts]
- * @property {string} [nodeOptions]
- * @property {string} [scriptShell]
- * @property {boolean} [scriptsPrependNodePath]
- * @property {boolean} [unsafePerm=true]
- */
- /**
- * Alias dash-cased npmConf to camelCase
- * @param {LifecycleConfig} obj
- * @returns {LifecycleConfig}
- */
- function flattenOptions(obj) {
- return {
- ignorePrepublish: obj["ignore-prepublish"],
- ignoreScripts: obj["ignore-scripts"],
- nodeOptions: obj["node-options"],
- scriptShell: obj["script-shell"],
- scriptsPrependNodePath: obj["scripts-prepend-node-path"],
- unsafePerm: obj["unsafe-perm"],
- ...obj,
- };
- }
- /**
- * Run a lifecycle script for a package.
- * @param {import("@lerna/package").Package} pkg
- * @param {string} stage
- * @param {LifecycleConfig} options
- */
- function runLifecycle(pkg, stage, options) {
- // back-compat for @lerna/npm-conf instances
- // https://github.com/isaacs/proto-list/blob/27764cd/proto-list.js#L14
- if ("root" in options) {
- // eslint-disable-next-line no-param-reassign
- options = options.snapshot;
- }
- const opts = {
- log,
- unsafePerm: true,
- ...flattenOptions(options),
- };
- const dir = pkg.location;
- const config = {};
- if (opts.ignoreScripts) {
- opts.log.verbose("lifecycle", "%j ignored in %j", stage, pkg.name);
- return Promise.resolve();
- }
- if (!pkg.scripts || !pkg.scripts[stage]) {
- opts.log.silly("lifecycle", "No script for %j in %j, continuing", stage, pkg.name);
- return Promise.resolve();
- }
- if (stage === "prepublish" && opts.ignorePrepublish) {
- opts.log.verbose("lifecycle", "%j ignored in %j", stage, pkg.name);
- return Promise.resolve();
- }
- // https://github.com/zkat/figgy-pudding/blob/7d68bd3/index.js#L42-L64
- for (const [key, val] of Object.entries(opts)) {
- // omit falsy values and circular objects
- if (val != null && key !== "log" && key !== "logstream") {
- config[key] = val;
- }
- }
- /* istanbul ignore else */
- // eslint-disable-next-line no-underscore-dangle
- if (pkg.__isLernaPackage) {
- // To ensure npm-lifecycle creates the correct npm_package_* env vars,
- // we must pass the _actual_ JSON instead of our fancy Package thingy
- // eslint-disable-next-line no-param-reassign
- pkg = pkg.toJSON();
- }
- // TODO: remove pkg._id when npm-lifecycle no longer relies on it
- pkg._id = `${pkg.name}@${pkg.version}`; // eslint-disable-line
- opts.log.silly("lifecycle", "%j starting in %j", stage, pkg.name);
- return runScript(pkg, stage, dir, {
- config,
- dir,
- failOk: false,
- log: opts.log,
- // bring along camelCased aliases
- nodeOptions: opts.nodeOptions,
- scriptShell: opts.scriptShell,
- scriptsPrependNodePath: opts.scriptsPrependNodePath,
- unsafePerm: opts.unsafePerm,
- }).then(
- () => {
- opts.log.silly("lifecycle", "%j finished in %j", stage, pkg.name);
- },
- (err) => {
- // propagate the exit code
- const exitCode = err.errno || 1;
- // error logging has already occurred on stderr, but we need to stop the chain
- log.error("lifecycle", "%j errored in %j, exiting %d", stage, pkg.name, exitCode);
- // ensure clean logging, avoiding spurious log dump
- err.name = "ValidationError";
- // our yargs.fail() handler expects a numeric .exitCode, not .errno
- err.exitCode = exitCode;
- process.exitCode = exitCode;
- // stop the chain
- throw err;
- }
- );
- }
- function createRunner(commandOptions) {
- const cfg = npmConf(commandOptions).snapshot;
- return (pkg, stage) => runLifecycle(pkg, stage, cfg);
- }
|