커밋 메시지 자동 검사
Git Hooks와 commitlint를 이용해 작성한 커밋 메시지가 유효한지 검사할 수 있습니다.
다음 글들을 참고하시면 더 많은 정보를 얻으실 수 있습니다.
Git Hooks
프로젝트의 .git 폴더 내부는 다음과 같이 구성되어 있습니다.
├── COMMIT_EDITMSG
├── HEAD
├── ORIG_HEAD
├── config
├── description
├── hooks
├── index
├── info
├── logs
├── objects
└── refs
이 중 hooks 폴더에 들어가면 다음과 같은 sample 파일들을 만나게 됩니다.
├── applypatch-msg.sample
├── commit-msg.sample
├── fsmonitor-watchman.sample
├── post-update.sample
├── pre-applypatch.sample
├── pre-commit.sample
├── pre-merge-commit.sample
├── pre-push.sample
├── pre-rebase.sample
├── pre-receive.sample
├── prepare-commit-msg.sample
└── update.sample
각각의 파일들은 쉘 스크립트 파일들이며, .sample을 지울 경우 git의 각 과정에서 작동합니다.
이 중에서 commit-msg 파일을 작성해 commit message 작성 후 convention 검사를 진행할 수 있습니다.
정규표현식을 사용해서 commit 메시지 체크하기
# exit with an error
exit 1
각 과정에서 위와 같은 방식으로 종료할 경우, 그 commit (이 외에 다른 동작들도) 은 자동적으로 취소됩니다.
따라서 다음과 같은 sh 파일을 만들 수 있습니다.
config=commit-msg.config.json
# set variables
enabled=$(jq -r .enabled $config)
revert=$(jq -r .revert $config)
types=($(jq -r '.types[]' $config))
min_length=$(jq -r .length.min $config)
max_length=$(jq -r .length.max $config)
if [[ ! -f $config || ! $enabled ]]; then
exit 0
fi
regexp="^("
if $revert; then
regexp="${regexp}revert: )?(\w+)("
fi
for type in "${types[@]}"
do
regexp="${regexp}$type|"
done
regexp="${regexp})(\(.+\))?: "
regexp="${regexp}.{$min_length,$max_length}$"
msg=$(head -1 $1)
if [[ ! $msg =~ $regexp ]]; then
echo -e "\n\e[1m\e[31m[INVALID COMMIT MESSAGE]"
echo -e "------------------------\033[0m\e[0m"
echo -e "\e[1mValid types:\e[0m \e[34m${types[@]}\033[0m"
echo -e "\e[1mMax length (first line):\e[0m \e[34m$max_length\033[0m"
echo -e "\e[1mMin length (first line):\e[0m \e[34m$min_length\033[0m\n"
# exit with an error
exit 1
fi
// commit-msg.config.json
{
"enabled": true,
"revert": true,
"length": {
"min": 1,
"max": 52
},
"types": [
"build",
"ci",
"docs",
"feat",
"fix",
"perf",
"refactor",
"style",
"test",
"chore"
]
}
위 스크립트는 json 파일로 설정을 읽어들여오고 정규표현식을 이용해 검사하는 코드입니다.
huscky & commitlint를 이용한 검사
git hook 을 트리거 하는 용도로 npm 모듈인 huscky를 사용할 수 있습니다.
commitlint의 경우 commit 에 대한 lint를 확인하여 성공/실패를 리턴합니다.
다음 명령을 .git 폴더가 있는 프로젝트의 root에서 실행해주세요
yarn add husky @commitlint/cli @commitlint/config-conventional -D
husky가 githook 을 덮어쓰기 때문에 husky 설정 이전에 repo를 먼저 초기화 해야 합니다.
그리고 package.json에 다음과 같은 내용을 추가합니다.
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
}
위 명령은 husky에서 hooks가 일어났을 때, commit-message에서 commitlint를 검사한다는 내용입니다.
commitlint에서 extends로 node_modules 내부의 @commitlint/config-conventional 에 존재하는 index.js 파일에서 설정을 읽어 오는데요,
설정 파일은 다음과 같습니다.
module.exports = {
parserPreset: 'conventional-changelog-conventionalcommits',
rules: {
'body-leading-blank': [1, 'always'],
'body-max-line-length': [2, 'always', 100],
'footer-leading-blank': [1, 'always'],
'footer-max-line-length': [2, 'always', 100],
'header-max-length': [2, 'always', 100],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [
2,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
'test',
],
],
},
};
package.json의 commitlint.extends 부분을 직접 작성한 옵션으로 변경하면, 프로젝트에 적합한 commit convention을 적용할 수 있습니다.
'공부' 카테고리의 다른 글
CRA를 사용하지 않고 React 프로젝트 생성하기 (0) | 2020.08.16 |
---|