From c9c51ebfb8f8aa18f5fcc015813e3486f7aec5e8 Mon Sep 17 00:00:00 2001 From: fisher Date: Fri, 1 Apr 2022 20:32:46 +0800 Subject: [PATCH] Update autopublish --- package.json | 4 +- packages/autopublish/index.js | 296 +++++++++++++++++++++----------- packages/autopublish/publish.js | 119 ------------- 3 files changed, 194 insertions(+), 225 deletions(-) delete mode 100644 packages/autopublish/publish.js diff --git a/package.json b/package.json index b56dd4c..e503640 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "test:babelplugin": "jest babel", "test:extract": "jest extract", "test:translate": "jest translate", - "demo:extract": "node ./packages/demo/extract.demo.js", - "demo:compile": "node ./packages/demo/compile.demo.js" + "list:package":"node ./packages/autopublish/index.js list" + }, "author": "", "license": "ISC", diff --git a/packages/autopublish/index.js b/packages/autopublish/index.js index cb79575..5e41ba4 100644 --- a/packages/autopublish/index.js +++ b/packages/autopublish/index.js @@ -1,113 +1,201 @@ /** - * - * 自动发布工具 - * - * 自动读取当前项目的版本标签,如果不致则进行 - * + * 用于多包环境下的自动发布 + * + * autopublish + * + * 1.在package.json中添加scripts + * { + * scripts:{ + * "publish":"autopublish [options]", + * } + * } + * 2. 参数 + * -q: 默认情况下会比对最后一次发布的时间,来决定是否自动发布 + * 当-q参数被指定时,会询问用户 + * + * + * * - * - * 支持两种发布方式: - * - * 1. 自动发布 - * - * 当选择自动发布时,会读取当前项目下的所有文件,然后 - * - * 根据每个包的最后提交时间和最近一次发布来决定是否自动发布 - * 每个包发布时均需要修改package.json.lastPublish值 - * - * 2. 手动发布 - * 手动选择要发布的包 - * - * pnpm add @voerkai18n/autopublish - * - * // 自动发布 - * autopublish - * */ -const inquirer = require("inquirer"); -const fs = require("fs-extra"); -const shelljs = require("shelljs"); -const path = require("path"); -const createLogger = require("logsets"); -const commander = require("commander"); + const fs = require("fs-extra"); + const inquirer = require("inquirer"); -const dayjs = require("dayjs"); -const relativeTime = require("dayjs/plugin/relativeTime"); -dayjs.extend(relativeTime); + const path = require("path"); + const shelljs = require("shelljs"); + const createLogger = require("logsets"); + const { Command } = require('commander'); + const dayjs = require("dayjs"); + const relativeTime = require("dayjs/plugin/relativeTime"); + dayjs.extend(relativeTime); + + const logger = createLogger(); + + + const program =new Command() + + + + const packages = [ + "git log --format=%cd --date=iso -1 -- packages/babel/package.json", + "git log --format=%cd --date=iso -1 -- packages/cli/package.json", + "git log --format=%cd --date=iso -1 -- packages/runtime/package.json", + "git log --format=%cd --date=iso -1 -- packages/formatters/package.json", + "git log --format=%cd --date=iso -1 -- packages/vue/package.json", + "git log --format=%cd --date=iso -1 -- packages/vite/package.json", + "git log --format=%cd --date=iso -1 -- packages/autopublish/package.json", + "git log --format=%cd --date=iso -1 -- packages/utils/package.json" + ] + + function getPackages(){ + let workspaceRoot = process.cwd() + if(!fs.existsSync(path.join(workspaceRoot,"pnpm-workspace.yaml"))){ + console.log("命令只能在工作区根目录下执行") + return + } + // 获取包最后一次提交的时间 + const getLastCommitScript = "git log --format=%cd --date=iso -1 -- {packagePath}" + return fs.readdirSync(path.join(workspaceRoot,"packages")).map(packageName=>{ + const pkgFile = path.join(workspaceRoot,"packages",packageName,"package.json") + if(fs.existsSync(pkgFile)){ + const { name, version }= fs.readJSONSync(pkgFile) + const lastCommit = shelljs.exec(getLastCommitScript.replace("{packagePath}",`packages/${packageName}/package.json`), { silent: true }).stdout.trim() + return { + name, + version, + lastCommit + } + } + }).filter(pkgInfo=>pkgInfo) + } + + function assertInWorkspaceRoot(){ + const workspaceRoot = process.cwd() + if(!fs.existsSync(path.join(workspaceRoot,"pnpm-workspace.yaml"))){ + throw new Error("命令只能在工作区根目录下执行") + } + } + + /** + * 返回当前包是否有未提交的文件 + * + * 如果包文件夹下有未提交的文件,则返回true + * + */ + function getPackageLastChanges(packageName){ + const changeFiles = shelljs.exec(`git status -s .`, { silent: true }).stdout.trim() + return changeFiles.length>0 ? changeFiles.split("\n") : [] + } + +function execShellScript(script){ + if(shelljs.exec(script).code>0){ + throw new Error(`执行<${script}>失败`) + } +} -const logger = createLogger(); + program + .command("publish") + .description("发布当前工作区下的包") + .option("-f, --force", "强制发布") + .option("--no-auto-commit", "不提交源码") + .option("-q, --query", "询问是否发布,否则会自动发布") + .option("-i, --version-increment-step [value]", "版本增长方式,取值major,minor,patch",'patch') + .action(async (options) => { + console.log(JSON.stringify(options)) + const {versionIncrementStep,autoCommit} = options + const packageFolder = process.cwd() + const packageName = path.basename(packageFolder) + const pkgFile = path.join(packageFolder,"package.json") + + const { scripts } = fs.readJSONSync(pkgFile) + + logger.log("包名:{}",`${packageName}`) + + + // 第一步: 查询当否已经提交了代码,如果没有则提交代码 + const lastChanges = getPackageLastChanges(packageName) + let lastCommit = shelljs.exec(`git log --format=%cd --date=iso -1 -- .`, { silent: true }).stdout.trim() + if(lastCommit){ + lastCommit = dayjs(lastCommit) + logger.log("最后一次提交:{}({})",lastCommit.format("YYYY-MM-DD HH:mm:ss"),lastCommit.fromNow()) + } + if(lastChanges.length>0){ + logger.log("包[{}]存在{}个未提交的文件:",packageName,lastChanges.length) + lastChanges.forEach(file=>logger.log(` - ${file.trim()}`)) + let isCommit = autoCommit + if(!autoCommit){ + const result = await inquirer.prompt({ + name:"isCommit", + type:"confirm", + message:"是否提交未提交的文件?" + }) + isCommit = result.isCommit + } + if(isCommit){ + execShellScript(`git commit -a -m "Update ${packageName}"`) + } + + + } -const program = commander() + + + // 由于每次发布均会更新npm version patch,并且需要提交代码 + // const lastCommit = shelljs.exec(`git log --format=%cd --date=iso -1 -- ${pkgFile}`, { silent: true }).stdout.trim() + + // // 增加版本号 + // shelljs.exec(`npm version ${versionIncrementStep}`, { silent: true }).stdout.trim() + + // // + // shelljs.exec(`pnpm publish --access publish`, { silent: true }).stdout.trim() + + }) + + program + .command("list") + .description("列出各个包的最后一次提交时间和版本信息") + .action(options => { + assertInWorkspaceRoot() + getPackages().forEach(package => { + if(package.lastCommit){ + console.log(`${package.name.padEnd(16)}\tVersion: ${package.version.padEnd(12)} lastCommit: ${dayjs(package.lastCommit).format("YYYY/MM/DD hh:mm:ss")}(${dayjs(package.lastCommit).fromNow()}) `) + }else{ + console.log(`${package.name.padEnd(16)}\tVersion: ${package.version.padEnd(12)} lastCommit: None `) + } + }) + }) + + + + program.parseAsync(process.argv); + - -program - .version("1.0.0") - .option("-a, --auto", "自动发布") - .option("-a, --auto", "启用自动发布") - .option("-m, --monorepo", "是否是monorepo工程") - .option("-i, --independent", "每个包独立发布") - .option("-e, --excludePackages", "多包场景时忽略的包") - .action((options) => { - - - - - })) - - - - -// 读取packages所有包 - -let excludePackages = ["apps"]; - -let packages = []; - -fs.readdirSync(path.join(__dirname, "packages")).forEach(function(packageName){ - if (excludePackages.includes(packageName)) return; - const packageFolder = path.join(__dirname, "packages", packageName); - // 读取指定包 - const { version: packageVersion,lastPublishTime } = require(path.join(packageFolder,"package.json")); - // 最后一次提交的时间 - const packageLastCommitTime = shelljs.exec(`git log -1 --format=%cd --date=iso ${packageFolder}`, {silent: true}).stdout.trim(); - // 最后发布的时间 - packages.push({ - name: `@voerkai18n/${packageName.padEnd(20)}\t\t( Version:${packageVersion}, LastCommit: ${dayjs(packageLastCommitTime).fromNow()})`, - value: { - packageFolder, - lastCommitTime: packageLastCommitTime, - version: packageVersion, - }, - }); -}); - -inquirer - .prompt([ - { - type: "confirm", - name: "autoPublish", - message: "是否自动发布?", - default: true, - }, - { - type: "checkbox", - name: "selectPackages", - message: "请选择要发布的库:", - choices: packages, - when: function (answer) { - return !answer.autoPublish; - }, - }, - ]) - .then((answers) => { - console.log(answers); - }) - .catch((error) => { - if (error.isTtyError) { - // Prompt couldn't be rendered in the current environment - } else { - // Something else went wrong - } - }); +// inquirer +// .prompt([ +// { +// type: "confirm", +// name: "autoPublish", +// message: "是否自动发布?", +// default: true, +// }, +// { +// type: "checkbox", +// name: "selectPackages", +// message: "请选择要发布的库:", +// choices: packages, +// when: function (answer) { +// return !answer.autoPublish; +// }, +// }, +// ]) +// .then((answers) => { +// console.log(answers); +// }) +// .catch((error) => { +// if (error.isTtyError) { +// // Prompt couldn't be rendered in the current environment +// } else { +// // Something else went wrong +// } +// }); diff --git a/packages/autopublish/publish.js b/packages/autopublish/publish.js deleted file mode 100644 index ddc7c16..0000000 --- a/packages/autopublish/publish.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * 用于多包环境下的自动发布 - * - * autopublish - * - * 1.在package.json中添加scripts - * { - * scripts:{ - * "publish":"autopublish [options]", - * } - * } - * 2. 参数 - * -q: 默认情况下会比对最后一次发布的时间,来决定是否自动发布 - * 当-q参数被指定时,会询问用户 - * - * - * - * - */ - -const fs = require("fs-extra"); -const path = require("path"); -const shelljs = require("shelljs"); -const createLogger = require("logsets"); -const { Command } = require('commander'); -const dayjs = require("dayjs"); -const relativeTime = require("dayjs/plugin/relativeTime"); -dayjs.extend(relativeTime); - -const logger = createLogger(); - - -const program =new Command() - - - - -const packages = [ - "git log --format=%cd --date=iso -1 -- packages/babel/package.json", - "git log --format=%cd --date=iso -1 -- packages/cli/package.json", - "git log --format=%cd --date=iso -1 -- packages/runtime/package.json", - "git log --format=%cd --date=iso -1 -- packages/formatters/package.json", - "git log --format=%cd --date=iso -1 -- packages/vue/package.json", - "git log --format=%cd --date=iso -1 -- packages/vite/package.json", - "git log --format=%cd --date=iso -1 -- packages/autopublish/package.json", - "git log --format=%cd --date=iso -1 -- packages/utils/package.json" -] - -function getPackages(){ - let workspaceRoot = process.cwd() - if(!fs.existsSync(path.join(workspaceRoot,"pnpm-workspace.yaml"))){ - console.log("命令只能在工作区根目录下执行") - return - } - // 获取包最后一次提交的时间 - const getLastCommitScript = "git log --format=%cd --date=iso -1 -- {packagePath}" - return fs.readdirSync(path.join(workspaceRoot,"packages")).map(packageName=>{ - const pkgFile = path.join(workspaceRoot,"packages",packageName,"package.json") - if(fs.existsSync(pkgFile)){ - const { name, version }= fs.readJSONSync(pkgFile) - const lastCommit = shelljs.exec(getLastCommitScript.replace("{packagePath}",`packages/${packageName}/package.json`), { silent: true }).stdout.trim() - return { - name, - version, - lastCommit - } - } - }).filter(pkgInfo=>pkgInfo) -} - -function assertInWorkspaceRoot(){ - const workspaceRoot = process.cwd() - if(!fs.existsSync(path.join(workspaceRoot,"pnpm-workspace.yaml"))){ - throw new Error("命令只能在工作区根目录下执行") - } -} - - -program - .command("publish") - .description("发布当前工作区下的包") - .option("-f, --force", "强制发布") - .option("-q, --query", "询问是否发布,否则会自动发布") - .option("-i, --version-increment-step [value]", "版本增长方式,取值major,minor,patch",'patch') - .action(options => { - const {versionIncrementStep} = options - const packageFolder = process.cwd() - const pkgFile = path.join(packageFolder,"package.json") - - // 由于每次发布均会更新npm version patch,并且需要提交代码 - const lastCommit = shelljs.exec(`git log --format=%cd --date=iso -1 -- ${pkgFile}`, { silent: true }).stdout.trim() - - // 增加版本号 - shelljs.exec(`npm version ${versionIncrementStep}`, { silent: true }).stdout.trim() - - // - shelljs.exec(`pnpm publish --access publish`, { silent: true }).stdout.trim() - - }) - -program - .command("list") - .description("列出各个包的最后一次提交时间和版本信息") - .action(options => { - assertInWorkspaceRoot() - - getPackages().forEach(package => { - //console.log(`${package.name}`) - if(package.lastCommit){ - console.log(`${package.name.padEnd(16)}\tVersion: ${package.version.padEnd(12)} lastCommit: ${dayjs(package.lastCommit).format("YYYY/MM/DD ")}(${dayjs(package.lastCommit).fromNow()}) `) - }else{ - console.log(`${package.name.padEnd(16)}\tVersion: ${package.version.padEnd(12)} lastCommit: None `) - } - }) - }) - - - -program.parse(process.argv);