git hooks를 사용하여 commit 실수 줄이기

김장남·2021년 9월 17일
1

오늘도 회사에서 얻은것을 정리해본다.

회사 입사하고 가장 놀랐던것은 lint와 prettier가 없다는것!
그것은 react의 기초적인 문법과 공통적인 코딩규칙이 없다는것!

그 다음으로 놀란것은 typescript가 없다는것!

이 두개가 나를 엄청 괴롭혔다..

하지만! 새로만드는 Next.js를 사용하는 어드민에 typescript를 와 lint, prettier 를 셋팅하고
RN으로 되어있는 앱에서는 린트를 적용하였다.

린트를 적용하고 놀랐던 점은...변수가 없는데 사용되고 있었다는 것..그리고 hooks기본 룰(dependency Array) 조차 지켜지고 있지 않다는점..회사 서비스는 너무나 좋은데 개발팀은 조금 많이 아쉽다.

여하튼! 각설하고.

당연하게도 PR기능도 코드리뷰도 없었고 이번 프로젝트를 시작하면서 브랜치들도 너무 많고 코드리뷰의 필요성도 느꼈다.
전 회사에서 깃헙을 사용하면서 fork를 사용하여 개발하고 pr로 머지하는 경험이 너무 좋았어서 새로운 프로젝트를 시작하면서
팀원들에게 한번 해보면 어떻겠냐는 의견을 냈고 다행히도 두 분다 한번 해보겠다고 동의 해주셔서
PR과 코드리뷰를 진행하고 있다.

코드리뷰의 수준은 높은 수준은 아니지만 그래도 서로의 실수나 의도를 한번씩 되짚어 볼수있게 되었고 포크를 사용하여 개발 하다 보니 메인 레포지토리의 브랜치가 깔끔해진다는 장점이 있었다. 그리고 Jira의 티켓번호를 사용하여 커밋하고 PR하고 머지 하니 각 작업별로 추적이 쉬워졌다.

내가 건의한 새로운 문화가 자리를 잘 잡아가서 기분이 좋았다.

그런데 PR을 계속 하다보니 디버깅용으로 넣어놓은 console.log가 업로드되어 코드리뷰의 1/3정도가 테스트코드를 지워달라는 요청이었고
나는 이런 실수를 반복했다. 그래서 휴먼에러를 없애보기로 결심했다.

그리하여 찾은 결과는 git hook의 preCommit을 사용하여 커밋전 console.log를 찾아내어 커밋을 중지시킬수 있다는 것을 알게 됐다.

#!/bin/bash

# Redirect output to stderr.
exec 1>&2
# enable user input
exec < /dev/tty

consoleRegexp='^[^-].*.*console.log'
filenameRegexp='\(^[^-].*.*console.log(\|^+++\)'
if test "$(git diff --cached | grep -c "$consoleRegexp")" != 0
then
  exec git diff --cached | grep -ne "$filenameRegexp" | grep -B 1 "$consoleRegexp"
  read -rp "There are some occurrences of console.log at your modification. Are you sure want to continue? (y/n) " yn
  if echo "$yn" | grep "^[Yy]$"
  then
    exit 0; #THE USER WANTS TO CONTINUE
  else
    exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
  fi
fi

출처

스크립트의 내용은 그리 복잡한 내용은 아니었다. git diff 를 캐시에 넣고 grep으로 console.log 정규표현식을 사용해 console.log가 사용되었는지를 찾는 것이다.

누군가 스크립트를 잘 짜주었기 때문에 나는 이것을 살짜쿵 바꿔서 사용해보기로 했다.
스크립트를 보게 되면 console.log가 포함되어있을때 계속 커밋할지 여부를 물어보는 부분이 있는데 그부분을 무조건 커밋을 멈추게 변경하고 sourcetree를 사용할때는 tty를 사용하여 키보드 입력을 받을수 없기 때문에 이 부분도 삭제 해준다.

# Redirect output to stderr.
exec 1>&2
# enable user input
# sourcetree에서는 사용자 입력을 받을 수 없음
# exec < /dev/tty

consoleRegexp='^[^-].*.*console.log'
filenameRegexp='\(^[^-].*.*console.log(\|^+++\)'

if test "$(git diff --cached | grep -c "$consoleRegexp")" != 0
then
 exec git diff --cached | grep -ne "$filenameRegexp" | grep -B 1 "$consoleRegexp"
 echo "변경된 파일중 console.log가 포함되어 있습니다."
 exit 1; # THE USER DONT WANT TO CONTINUE SO ROLLBACK
fi

이렇게 만들어서 .git/hooks 에 넣고 console.log가 있는 코드를 커밋해봤더니 커밋이 잘 막힌다.

그런데 이걸 프로젝트에 올려서 팀원들과 같이 사용 하려니 .git 폴더가 .gitignore에 포함되어있고 그걸 우회하려면
git설정을 변경하여 hooks폴더의 위치를 변경하거나, 스크립트를 사용하는 방법이 있는데 이 두 방법은 좀 불편할거 같고
그래서 잘 몰라도 사용 할 수 있게 해야 된다고 생각하여 자동화 하는 방법을 찾아보니 husky라는 유틸을 사용하면 될것같았다.

사용법을 잘 몰라 블로그공식문서을 참고했다.

공식문서에서 말해주듯이 npm을 사용하면 prepare 기능을 사용하여 간단하게 사용할수있지만 yarn을 사용하면 prepare기능이 없어 아래 링크의 방법을 사용하여 명령어를 사용해야 한다.
https://typicode.github.io/husky/#/?id=yarn-2

profile
React 개발자

0개의 댓글