git hook 사용하기 with husky v6
현재 작업 플로우와 예상되는 문제점
일반적으로 git을 이용해 혼자 프로젝트를 할 때는 branch를 팔 일도 없으니 다음과 같은 전략으로 git을 사용했다.
git init => git add . => git commit -m "msg" => git push [repoName] [branchName]
간단히 협업할 때는 branch를 판 후에 미팅 때마다 merge하는 작업을 했다.
git branch [branchName] => git checkout [branchName] // branch 생성 및 이동
git pull [address] => ... 작업 => git push [repoName] [branchName]
git checkout [branchName A] => git merge [branchName B] // A branch에서 B merge
// conflict나는 것은 둘이 같이 모여서 몹 프로그래밍 하면 좋음. 안되면 책임이 있는 사람이 작업할 것.
그런데 위 협업 과정에서, lint를 안하고 push를 하는 등의 문제가 종종 나오게 되었는데 협업하는 사람이 겨우 2명인지라 그렇게 크리티컬한 문제는 아니었지만, 사람의 수가 많아지게 된다면 필시 문제가 생길 것이라 생각되었다.
남의 프로젝트를 살펴보니 husky라는 git hook을 관리하는 도구를 사용하더라.
외부 도구 없이 git hook을 사용하기
알아보니 husky와 같은 도구 없이도 git hook을 사용할 수 있었다.
https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
위 git-scm 사이트의 번역글을 읽었고 간단히 정리하자면 다음과 같다.
1) client-side 훅이 있고, server-side 훅이 있다.
There are two groups of these hooks: client-side and server-side.
Client-side hooks are triggered by operations such as committing and merging, while server-side hooks run on network operations such as receiving pushed commits. You can use these hooks for all sorts of reasons.
2) .git/hooks에 예제들이 있고, 이름에 따라 작동하며, 쉘로 코딩되어 있지만 실행가능하기만 하면 python도 되고 다 된다.
... you can write them in Ruby or Python or whatever language you are familiar with....
=> 이거 직접 다 짜고, 기존 라이브러리랑 연동을 어떻게 할 지를 생각해보면 생각보다 직접 만들기는 힘들수도...
3) 그래서 종류가 뭐가 있는지 정리해보려고 하니, 가비아 기술 블로그에서 이미 정리해놓은 게 있어서 가져와보았다.
한편, .git/hooks 내부를 실제로 출력한 결과는 아래와 같다. sample을 지우고 코드를 수정하면, git을 사용하면서 자연스럽게 hook이 트리거 된다.
husky를 사용하여 push 전에 formatting을 해보자.
https://github.com/typicode/husky
다 좋은데,
1) 위 처럼 직접 hook을 만들어 사용하는 것은 시간이 많이 드는 일이고,
2) 게다가 훅이 든 폴더인 .git은 gitignore의 대상이므로 협업자에게 공유되지 않는다.
따라서, husky를 써보려고 한다. (v6)
v5때 라이센스 문제가 있었던 것으로 보이는데, v6 때 MIT 라이센스가 되었으니 이슈는 해소되었으므로 아무 문제 없어졌다 :)
(1) installation
yarn add husky -D
(2) .husky
구성 방법에 대해서는 공식 문서 https://typicode.github.io/husky/#/?id=usage 를 참고합니다.
저는 권고하는 대로 recommended를 따랐습니다.
npx husky-init && npm install # npm
npx husky-init && yarn # Yarn 1
yarn dlx husky-init --yarn2 && yarn # Yarn 2
v4 버전에서는 .huskyrc를 만들어서 작성하는 것으로 보이는데, v6에서는 .husky 폴더를 만들어서 관리하는 것으로 보입니다.
(3) hook 작성하기
아래처럼 prettier를 구성해놓았으니까,
"scripts": {
"build:watch": "rm -rf ./dist && tsc -w",
"build": "rm -rf ./dist && tsc",
"start:dev": "nodemon --exec ts-node ./src/index.ts",
"format": "prettier --write \"src/**/*.ts\"",
"prepare": "husky install"
},
아래처럼 구성해놓으면 되겠습니다.
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
echo 'git hook from .husky'
npm run format
추가적으로 lint라던가, 테스트 코드를 실행하는 여러 방법이 있겠습니다.
특히, commit 전에 테스트를 실행하는 식으로 구성하면 더 좋을 것으로 보입니다.
ref)
https://woowabros.github.io/tools/2017/07/12/git_hook.html
=> 우형에서는 이미지 압축도 git hook으로 한단다.
https://library.gabia.com/contents/8492/
https://www.huskyhoochu.com/npm-husky-the-git-hook-manager/
https://library.gabia.com/contents/8492/