https://codeburst.io/understanding-git-hooks-in-the-easiest-way-bad9afcbb1b3
OLD [2020-06-12]
Write task name to commit msg
Need to install the following deps:
yarn add -D husky
Need to make scripts/write-task-name-to-commit.js
:
#!/usr/bin/env node
const fs = require('fs')
const child_process = require('child_process')
const { promisify } = require('util')
const { EOL } = require('os')
const exec = promisify(child_process.exec)
const timeToWrite = 5000
const branchContract = /^(feature|bugfix)\/(CONTRACT)-[0-9]{1,4}/
const taskContract = /(CONTRACT)-[0-9]{1,4}/
const commitEditmsgFile = process.env.HUSKY_GIT_PARAMS || process.argv[2] // file '.git/COMMIT_EDITMSG'
cleanup()
main()
async function getCurrentBranch() {
const branchOutput = await exec('git symbolic-ref --short HEAD')
if (branchOutput.stderr) {
throw new Error(stderr)
}
return branchOutput.stdout
}
function getTaskFromBranch(branchName) {
if (!branchContract.test(branchName)) {
console.log('⚠️ Имя ветки не соответствует шаблону "{type}/(CONTRACT)-{number}"')
throw new Error('Unsupported branch name')
}
const [, task] = branchName.split('/')
return task.replace(/\s+/g, '')
}
function existTaskInFile(file) {
const message = fs.readFileSync(file, 'utf8')
const withoutComments = message
.split(EOL)
.filter((l) => !/^#/.test(l))
.join('')
return taskContract.test(withoutComments)
}
function writeTaskToTitleInFile(task, file) {
const message = fs.readFileSync(file, 'utf8')
const lines = message.split(EOL)
lines[0] = `${task} ${lines[0]}`
const newLines = lines.join(EOL)
fs.writeFileSync(file, newLines, 'utf8')
}
function cleanup() {
setTimeout(() => {
console.log('⚠️ Таймаут commit-msg hook ', timeToWrite)
process.exit(1)
}, timeToWrite)
}
async function main() {
let task = ''
let branchName = ''
if (existTaskInFile(commitEditmsgFile)) {
console.log('👌 В commit сообщении уже есть id задачи')
process.exit(0)
}
try {
branchName = await getCurrentBranch()
task = getTaskFromBranch(branchName)
} catch (error) {
console.log('⚠️ Не удалось получить имя задачи', task, 'из ветки', branchName)
process.exit(1)
}
try {
writeTaskToTitleInFile(task, commitEditmsgFile)
} catch (err) {
console.log('⚠️ Не удалось записать имя задачи', task, 'в commit-msg файл', commitEditmsgFile)
console.error(err)
process.exit(1)
}
console.log('👌 Перезапись сообщения коммита: УСПЕШНО')
process.exit(0)
}
As you can see my pattern is /^(feature|bugfix)\/(CONTRACT)-[0-9]{1,4}/
. Next changes in package.json
should be like this:
{
"husky": {
"hooks": {
"commit-msg": "node ./scripts/write-task-name-to-commit"
}
},
}
That's all. Task name should be added for next commit automatically.
Pre commit
Need to install the following deps:
# Our target deps:
yarn add -D prettier lint-staged
# Install this if necessary:
yarn add -D typescript eslint-config-prettier eslint-plugin-prettier@latest eslint-plugin-standard
Next changes in package.json
should be like this:
{
"lint-staged": {
"*.{js, jsx, ts, tsx}": [
// For storybook:
// "*.{js, jsx, ts, tsx} !.storybook/*": [
"node_modules/.bin/eslint --max-warnings=0",
"prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
}
And also you could make this updates in package.json
if interested:
{
"scripts": {
// ...
"lint": "eslint --debug src/**/*.js*",
"lint:fix": "eslint src/**/*.ts* --fix"
}
}
Congrats! The next commit will have your pre-commit
hook.
P.S.
На всякий случай, проверил, все ли работает если следовать по данной инструкции. Посмотреть можно здесь.