UNPKG

beesbuild

Version:

构建工具链

412 lines (411 loc) 13.6 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import path from "path"; import logger from "logsets"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import input from "@inquirer/input"; import confirm from "@inquirer/confirm"; import select, { Separator } from "@inquirer/select"; import { consola, getPackageManifest, git, incNextVersion, isValidPreRelease, parseVersion, versionTransformer } from "@beesbuild/utils"; import semver from "semver"; import { ALL_RELEASE_TYPES, CONTINUATION_TYPES, PRERELEASE_TYPES, PRE_RELEASE_TYPES, RELEASE_TYPES } from "../../variables.mjs"; dayjs.extend(relativeTime); const CHOICES = { latestIsPreRelease: [...RELEASE_TYPES, CONTINUATION_TYPES[0]], preRelease: PRERELEASE_TYPES, default: [...RELEASE_TYPES, ...PRERELEASE_TYPES] }; const PRE_RELEASE_ID = "beta"; const defsContextOptions = () => { return { rootDir: process.cwd(), logs: [], debug: false, excludes: [], report: "versions.md", changeLogs: "changeLogs", increment: "patch", preReleaseId: "", isPreRelease: false, silent: true, includeDescendants: false, distTag: [], test: false, force: false }; }; class Context { constructor(options) { __publicField(this, "options", defsContextOptions()); var _a, _b; const rootDir = this.options.rootDir = (_a = options.rootDir) != null ? _a : process.cwd(); const workspace = this.options.workspace = getPackageManifest(path.resolve(rootDir, ".", "package.json")); const defs = defsContextOptions(); const context = { ...defs, rootDir, ...(_b = workspace == null ? void 0 : workspace.publishConfig) != null ? _b : {}, ...options }; Object.entries(context).forEach(([key]) => { var _a2; switch (true) { case key === "preReleaseId": if (!(context == null ? void 0 : context.preReleaseId) || !PRE_RELEASE_TYPES.includes(context == null ? void 0 : context.preReleaseId)) { this.options.preReleaseId = ""; } else { this.options.preReleaseId = context == null ? void 0 : context.preReleaseId; } return; case key === "increment": if (!(context == null ? void 0 : context.increment) || (context == null ? void 0 : context.increment) === "none") { this.options.increment = ""; } else { this.options.increment = context == null ? void 0 : context.increment; } return; default: } this.options[key] = (_a2 = context[key]) != null ? _a2 : defs[key]; }); } shortDate(time, format = "MM/DD hh:mm:ss") { return dayjs(time).format(format); } relativeTime(time) { return dayjs(time).fromNow(); } log(info) { this.options.logs.push(info); } /** * 切换到发布分支 */ async switchToReleaseBranch(options) { const releaseBranch = this.options.releaseBranch; let currentBranch; let isCheckout = false; try { currentBranch = git.getCurrentBranch(); logger.log("- \u5F53\u524D\u5206\u652F: {}", currentBranch); logger.log("- \u53D1\u5E03\u5206\u652F: {}", releaseBranch || currentBranch); if (releaseBranch && releaseBranch !== currentBranch) { logger.log("- \u5207\u6362\u5230\u53D1\u5E03\u5206\u652F: {}", releaseBranch); await git.checkoutBranch(releaseBranch); isCheckout = true; } } catch (e) { this.log(`ERROR: ${e == null ? void 0 : e.stack}`); throw e; } finally { if (isCheckout) { this.options.oldBranch = currentBranch; } } } /** * */ packagesFilter(options) { var _a; let packages = this.options.packages; const excludes = this.options.excludes; if (!packages || (packages == null ? void 0 : packages.length) === 0) return []; packages = packages.filter( (value) => !excludes.includes(value == null ? void 0 : value.name) || (value == null ? void 0 : value.private) === true ); for (let i = 0; i < packages.length; i++) { const pkgInfo1 = packages[i]; const dependencies1 = Object.keys((_a = pkgInfo1 == null ? void 0 : pkgInfo1.dependencies) != null ? _a : {}); if (dependencies1.length === 0) continue; for (let j = i; j < packages.length; j++) { const pkgInfo2 = packages[j]; if (dependencies1.includes(pkgInfo2.name)) { const p = packages[i]; packages[i] = packages[j]; packages[j] = p; } } } return packages; } getReleaseTypes({ increment, latestIsPreRelease, isPreRelease } = {}) { if (increment && ALL_RELEASE_TYPES.includes(increment)) { return [increment]; } return latestIsPreRelease ? CHOICES.latestIsPreRelease : isPreRelease ? CHOICES.preRelease : CHOICES.default; } get releaseConfig() { let increment = this.options.increment; const preReleaseId = this.options.preReleaseId; let isPreRelease = false; let latestIsPreRelease = false; switch (true) { case CHOICES.preRelease.includes(increment): case CONTINUATION_TYPES.includes(increment): isPreRelease = true; latestIsPreRelease = true; if (increment === "pre") { increment = ""; } break; case !CHOICES.default.includes(increment): increment = ""; break; } return { increment, latestIsPreRelease, isPreRelease, preReleaseId: typeof preReleaseId === "string" ? preReleaseId : PRE_RELEASE_ID }; } get isPreRelease() { return this.releaseConfig.isPreRelease; } get packages() { return this.packagesFilter(); } getPackageChoices(options) { return this.packages.reduce((prev = [], value) => { const { isPreRelease, preReleaseId: _preReleaseId, version } = parseVersion(value.version); if (!version) return prev; let latestIsPreRelease = false; if (typeof value.version === "string") { latestIsPreRelease = isValidPreRelease(version); } const types = this.getReleaseTypes({ latestIsPreRelease, isPreRelease }); const choices = types.map((increment) => { const preReleaseId = !RELEASE_TYPES.includes(increment) ? _preReleaseId != null ? _preReleaseId : this.releaseConfig.preReleaseId : ""; const nextVersion = incNextVersion(version, increment, preReleaseId); return { name: `${increment} (${value.name}@${nextVersion})`, value: [increment, value.name, nextVersion], increment, latestVersion: version, nextVersion, pkgName: value.name, pkg: value }; }); return prev.concat(choices); }, []); } async confirmRelease(choice) { const answer = await confirm({ message: `\u786E\u8BA4\u662F\u5426\u7ACB\u5373\u53D1\u5E03 ${choice.name}?` }); if (answer === true) return choice.value; return answer; } async selectIncrement(choices, one = false) { if (one === false) { const otherChoice = { name: "\u6309\u6B65\u9AA4\u6267\u884C\u53D1\u5E03\uFF1F", value: null }; choices = [ otherChoice, new Separator("-- \u5206\u5272\u7EBF - start --"), ...choices, new Separator("-- \u5206\u5272\u7EBF - end --") ]; } else { const otherChoice = { name: "\u5176\u4ED6\uFF0C\u8BF7\u6307\u5B9A\u7248\u672C...", value: null }; choices = [...choices, otherChoice]; } const answer = await select({ message: `\u9009\u62E9\u589E\u91CF\uFF08\u4E0B\u4E00\u4E2A\u7248\u672C\uFF09\uFF1A`, choices, pageSize: 9 }); if (answer === null && one !== false) { const latestVersion = choices[0].latestVersion; const nextVersion = choices[0].nextVersion; const value = ["customize", choices[0].pkgName]; const transformer = versionTransformer(latestVersion); const answer2 = await input({ message: "\u8BF7\u8F93\u5165\u6709\u6548\u7248\u672C\uFF1A", default: nextVersion, transformer, validate(input2) { return !!semver.valid(input2) || "\u7248\u672C\u5FC5\u987B\u7B26\u5408 semver \u6807\u51C6\u3002"; } }); if (!answer2) return []; return value.concat(answer2); } return answer; } async promptListRelease(prompts) { const answers = []; const prompt = { select: (message, choices) => select({ message, choices, pageSize: 9 }), confirm: (message, choices) => confirm({ message }) }; for (let { type, message, choices, transformerValue } of prompts) { if (typeof message === "function") { message = await message(answers); } let answer = await prompt[type](message, choices); if (typeof transformerValue === "function") { answer = await transformerValue(answer, answers); } if (!answer) break; answers.push(answer); } return answers; } /** * 向用户询问要发布哪些包 * @returns {selectedPackages,distTag,increment } */ async askForPublishPackages(options) { let packageChoices = this.getPackageChoices(options); const { increment, isPreRelease, preReleaseId } = this.releaseConfig; if (packageChoices.length === 0) return {}; consola.log(packageChoices.length, "packageChoices"); const packages = packageChoices.reduce((prev, value) => { if (!prev.some((choice) => choice.name === value.pkgName)) { prev.push(value.pkg); } return prev; }, []); if (increment) { packageChoices = packageChoices.filter((value) => value.increment === increment); } if (packageChoices.length === 1) { const answer2 = await this.confirmRelease(packageChoices[0]); return answer2; } if (packages.length === 1 && packageChoices.length > 0) { const answer2 = await this.selectIncrement(packageChoices, true); return answer2; } const types = this.getReleaseTypes({ increment, isPreRelease }); let choices = types.map((increment2) => { const { version } = parseVersion("0.0.0"); const filter = typeof (options == null ? void 0 : options.filter) === "string" ? `\u3010${options == null ? void 0 : options.filter}\u3011` : ""; const nextVersion = incNextVersion(version != null ? version : "", increment2, preReleaseId != null ? preReleaseId : ""); return { name: `${increment2} +(${nextVersion == null ? void 0 : nextVersion.replace(/0/gi, "*")})`, value: [increment2], description: `\u53D1\u5E03${filter != null ? filter : ""} \u5168\u91CF\u5305 ${increment2} \u7248\u672C`, increment: increment2 }; }); if (increment) { choices = choices.filter((value) => value.increment === increment); } const typesChoices = choices; if (choices.length === 1) { const increment2 = choices[0].increment; choices = packageChoices.filter((value) => value.increment === increment2); } else { const d = new Separator("-- \u4EE5\u4E0B\u9009\u62E9\u72EC\u7ACB\u5305\u7248\u672C\u53D1\u5E03 --"); choices = choices.concat(d).concat(packageChoices); } if (choices.length === 1) { return this.confirmRelease(packageChoices[0]); } const answer = await this.selectIncrement(choices); if (answer === null) { const prompts = [ { type: "select", key: "increment", message: `\u9009\u62E9\u589E\u91CF\u65B9\u5F0F\uFF1A${CHOICES.default.join("\u3001")}`, choices: typesChoices.map((value) => { return { name: value.increment, value: value.increment }; }) }, { type: "select", key: "name", message: `\u9009\u62E9\u9700\u8981\u53D1\u5E03\u7684\u5305\uFF1A`, choices: packages.map((value) => { return { name: value.name, value: value.name }; }) }, { type: "confirm", message: (answer2) => `\u786E\u8BA4\u662F\u5426\u7ACB\u5373\u53D1\u5E03 ${answer2[1]}?`, transformerValue: (answer2, answers) => { const [increment2, name] = answers; if (answer2 === true) { const choice = packageChoices.find( (value) => value.increment === increment2 && name === value.pkgName ); return choice && (choice == null ? void 0 : choice.latestVersion) ? choice.latestVersion : false; } return false; } } ]; return this.promptListRelease(prompts); } } /** * 发布指定的包 * * - 并且在package.json中记录最后发布时间 * * 本命令只能在包文件夹下执行 * * @param task */ // publishPackage(task) { // const { // rootDir, // distTag, // build, // test, // buildScript, // increment, // silent, // package: currentPackage, // } = this; // } } export { Context, defsContextOptions };