UNPKG

@changesets/cli

Version:

Organise your package versioning and publishing to make both contributors and maintainers happy

604 lines (545 loc) 28.6 kB
"use strict"; function _interopDefault(ex) { return ex && "object" == typeof ex && "default" in ex ? ex.default : ex; } var meow = _interopDefault(require("meow")), config = require("@changesets/config"), fs = _interopDefault(require("fs-extra")), path = _interopDefault(require("path")), getWorkspaces$1 = _interopDefault(require("get-workspaces")), chalk = _interopDefault(require("chalk")), util = _interopDefault(require("util")), pkgDir = _interopDefault(require("pkg-dir")), uuid = _interopDefault(require("uuid/v1")), termSize = _interopDefault(require("term-size")), enquirer = require("enquirer"), git = require("@changesets/git"), _objectSpread = _interopDefault(require("@babel/runtime/helpers/objectSpread")), prettier = _interopDefault(require("prettier")), humanId = _interopDefault(require("human-id")), semver = _interopDefault(require("semver")), boxen = _interopDefault(require("boxen")), outdent = _interopDefault(require("outdent")), applyReleasePlan = _interopDefault(require("@changesets/apply-release-plan")), readChangesets = _interopDefault(require("@changesets/read")), getDependentsgraph = _interopDefault(require("get-dependents-graph")), assembleReleasePlan = _interopDefault(require("@changesets/assemble-release-plan")), pLimit = _interopDefault(require("p-limit")), spawn = _interopDefault(require("spawndamnit")), isCI = _interopDefault(require("is-ci")), table = _interopDefault(require("tty-table")), getReleasePlan = _interopDefault(require("@changesets/get-release-plan")); let prefix = "🦋 "; function format(args, customPrefix) { let fullPrefix = prefix + (void 0 === customPrefix ? "" : " " + customPrefix); return fullPrefix + util.format("", ...args).split("\n").join("\n" + fullPrefix + " "); } function log(...args) { console.log(format(args)); } function info(...args) { console.error(format(args, chalk.cyan("info"))); } function warn(...args) { console.error(format(args, chalk.yellow("warn"))); } function error(...args) { console.error(format(args, chalk.red("error"))); } function success(...args) { console.log(format(args, chalk.green("success"))); } var logger = { log: log, info: info, warn: warn, error: error, success: success, format: format }; async function getProjectDirectory(cwd) { const projectDir = await pkgDir(cwd); if (!projectDir) throw new Error("Could not find project directory"); return projectDir; } async function getChangesetBase(cwd) { const dir = await getProjectDirectory(cwd); return path.resolve(dir, ".changeset"); } const pkgPath = path.dirname(require.resolve("@changesets/cli/package.json")); async function init(cwd) { const changesetBase = await getChangesetBase(cwd); fs.existsSync(changesetBase) ? fs.existsSync(path.join(changesetBase, "config.json")) ? logger.warn("It looks like you already have changesets initialized. You should be able to run changeset commands no problems.") : (fs.existsSync(path.join(changesetBase, "config.js")) ? (logger.error("It looks like you're using the version 1 `.changeset/config.js` file"), logger.error("The format of the config object has significantly changed in v2 as well"), logger.error(" - we thoroughly recommend looking at the changelog for this package for what has changed"), logger.error("Changesets will write the defaults for the new config, remember to transfer your options into the new config at `.changeset/config.json`")) : (logger.error("It looks like you don't have a config file"), logger.error("The default config file will be written at `.changeset/config.json`")), await fs.writeFile(path.resolve(changesetBase, "config.json"), JSON.stringify(config.defaultWrittenConfig, null, 2))) : (await fs.copy(path.resolve(pkgPath, "./default-files"), changesetBase), await fs.writeFile(path.resolve(changesetBase, "config.json"), JSON.stringify(config.defaultWrittenConfig, null, 2)), logger.log(chalk`Thanks for choosing {green changesets} to help manage your versioning and publishing\n`), logger.log("You should be set up to start using changesets now!\n"), logger.info("We have added a `.changeset` folder, and a couple of files to help you out:"), logger.info(chalk`- {blue .changeset/README.md} contains information about using changesets`), logger.info(chalk`- {blue .changeset/config.json} is our default config`)); } const limit = Math.max(termSize().rows - 5, 10); let cancelFlow = () => { logger.success("Cancelled... 👋 "), process.exit(); }; async function askCheckboxPlus(message, choices, format) { const name = `CheckboxPlus-${uuid()}`; return enquirer.prompt({ type: "autocomplete", name: name, message: message, prefix: prefix, multiple: !0, choices: choices, format: format, limit: limit, onCancel: cancelFlow }).then(responses => responses[name]).catch(err => { logger.error(err); }); } async function askQuestion(message) { const name = `Question-${uuid()}`; return enquirer.prompt([ { type: "input", message: message, name: name, prefix: prefix, onCancel: cancelFlow } ]).then(responses => responses[name]).catch(err => { logger.error(err); }); } async function askConfirm(message) { const name = `Confirm-${uuid()}`; return enquirer.prompt([ { message: message, name: name, prefix: prefix, type: "confirm", initial: !0, onCancel: cancelFlow } ]).then(responses => responses[name]).catch(err => { logger.error(err); }); } async function writeChangeset(changeset, cwd) { const {summary: summary, releases: releases} = changeset, changesetBase = await getChangesetBase(cwd), changesetID = humanId({ separator: "-", capitalize: !1 }), prettierConfig = await prettier.resolveConfig(cwd), newChangesetPath = path.resolve(changesetBase, `${changesetID}.md`), changesetContents = `---\n${releases.map(release => `"${release.name}": ${release.type}`).join("\n")}\n---\n\n${summary}\n `; return await fs.writeFile(newChangesetPath, prettier.format(changesetContents, _objectSpread({}, prettierConfig, { parser: "markdown" }))), changesetID; } async function getWorkspaces(opts) { let workspaces = await getWorkspaces$1(_objectSpread({ tools: [ "yarn", "bolt", "root" ] }, opts)); return null === workspaces ? [] : workspaces; } const {green: green, yellow: yellow, red: red, bold: bold, blue: blue, cyan: cyan} = chalk; async function getPackagesToRelease(changedPackages, allPackages) { function askInitialReleaseQuestion(defaultChoiceList) { return askCheckboxPlus("Which packages would you like to include?", defaultChoiceList, x => Array.isArray(x) ? x.filter(x => "changed packages" !== x && "unchanged packages" !== x).map(x => cyan(x)).join(", ") : x); } if (allPackages.length > 1) { const unchangedPackagesNames = allPackages.map(({name: name}) => name).filter(name => !changedPackages.includes(name)), defaultChoiceList = [ { name: "changed packages", choices: changedPackages }, { name: "unchanged packages", choices: unchangedPackagesNames } ].filter(({choices: choices}) => 0 !== choices.length); let packagesToRelease = await askInitialReleaseQuestion(defaultChoiceList); if (0 === packagesToRelease.length) do { logger.error("You must select at least one package to release"), logger.error("(You most likely hit enter instead of space!)"), packagesToRelease = await askInitialReleaseQuestion(defaultChoiceList); } while (0 === packagesToRelease.length); return packagesToRelease.filter(pkgName => "changed packages" !== pkgName && "unchanged packages" !== pkgName); } return [ allPackages[0].name ]; } function formatPkgNameAndVersion(pkgName, version) { return `${bold(pkgName)}@${bold(version)}`; } async function createChangeset(changedPackages, cwd) { const allPackages = await getWorkspaces({ cwd: cwd }), packagesToRelease = await getPackagesToRelease(changedPackages, allPackages); let pkgJsonsByName = new Map(allPackages.map(({name: name, config: config}) => [ name, config ])); const releases = []; let pkgsLeftToGetBumpTypeFor = new Set(packagesToRelease), pkgsThatShouldBeMajorBumped = await askCheckboxPlus(bold(`Which packages should have a ${red("major")} bump?`), packagesToRelease.map(pkgName => ({ name: pkgName, message: formatPkgNameAndVersion(pkgName, pkgJsonsByName.get(pkgName).version) }))); for (const pkgName of pkgsThatShouldBeMajorBumped) { let {version: version} = pkgJsonsByName.get(pkgName); if (semver.lt(version, "1.0.0")) { if (logger.log(yellow(`WARNING: Releasing a major version for ${green(pkgName)} will be its ${red("first major release")}.`)), logger.log(yellow(`If you are unsure if this is correct, contact the package's maintainers$ ${red("before committing this changeset")}.`)), !await askConfirm(bold(`Are you sure you want still want to release the ${red("first major release")} of ${pkgName}?`))) continue; } pkgsLeftToGetBumpTypeFor.delete(pkgName), releases.push({ name: pkgName, type: "major" }); } if (0 !== pkgsLeftToGetBumpTypeFor.size) { let pkgsThatShouldBeMinorBumped = await askCheckboxPlus(bold(`Which packages should have a ${green("minor")} bump?`), [ ...pkgsLeftToGetBumpTypeFor ].map(pkgName => ({ name: pkgName, message: formatPkgNameAndVersion(pkgName, pkgJsonsByName.get(pkgName).version) }))); for (const pkgName of pkgsThatShouldBeMinorBumped) pkgsLeftToGetBumpTypeFor.delete(pkgName), releases.push({ name: pkgName, type: "minor" }); } if (0 !== pkgsLeftToGetBumpTypeFor.size) { logger.log(`The following packages will be ${blue("patch")} bumped:`), pkgsLeftToGetBumpTypeFor.forEach(pkgName => { logger.log(formatPkgNameAndVersion(pkgName, pkgJsonsByName.get(pkgName).version)); }); for (const pkgName of pkgsLeftToGetBumpTypeFor) releases.push({ name: pkgName, type: "patch" }); } logger.log("Please enter a summary for this change (this will be in the changelogs)"); let summary = await askQuestion("Summary"); for (;0 === summary.length; ) logger.error("A summary is required for the changelog! 😪"), summary = await askQuestion("Summary"); return { summary: summary, releases: releases }; } function printConfirmationMessage(changeset) { function getReleasesOfType(type) { return changeset.releases.filter(release => release.type === type).map(release => release.name); } logger.log("=== Releasing the following packages ==="); const majorReleases = getReleasesOfType("major"), minorReleases = getReleasesOfType("minor"), patchReleases = getReleasesOfType("patch"); majorReleases.length > 0 && logger.log(`${chalk.green("[Major]")}\n ${majorReleases.join(", ")}`), minorReleases.length > 0 && logger.log(`${chalk.green("[Minor]")}\n ${minorReleases.join(", ")}`), patchReleases.length > 0 && logger.log(`${chalk.green("[Patch]")}\n ${patchReleases.join(", ")}`); const message = outdent` ${chalk.red("========= NOTE ========")} All dependents of these packages that will be incompatible with the new version will be ${chalk.red("patch bumped")} when this changeset is applied.`, prettyMessage = boxen(message, { borderStyle: "double", align: "center" }); logger.log(prettyMessage); } async function add(cwd, config) { const changesetBase = await getChangesetBase(cwd); if (!fs.existsSync(changesetBase)) return logger.warn("There is no .changeset folder. "), logger.warn("If this is the first time `changesets` have been used in this project, run `yarn changesets init` to get set up."), void logger.warn("If you expected there to be changesets, you should check git history for when the folder was removed to ensure you do not lose any configuration."); const changePackagesName = (await git.getChangedPackagesSinceMaster(cwd)).filter(a => a).map(pkg => pkg.name), newChangeset = await createChangeset(changePackagesName, cwd); if (printConfirmationMessage(newChangeset), await askConfirm("Is this your desired changeset?")) { const changesetID = await writeChangeset(newChangeset, cwd); config.commit ? (await git.add(path.resolve(changesetBase, `${changesetID}.md`), cwd), await git.commit(`CHANGESET: ${changesetID}. ${newChangeset.summary}`, cwd), logger.log(chalk.green("Changeset added and committed"))) : logger.log(chalk.green("Changeset added! - you can now commit it\n")), [ ...newChangeset.releases ].find(c => "major" === c.type) ? (logger.warn("This Changeset includes a major change and we STRONGLY recommend adding more information to the changeset:"), logger.warn("WHAT the breaking change is"), logger.warn("WHY the change was made"), logger.warn("HOW a consumer should update their code")) : logger.log(chalk.green("If you want to modify or expand on the changeset summary, you can find it here")), logger.info(chalk.blue(path.resolve(changesetBase, `${changesetID}.md`))); } } const removeEmptyFolders = folderPath => { fs.readdirSync(folderPath).forEach(contentPath => { const singleChangesetPath = path.resolve(folderPath, contentPath); fs.statSync(singleChangesetPath).isDirectory() && fs.readdirSync(singleChangesetPath).length < 1 && fs.rmdirSync(singleChangesetPath); }); }, removeFolders = folderPath => { if (!fs.existsSync(folderPath)) return; fs.readdirSync(folderPath).forEach(contentPath => { const singleChangesetPath = path.resolve(folderPath, contentPath); fs.statSync(singleChangesetPath).isDirectory() && (fs.emptyDirSync(singleChangesetPath), fs.rmdirSync(singleChangesetPath)); }); }; async function getChangesets(changesetBase, sinceMasterOnly) { if (!fs.existsSync(changesetBase)) throw new Error("There is no .changeset directory in this project"); let changesets = fs.readdirSync(changesetBase).filter(dir => fs.lstatSync(path.join(changesetBase, dir)).isDirectory()); if (sinceMasterOnly) { const newHahses = (await git.getChangedChangesetFilesSinceMaster(changesetBase)).map(c => c.split("/")[1]); changesets = changesets.filter(dir => newHahses.includes(dir)); } const changesetContents = changesets.map(async changesetDir => { const summary = fs.readFileSync(path.join(changesetBase, changesetDir, "changes.md"), "utf-8"), jsonPath = path.join(changesetBase, changesetDir, "changes.json"), json = require(jsonPath), commit = await git.getCommitThatAddsFile(jsonPath, changesetBase); return _objectSpread({}, json, { summary: summary, commit: commit, id: changesetDir }); }); return Promise.all(changesetContents); } let importantSeparator = chalk.red("===============================IMPORTANT!==============================="); async function getOldChangesetsAndWarn(cwd) { let changesetBase = await getChangesetBase(cwd); removeEmptyFolders(changesetBase); let unreleasedChangesets = await getChangesets(changesetBase, !1); return 0 === unreleasedChangesets.length ? [] : (logger.warn(importantSeparator), logger.warn("There were old changesets from version 1 found"), logger.warn("Theses are being applied now but the dependents graph may have changed"), logger.warn("Make sure you validate all your dependencies"), logger.warn("In a future version, we will no longer apply these old changesets, and will instead throw here"), logger.warn("----------------------------------------------------------------------"), unreleasedChangesets.map(({releases: releases, id: id, summary: summary}) => ({ releases: releases, id: id, summary: summary }))); } async function cleanupOldChangesets(cwd, config) { let changesetBase = await getChangesetBase(cwd); removeFolders(changesetBase), config.commit && (await git.add(changesetBase, cwd), logger.log("Committing removing old changesets..."), await git.commit("removing legacy changesets", cwd)); } async function version(cwd, config) { let oldChangesets = await getOldChangesetsAndWarn(cwd), newChangesets = await readChangesets(cwd, !1), changesets = [ ...oldChangesets, ...newChangesets ]; if (0 === changesets.length) return void logger.warn("No unreleased changesets found, exiting."); let workspaces = await getWorkspaces$1({ cwd: cwd, tools: [ "yarn", "bolt", "root" ] }); if (!workspaces) throw new Error("Could not resolve workspaes for current working directory"); let dependentsGraph = await getDependentsgraph({ cwd: cwd }), releasePlan = await assembleReleasePlan(changesets, workspaces, dependentsGraph, config); await applyReleasePlan(releasePlan, cwd, config), oldChangesets.length > 0 && await cleanupOldChangesets(cwd, config), config.commit ? logger.log("All files have been updated and committed. You're ready to publish!") : logger.log("All files have been updated. Review them and commit at your leisure"), logger.warn("If you alter version changes in package.jsons, make sure to run bolt before publishing to ensure the repo is in a valid state"); } class ExitError extends Error { constructor(code) { super("the process exited with code: " + code), this.code = code; } } const npmRequestLimit = pLimit(40); function getCorrectRegistry() { return "https://registry.yarnpkg.com" === process.env.npm_config_registry ? void 0 : process.env.npm_config_registry; } async function getTokenIsRequired() { const envOverride = { npm_config_registry: getCorrectRegistry() }; let result = await spawn("npm", [ "profile", "get", "--json" ], { env: Object.assign({}, process.env, envOverride) }), json = JSON.parse(result.stdout.toString()); if (json.error) throw logger.error(`an error occurred while running \`npm profile get\`: ${json.error.code}`), logger.error(json.error.summary), json.error.summary && logger.error(json.error.summary), new ExitError(1); return "auth-and-writes" === json.tfa.mode; } function info$1(pkgName) { return npmRequestLimit(async () => { logger.info(`npm info ${pkgName}`); const envOverride = { npm_config_registry: getCorrectRegistry() }; let result = await spawn("npm", [ "info", pkgName, "--json" ], { env: Object.assign({}, process.env, envOverride) }); return JSON.parse(result.stdout.toString()); }); } async function infoAllow404(pkgName) { let pkgInfo = await info$1(pkgName); if (pkgInfo.error && "E404" === pkgInfo.error.code) return logger.warn(`Recieved 404 for npm info ${chalk.cyan(`"${pkgName}"`)}`), { published: !1, pkgInfo: {} }; if (pkgInfo.error) throw logger.error(`Recieved an unknown error code: ${pkgInfo.error.code} for npm info ${chalk.cyan(`"${pkgName}"`)}`), logger.error(pkgInfo.error.summary), pkgInfo.error.detail && logger.error(pkgInfo.error.detail), new ExitError(1); return { published: !0, pkgInfo: pkgInfo }; } let otpAskLimit = pLimit(1), askForOtpCode = twoFactorState => otpAskLimit(async () => { if (null !== twoFactorState.token) return twoFactorState.token; logger.info("This operation requires a one-time password from your authenticator."); let val = await askQuestion("Enter one-time password:"); return twoFactorState.token = val, val; }), getOtpCode = async twoFactorState => null !== twoFactorState.token ? twoFactorState.token : askForOtpCode(twoFactorState); async function internalPublish(pkgName, opts, twoFactorState) { let publishFlags = opts.access ? [ "--access", opts.access ] : []; if (await twoFactorState.isRequired && !isCI) { let otpCode = await getOtpCode(twoFactorState); publishFlags.push("--otp", otpCode); } const envOverride = { npm_config_registry: getCorrectRegistry() }; let {stdout: stdout} = await spawn("npm", [ "publish", "--json", ...publishFlags ], { cwd: opts.cwd, env: Object.assign({}, process.env, envOverride) }), json = JSON.parse(stdout.toString()); return json.error ? "EOTP" !== json.error.code || isCI ? (logger.error(`an error occurred while publishing ${pkgName}: ${json.error.code}`, json.error.summary, json.error.detail ? "\n" + json.error.detail : ""), { published: !1 }) : (null !== twoFactorState.token && (twoFactorState.token = null), twoFactorState.isRequired = Promise.resolve(!0), internalPublish(pkgName, opts, twoFactorState)) : { published: !0 }; } function publish(pkgName, opts, twoFactorState) { return npmRequestLimit(() => internalPublish(pkgName, opts, twoFactorState)); } async function publishPackages({cwd: cwd, access: access, otp: otp}) { const publicPackages = (await getWorkspaces({ cwd: cwd })).filter(pkg => !pkg.config.private); let twoFactorState = void 0 === otp ? { token: null, isRequired: getTokenIsRequired() } : { token: otp, isRequired: Promise.resolve(!0) }; const unpublishedPackagesInfo = await getUnpublishedPackages(publicPackages), unpublishedPackages = publicPackages.filter(pkg => unpublishedPackagesInfo.some(p => pkg.name === p.name)); return 0 === unpublishedPackagesInfo.length && logger.warn("No unpublished packages to publish"), await Promise.all(unpublishedPackages.map(pkg => publishAPackage(pkg, access, twoFactorState))); } async function publishAPackage(pkg, access, twoFactorState) { const {name: name, version: version} = pkg.config; logger.info(`Publishing ${chalk.cyan(`"${name}"`)} at ${chalk.green(`"${version}"`)}`); const publishDir = pkg.dir; return { name: name, newVersion: version, published: (await publish(name, { cwd: publishDir, access: access }, twoFactorState)).published }; } async function getUnpublishedPackages(packages) { const results = await Promise.all(packages.map(async pkg => { const config = pkg.config, response = await infoAllow404(config.name); return { name: config.name, localVersion: config.version, isPublished: response.published, publishedVersion: response.pkgInfo.version || "" }; })), packagesToPublish = []; for (const pkgInfo of results) { const {name: name, isPublished: isPublished, localVersion: localVersion, publishedVersion: publishedVersion} = pkgInfo; isPublished ? semver.gt(localVersion, publishedVersion) ? (packagesToPublish.push(pkgInfo), logger.info(`${name} is being published because our local version (${localVersion}) is ahead of npm's (${publishedVersion})`)) : semver.lt(localVersion, publishedVersion) && logger.warn(`${name} is not being published because version ${publishedVersion} is already published on npm and we are trying to publish version ${localVersion}`) : packagesToPublish.push(pkgInfo); } return packagesToPublish; } function logReleases(pkgs) { const mappedPkgs = pkgs.map(p => `${p.name}@${p.newVersion}`).join("\n"); logger.log(mappedPkgs); } async function run(cwd, {otp: otp}, config) { const response = await publishPackages({ cwd: cwd, access: config.access, otp: otp }), successful = response.filter(p => p.published), unsuccessful = response.filter(p => !p.published); if (successful.length > 0) { logger.success("packages published successfully:"), logReleases(successful), logger.log("Creating tags..."); for (const pkg of successful) { const tag = `${pkg.name}@${pkg.newVersion}`; logger.log("New tag: ", tag), await git.tag(tag, cwd); } } if (unsuccessful.length > 0) throw logger.error("packages failed to publish:"), logReleases(unsuccessful), new ExitError(1); } async function getStatus(cwd, {sinceMaster: sinceMaster, verbose: verbose, output: output}, config) { const releasePlan = await getReleasePlan(cwd, sinceMaster, config), {changesets: changesets, releases: releases} = releasePlan; if (changesets.length < 1 && (logger.error("No changesets present"), process.exit(1)), output) return void await fs.writeFile(path.join(cwd, output), JSON.stringify(releasePlan, void 0, 2)); const print = verbose ? verbosePrint : SimplePrint; return print("patch", releases), logger.log("---"), print("minor", releases), logger.log("---"), print("major", releases), releasePlan; } function SimplePrint(type, releases) { const packages = releases.filter(r => r.type === type); if (packages.length) { logger.info(chalk`Packages to be bumped at {green ${type}}:\n`); const pkgs = packages.map(({name: name}) => `- ${name}`).join("\n"); logger.log(chalk.green(pkgs)); } else logger.info(chalk`{red NO} packages to be bumped at {green ${type}}`); } function verbosePrint(type, releases) { const packages = releases.filter(r => r.type === type); if (packages.length) { logger.info(chalk`Packages to be bumped at {green ${type}}`); const columns = packages.map(({name: name, newVersion: version, changesets: changesets}) => [ chalk.green(name), version, changesets.map(c => chalk.blue(` .changeset/${c}/changes.md`)).join(" +") ]), t1 = table([ { value: "Package Name", width: 20 }, { value: "New Version", width: 20 }, { value: "Related Changeset Summaries", width: 70 } ], columns, { paddingLeft: 1, paddingRight: 0, headerAlign: "center", align: "left" }); logger.log(t1.render() + "\n"); } else logger.info(chalk`Running release would release {red NO} packages as a {green ${type}}`); } const {input: input, flags: flags} = meow("\n Usage\n $ changesets [command]\n Commands\n init\n add\n version\n publish [--otp=code]\n status [--since-master --verbose --output=JSON_FILE.json]\n ", { flags: { sinceMaster: { type: "boolean" }, verbose: { type: "boolean", alias: "v" }, output: { type: "string", alias: "o" }, otp: { type: "string", default: void 0 } } }), cwd = process.cwd(); (async () => { const workspaces = await getWorkspaces$1({ cwd: cwd, tools: [ "yarn", "bolt", "root" ] }); if (!workspaces) throw new Error("We could not resolve workspaces - check you are running this command from the correct directory"); if ("init" === input[0]) return void await init(cwd); let config$1; try { config$1 = await config.read(cwd, workspaces); } catch (e) { if (!await fs.pathExists(path.resolve(cwd, ".changeset/config.js"))) throw e; logger.error("It looks like you're using the version 1 `.changeset/config.js` file"), logger.error("You'll need to convert it to a `.changeset/config.json` file"), logger.error("The format of the config object has significantly changed in v2 as well"), logger.error(" - we thoroughly recommend looking at the changelog for this package for what has changed"), process.exit(1); } if (input.length < 1) await add(cwd, config$1); else if (input.length > 1) logger.error("Too many arguments passed to changesets - we only accept the command name as an argument"); else { const {sinceMaster: sinceMaster, verbose: verbose, output: output, otp: otp} = flags; switch ([ "updateChangelog", "isPublic", "skipCI", "commit" ].forEach(flag => { if (flags[flag]) throw logger.error(`the flag ${flag} has been removed from changesets for version 2`), logger.error("Please encode the desired value into your config"), logger.error("See our changelog for more details"), new ExitError(1); }), input[0]) { case "add": return void await add(cwd, config$1); case "version": return void await version(cwd, config$1); case "publish": return void await run(cwd, { otp: otp }, config$1); case "status": return void await getStatus(cwd, { sinceMaster: sinceMaster, verbose: verbose, output: output }, config$1); case "bump": throw logger.error('In version 2 of changesets, "bump" has been renamed to "version" - see our changelog for an explanation'), logger.error("To fix this, use `changeset version` instead, and update any scripts that use changesets"), new ExitError(1); case "release": throw logger.error('In version 2 of changesets, "release" has been renamed to "publish" - see our changelog for an explanation'), logger.error("To fix this, use `changeset publish` instead, and update any scripts that use changesets"), new ExitError(1); default: throw logger.error(`Invalid command ${input[0]} was provided`), new ExitError(1); } } })().catch(err => { if (err instanceof ExitError) return process.exit(err.code); logger.error(err), process.exit(1); });