When submitting a bug fix, it is easy to forget to adjust the version number synchronously. If it is omitted, it is easy to cause problems such as missing updates. Therefore, it is planned to modify the version number into a rigid detection specification.
Achieve results with ESlint
detect almost, Git
automatically execute code detection after submission does not meet specifications submitted by the withdrawal on the error, then by submitting compliant.
analyze
Mainly to solve the following problems:
Trigger detection method
Now that we think of
ESlint
, the first thought is to add custom plug-insESlint
But I thought about it carefully, because it detects non-JavaScript files, and it is not a logical detection of the code. It is just to check whether the corresponding file has been modified before submitting, which is actually not a very suitable scenario.The most appropriate or directly
Git
hook,ESlint
is the use ofhusky
call detection in the relevant hooks.I wrote a husky7 + commitlint + lint-staged record , so the process is relatively familiar, just add the file with the relevant hook name under the
.husky
shell
script to start.Simple scripts are not conducive to maintenance, so I plan to
ESlint
, which is also convenient for adding functions later.How to know file changes
This is the
Git
. You only need to usegit diff
to compare thepackage.json
file, and the comparison information will be output.But the text is not easy to analyze, and no relevant available plug-ins are found all of a sudden, so I wrote a related parser by peggy to convert the text into json data that is convenient for parsing.
Terminate submission after submission failed
shell
script successfully returns0
and fails to returnnot 0.
Node.js
provides related methodsprocess.exit(1)
.If you don't understand the way, you can actually
lint-staged
. After all, there are ready-made examples.provides a way to actively bypass submission
Since it is added to the hook, you must not delete the hook and submit it when you don't need it. That can only do skip detection in the submission logic.
The most appropriate is
body
of the submission message. When the program recognizes the keyword, it can skip the detection logic.
Key logic
Provide command line invocation commands
Create an empty project, add the bin
field, and add related calling commands for our program
"bin":{
"check": "./dist/index.js"
}
The corresponding check
is the name of the command line call, and the corresponding value is the JavaScript file to be executed:
#!/usr/bin/env node
console.log('hello')
This will print out hello
.
Of course, this is not enough. Command line programs may also carry parameters or other functions, so you can cooperate with Commander.js
assist in processing command line commands.
Since it is written together with the business code, only a rough example can be provided:
import { Command } from "commander";
const program = new Command();
program
.command("change")
.option(
"--commitMsgPath <filePath>",
"当 commit message 中包含指定字符串时跳过当前命令检测"
)
.description("检测版本号是否有变动")
.action(async ({ commitMsgPath }: { commitMsgPath: string }) => {
try {
let msg: string[];
if (commitMsgPath) msg = readGitMessage(commitMsgPath);
const flag = await checkVersion(msg);
if (!flag) throw new Error("请修改版本号再提交");
} catch (e) {
console.error(`${DATA.NAME}: ${e.name} ${e.message}`);
process.exit(1);
}
});
program.parse(process.argv);
Call git diff to determine the data
simple-git
library can be used to execute git commands, which is very versatile, but unfortunately the data returned by diff is plain text, which is not convenient to process. Use the previously written simple diff format parser to process into readable json data.
The rest is very simple. Pass the returned diff data to the parser, and then determine whether there is a corresponding keyword version
. If there is, it means that the version number has been modified, and a more detailed version can be made if necessary. Number verification.
import simpleGit, { SimpleGit } from "simple-git";
const GitDiffParser = require("../lib/gitDiffParser");
/**
* 检测版本号是否变动
* @param msg
*/
export const checkVersion = async (msg?: string[]) => {
let flag = false;
const git: SimpleGit = simpleGit({
baseDir: process.cwd(),
binary: "git",
});
// 检测 git message 中是否有指定文本 有则跳过版本检测
if (msg && msg.some((item) => item === DATA.SKIP_MESSAGE_KEY)) return true;
// 判断版本号是否有变化
const diff = await git.diff(["--cached", "package.json"]);
if (diff) {
const result = <GitDiffParserResult>(
GitDiffParser.parse(diff, { REMOVE_INDENT: true })
);
result.change.forEach((item) => {
item.content.forEach((content) => {
if (content.type === "+" && content.text.includes(`"version"`))
flag = true;
});
});
return flag;
}
return flag;
};
Detection message provides a way to skip detection
It was originally written in the pre-commit
hook, but after checking a few git commands to get the message, there was no way to get the current message
.
So you can only switch to the commit-msg
hook and get the message $1
And what is returned is not the text of the message, but the file path of the message, so you need to read the file content yourself.
/**
* 读取git message消息文件
*/
export const readGitMessage = (filePath: string) => {
try {
const msg: string = fs.readFileSync(
path.join(process.cwd(), filePath),
"utf-8"
);
return msg.split(/\s/).filter((item) => item);
} catch (e) {
return undefined;
}
};
In this way, it checkVersion
process, compared with the predetermined key, if the same, it returns directly to true
, which skips the version detection logic.
commit-msg script
Adding to the project, you can directly npx
execute the detection logic. The message address is passed into the command as a parameter (previously .option("--commitMsgPath <filePath>", "Skip current command detection when the commit message contains the specified string") configuration parameter).
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx commitlint --edit "$1"
npx check change --commitMsgPath "$1"
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。