UNPKG

@lerna/publish

Version:

Publish packages in the current project

227 lines (225 loc) 9.01 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var import_core = require("@lerna/core"); var import_dedent = __toESM(require("dedent")); var import_fs_extra = __toESM(require("fs-extra")); var import_p_map_series = __toESM(require("p-map-series")); var import_path = __toESM(require("path")); const childProcess = require("@lerna/child-process"); module.exports = function factory(argv) { return new ImportCommand(argv); }; class ImportCommand extends import_core.Command { gitParamsForTargetCommits() { const params = ["log", "--format=%h"]; if (this.options.flatten) { params.push("--first-parent"); } return params; } initialize() { const inputPath = this.options.dir; const externalRepoPath = import_path.default.resolve(inputPath); const externalRepoBase = import_path.default.basename(externalRepoPath); this.externalExecOpts = Object.assign({}, this.execOpts, { cwd: externalRepoPath }); let stats; try { stats = import_fs_extra.default.statSync(externalRepoPath); } catch (e) { if (e.code === "ENOENT") { throw new import_core.ValidationError("ENOENT", `No repository found at "${inputPath}"`); } throw e; } if (!stats.isDirectory()) { throw new import_core.ValidationError("ENODIR", `Input path "${inputPath}" is not a directory`); } const packageJson = import_path.default.join(externalRepoPath, "package.json"); const packageName = require(packageJson).name; if (!packageName) { throw new import_core.ValidationError("ENOPKG", `No package name specified in "${packageJson}"`); } const targetBase = this.getTargetBase(); if (this.getPackageDirectories().indexOf(targetBase) === -1) { throw new import_core.ValidationError( "EDESTDIR", `--dest does not match with the package directories: ${this.getPackageDirectories()}` ); } const targetDir = import_path.default.join(targetBase, externalRepoBase); const gitRepoRoot = this.getWorkspaceRoot(); const lernaRootRelativeToGitRoot = import_path.default.relative(gitRepoRoot, this.project.rootPath); this.targetDirRelativeToGitRoot = import_path.default.join(lernaRootRelativeToGitRoot, targetDir); if (import_fs_extra.default.existsSync(import_path.default.resolve(this.project.rootPath, targetDir))) { throw new import_core.ValidationError("EEXISTS", `Target directory already exists "${targetDir}"`); } this.commits = this.externalExecSync("git", this.gitParamsForTargetCommits()).split("\n").reverse(); if (!this.commits.length) { throw new import_core.ValidationError("NOCOMMITS", `No git commits to import at "${inputPath}"`); } if (this.options.preserveCommit) { this.origGitEmail = this.execSync("git", ["config", "user.email"]); this.origGitName = this.execSync("git", ["config", "user.name"]); } this.preImportHead = this.getCurrentSHA(); if (this.execSync("git", ["diff-index", "HEAD"])) { throw new import_core.ValidationError("ECHANGES", "Local repository has un-committed changes"); } this.logger.info( "", `About to import ${this.commits.length} commits from ${inputPath} into ${targetDir}` ); if (this.options.yes) { return true; } return (0, import_core.promptConfirmation)("Are you sure you want to import these commits onto the current branch?"); } getPackageDirectories() { return this.project.packageConfigs.filter((p) => p.endsWith("*")).map((p) => import_path.default.dirname(p)); } getTargetBase() { if (this.options.dest) { return this.options.dest; } return this.getPackageDirectories().shift() || "packages"; } getCurrentSHA() { return this.execSync("git", ["rev-parse", "HEAD"]); } getWorkspaceRoot() { return this.execSync("git", ["rev-parse", "--show-toplevel"]); } execSync(cmd, args) { return childProcess.execSync(cmd, args, this.execOpts); } externalExecSync(cmd, args) { return childProcess.execSync(cmd, args, this.externalExecOpts); } createPatchForCommit(sha) { let patch = null; if (this.options.flatten) { const diff = this.externalExecSync("git", [ "log", "--reverse", "--first-parent", "-p", "-m", "--pretty=email", "--stat", "--binary", "-1", "--color=never", sha, // custom git prefixes for accurate parsing of filepaths (#1655) `--src-prefix=COMPARE_A/`, `--dst-prefix=COMPARE_B/` ]); const version = this.externalExecSync("git", ["--version"]).replace(/git version /g, ""); patch = `${diff} -- ${version}`; } else { patch = this.externalExecSync("git", [ "format-patch", "-1", sha, "--stdout", // custom git prefixes for accurate parsing of filepaths (#1655) `--src-prefix=COMPARE_A/`, `--dst-prefix=COMPARE_B/` ]); } const formattedTarget = this.targetDirRelativeToGitRoot.replace(/\\/g, "/"); const replacement = `$1/${formattedTarget}`; return patch.replace(/^([-+]{3} "?COMPARE_[AB])/gm, replacement).replace(/^(diff --git "?COMPARE_A)/gm, replacement).replace(/^(diff --git (?! "?COMPARE_B\/).+ "?COMPARE_B)/gm, replacement).replace(/^(copy (from|to)) ("?)/gm, `$1 $3${formattedTarget}/`).replace(/^(rename (from|to)) ("?)/gm, `$1 $3${formattedTarget}/`); } getGitUserFromSha(sha) { return { email: this.externalExecSync("git", ["show", "-s", "--format='%ae'", sha]), name: this.externalExecSync("git", ["show", "-s", "--format='%an'", sha]) }; } configureGitUser({ email, name }) { this.execSync("git", ["config", "user.email", `"${email}"`]); this.execSync("git", ["config", "user.name", `"${name}"`]); } execute() { this.enableProgressBar(); const tracker = this.logger.newItem("execute"); const mapper = (sha) => { tracker.info(sha); const patch = this.createPatchForCommit(sha); const procArgs = ["am", "-3", "--keep-non-patch"]; if (this.options.preserveCommit) { this.configureGitUser(this.getGitUserFromSha(sha)); procArgs.push("--committer-date-is-author-date"); } const proc = childProcess.exec("git", procArgs, this.execOpts); proc.stdin.end(patch); return (0, import_core.pulseTillDone)(proc).then(() => { tracker.completeWork(1); }).catch((err) => { const diff = this.externalExecSync("git", ["diff", "-s", `${sha}^!`]).trim(); if (diff === "") { tracker.completeWork(1); return childProcess.exec("git", ["am", "--skip"], this.execOpts); } err.sha = sha; throw err; }); }; tracker.addWork(this.commits.length); return (0, import_p_map_series.default)(this.commits, mapper).then(() => { tracker.finish(); if (this.options.preserveCommit) { this.configureGitUser({ email: this.origGitEmail, name: this.origGitName }); } this.logger.success("import", "finished"); }).catch((err) => { tracker.finish(); if (this.options.preserveCommit) { this.configureGitUser({ email: this.origGitEmail, name: this.origGitName }); } this.logger.error("import", `Rolling back to previous HEAD (commit ${this.preImportHead})`); this.execSync("git", ["am", "--abort"]); this.execSync("git", ["reset", "--hard", this.preImportHead]); throw new import_core.ValidationError( "EIMPORT", import_dedent.default` Failed to apply commit ${err.sha}. ${err.message} You may try again with --flatten to import flat history. ` ); }); } } module.exports.ImportCommand = ImportCommand;