一句话概括: 改造 cz-customizable ,使 commit message 的配置更加个性化。
前言
多人协作开发时,也许会有 commit message 格式规范的要求。
git + commitize + cz-customizable 可以帮助我们实现规范化的 commit message。
本文主要记录笔者在适配 cz-customizable 时遇到的问题、解决思路 及 操作步骤。
抛砖引玉,希望能给遇到相似问题的朋友一点参考或启发。
cz-customizable 的局限性
下文是 commitize 和 cz-customizable 的简单介绍,熟悉的朋友可以跳过。
commitize 是一个辅助提交 commit message 的工具。
通过开发人员与CLI的交互,生成并提交一条格式化的 commit message。
而 cz-customizable 是 commitize 的适配器。
通过读取文件 cz-config.js 实现一定程度上的配置调整,比如跳过scope的填写、自定义题目等等。
但使用 cz-customizable 也有局限性,如 不支持添加新题目、无法添加变量输入。这种局限性,源于官网文档 cz-config.js 不提供相关参数的配置。笔者正在做的(麻花要求 commit message )项目,也是如此。
以下问题清单,由局限性而生。
问题清单
下列为笔者遇到的问题清单,其中问题1和2建议按顺序阅读:
1. 如何新增一个自定义变量并给出输入提示?
2. 如何自定义message.header的格式?
3. 如何集成到项目中?并实现源码最小改动?(待更新)
本文默认您已使用过cz-customizable,或者看过readme操作文档。
1. 如何新增一个自定义变量并给出输入提示?
本文以存储变量issueId为例,预期的输入提示question为"Write the connnected issueId of this change (required):"
思路:观察 message 如何生成 -> 查看对应源码
1.观察 message 如何生成:
message 是字符串,由用户输入项按约定格式拼接而成。
CLI 执行命令 cz-customizable 后,会弹出提示文字question,并将用户输入项(一般为字符串)存储到 question 指定的变量中,再按一定规则将这些变量组织成我们最终想要的 commit message 格式。
2.查看源码
cz-customizable 源码 index.js,给了我们questions的定义路径。
// index.js
const questions = require('./lib/questions').getQuestions(config, cz);
进入源码 questions.js 看 getQuestions 函数,能提炼出以下信息:
getQuestions 给开发者提供了CLI输出 questions 的调整机会,如:
题目说明自定义、选项自定义、跳过指定题目 等。
questions 调整需要同步更改配置文档 cz-config.js 。
也就是说,要存储issueId,需要同时改动 questions.js 和 cz-config.js。
回到 getQuestions 函数,变量 questions 是 getQuestions 的内部变量,笔者想到两个方案改动 questions :
一、直接在函数内部往数组变量 questions 插入新对象。
二、question 支持从 config 配置获取。
操作步骤
为了快速验证答案,本次选了方案一,下方为伪代码:
// 数组变量 questions 插入此对象
{
type: 'input',
name: 'issueId',
message: messages.issueId,
default: null,
validate(value) {
const limit = config.issueIdLimitRange || [0, 10];
if (value.length > limit[1] || value.length < limit[0]) {
return `Exceed limit range: [${limit[0]}, ${limit[0]}]`;
}
const reg = new RegExp(/^\d+$/);
if(!reg.test(value)) {
return '只允许输入数字'
}
return true;
}
}
// cz-config.js - message对象添加属性:
messages: {
issueId:"\nWrite the connnected issueId of this change (required):",
// ...
}
至此,添加完毕。
CLI运行 cz-customizable,第一个即是我们为issueId自定义的题目。效果如图:
补充:
数组变量 questions 的数据结构遵循 inquirer 插件的 questions 结构。
插件 inquirer,与命令行交互的工具(A collection of common interactive command line user interfaces)。
迁移性也不错,支持多平台
2.如何自定义message.header的格式?
下表列出了 messsage.header 的两种格式,表体第一行为官网支持格式,第二行为自定义格式(在第一行的基础上改动,添加了 issueId,删除了 scope )。
| 格式对比 | 举例 |
|---|---|
| <type>(<scope>):<subject> | refactor(视图调整):代码更改,既不修复错误也不添加功能 |
| [issueId]<type>:<subject> | [14653]refactor:代码更改,既不修复错误也不添加功能 |
有了问题1(question.js新增issueId输入)的铺垫,问题2要实现起来并不困难。
直接上落地方案:
build-commit.js 添加 addissueId 函数
// build-commit.js
const addissueId = (id, config) => {
const prefix = _.get(config, 'idPrefix', '[');
const suffix = _.get(config, 'idSuffix', ']');
return _.trim(`${prefix}${id}${suffix}`);
};
const head =
addissueId(answers.issueId, config) + // add
addType(answers.type, config) +
addScope(answers.scope, config) +
addTicketNumber(answers.ticketNumber, config) +
addSubject(answers.subject.slice(0, config.subjectLimit));
CLI执行,最终生成了预期的 message 格式,输出结果一览:
[655544]feat: ff2
这里 type 删除了前后缀,是因为改造了 addType 。
header其他部分的格式改造大抵如此(如 addScope|addTicketNumber|addSubject )。
const addType = (type, config) => {
const prefix = _.get(config, 'typePrefix', '');
const suffix = _.get(config, 'typeSuffix', '');
/* 删除前后缀 */
// return _.trim(`${prefix}${type}${suffix}`);
return _.trim(`${type}`);
};
3. 如何集成到项目中?
笔者通过打源码补丁包的方式,将改动集成到项目中。
先说明为什么要改源码:
如果涉及问题1、2,即官网 cz-config.js 不支持的参数配置。
那么我们必须改动 question.js 和 build-commit.js 。
至此问题转换成如下两个:
一、如何获取稳定版本的源码。
二、如何生成源码补丁。
当然也可以直接把源码拷贝出来,放到项目下,当做项目代码的一部分,此方法的操作步骤没什么好说的。
回到问题一二。
一、如何获取稳定版本的源码?
很简单,package.json的版本号固定即可,参考官网版本号约定规范。如有必要也可以提交package-lock.json。
二、如何生成源码补丁?
本次使用插件 patch-package,github地址 。
CLI运行命令 npx patch-package cz-customizable,项目根目录下的patches目录中创建一个名为package-name+version.patch的文件
执行成功的结果如下图:
验证补丁包能否生效:
验证思路:
项目移除依赖 cz-customizable -> 重装依赖包和补丁包 -> CLI执行 cz-customizable 验证是否成功
1.项目移除依赖 cz-customizable:
npm uninstall cz-customizable
2.重装依赖包和补丁包:
CLI 执行命令 npm i 之前,先配置package.json
"devDependencies": {
+ "cz-customizable": "7.0.0"
},
"scripts": {
+ "postinstall": "patch-package"
}
提交代码本来就是开发干的事儿,因此只加到 devDependencies
postinstall - 是运行命令 npm install 期间要附加执行的命令,命令组合规则为 +script (本例 post + install ),postinstall 在安装软件包后运行。更多 npm 支持 package.json 文件的“scripts”属性规则参考文档
CLI 执行命令 npm i ,下图可看到 cz-customizable 安装成功。
3.CLI执行 cz-customizable
顺利的话,弹出了我们关于 issueId 的提示(回顾问题二)