Node命令行工具,方便commit提交信息

69 阅读2分钟

背景

项目提交commit需要符合一个公司规定的模版,git commit -s 一点点写太麻烦了,为了省时省力,搞了一个命令行工具

解决方案

初始化

npm init

package.json

注意 bin

{
  "name": "my-scripts",
  "version": "1.0.0",
  "description": "node 的一些工具小脚本,用于练习node",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "clean": "rimraf dist",
    "dev": "npm run clean && tsc -w",
    "prepublish": "npm run clean && tsc"
  },
  "bin": {
    "my-scripts": "bin/index.js",
    "my-commit": "bin/commit.js" 
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/zeroone001/node-scripts.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/zeroone001/node-scripts/issues"
  },
  "homepage": "https://github.com/zeroone001/node-scripts#readme",
  "devDependencies": {
    "@types/node": "^17.0.0",
    "@typescript-eslint/eslint-plugin": "^5.7.0",
    "@typescript-eslint/parser": "^5.7.0",
    "chalk": "^4.1.2",
    "child_process": "^1.0.2",
    "enquirer": "^2.3.6",
    "eslint": "^7.32.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "execa": "^4.1.0",
    "husky": "^7.0.4",
    "lint-staged": "^12.1.2",
    "minimist": "^1.2.5",
    "prettier": "^2.5.1",
    "rimraf": "^3.0.2",
    "typescript": "^4.5.4"
  },
  "lint-staged": {
    "*.{js,ts}": [
      "prettier-eslint --write",
      "eslint --fix",
      "git add"
    ]
  }
}

bin/commit

#!/usr/bin/env node

const chalk = require('chalk');

/* 
  交互式询问用户输入
  https://github.com/enquirer/enquirer
*/
const { prompt } = require('enquirer');

/* 参数 */
const arg = process.argv.slice(2);
const args = require('minimist')(arg);

/* 控制台输出 */
const step = (msg) => console.log(chalk.cyan(msg));
/* 
  run 真实在终端跑命令,比如 yarn build --release
  使用 child_process 依赖也可以
  这里参看Vue3 使用的 execa
*/
const execa = require('execa');
/* 封装execa */
const run = (bin, args, opts = {}) => execa(bin, args, { stdio: 'inherit', ...opts });

const command = (com) => {
  return execa.command(com);
};

async function main() {
  /* 判断是否有修改 */
  const { stdout: stdoutDiff } = await command('git diff');
  if (!stdoutDiff) {
    console.log(chalk.red('没有修改,结束commit'));
    return;
  }
  step('\ngit add -A');
  await command('git add -A');
  /* 
  提交信息
*/
  const { typeMes } = await prompt({
    type: 'select',
    name: 'typeMes',
    message: '请选择提交信息:',
    choices: ['Modify', 'New', 'Fix'],
  });
  /* 输入commit message */
  const responseCommit = await prompt({
    type: 'input',
    name: 'commit',
    message: '请输入change功能?',
  });
  let fixMessage = '';
  if (typeMes == 'Fix') {
    const jiraID = await prompt({
      type: 'input',
      name: 'jiraIDName',
      message: '请输入JIRA-ID?',
    });
    const mesCommit = await prompt({
      type: 'input',
      name: 'mesCommitName',
      message: '请输入进版原因?',
    });
    fixMessage = `\n${jiraID.jiraIDName}\n\n${mesCommit.mesCommitName}\n`;
  }
  const message = responseCommit.commit;
  if (message) {
    /* 从分支上获取规范化信息 */
    /* 1. 当前分支名称 */
    // const { stdout: stdoutName } = await command(`git rev-parse --abbrev-ref HEAD`);
    /* 2. 正则获取需求号 */
    // const matchArr = stdoutName.match(/^feature\/([A-Z]+-\d+)_/);
    // const targetDemand = matchArr ? matchArr[1] : 'APP-000000';
    const mesAll = `[${typeMes}]: ${message}\n${fixMessage}\nSigned-off-by: xxx <xxx@xxx.com>`;
    step(`\ngit commit -s '${mesAll}'`);
    await run('git', ['commit', '-m', `${mesAll}`]);
    /* 
      确认是否push
    */
    const { isPush } = await prompt({
      type: 'select',
      name: 'isPush',
      message: '请确定是否push 远程?',
      choices: ['Y', 'N'],
    });
    if (isPush === 'Y') {
      step(`\ngit push origin`);
      await command(`git push origin`);
      console.log(chalk.yellow(`push success!`));
    }
  } else {
    console.log(chalk.red(`请输入信息`));
    return;
  }
}

main();

link

本地执行 sudo npm link

使用

项目中执行 my-commit, 根据提示一步步的填写回车就行了