Git에서는 이벤트가 생겼을 때, 스크립트를 실행 할 수 있도록 하는 hook이라는 기능이 있다.

coding convention 관련해서 필요하여 찾아서 정리하였다. 사실 내용 자체는 진즉에 쓰던 내용인데 늑장부리다가 이제서야 대충이라도 마무리에서 업로드한다..그마저도 사진 붙이기는 귀찮아서 미완성인채로...업로드(나중에 수정해야지)

무튼! Git에 있는 모든 repository에 이미 hook을 지원하고 있다(전혀 몰랐었음...).

현재 가지고 repository의 .git/hooks/ 경로에 진입하면 아래와 같은 파일들을 볼 수 있다.

.sample의 확장자를 가지고 있는 파일은 모두 git에서 제공하는 hook들 이다.

 

이 중에서, 코드 Lint/Formatting 목적으로 주로쓰이는 hook은 pre-commit 이다.

pre-commit은 commit 하기 전에 필수적으로 확인해야 할 것이 있을때 활용된다.

코드 스타일을 검사할 때 정말 많이 활용되는 것 같다. 구글에 검색해보면 예제도 엄청 많다.

 

직접 shell script을 작성해서 미리 설치된 formatter를 실행하도록 할수도 있지만,

파이썬은 쉽게 할 수 있는 플러그인이 있어서 편리하다.

 

가장 먼저 pre-commit 패키지를 설치한다.

$ pip install pre-commit

mac에서는 brew로 설치하면 되는 듯하다.

 

 

설치 후에 pre-commit-config.yaml 파일의 생성을 위해서 아래 명령어를 입력해준다.

$pre-commit sample-config >.pre-commit-config.yaml

나같은 경우 이렇게 하니 encoding type 관련된 에러가 발생하였는데, 그 때는 아래 명령어를 활용하면 된다.

$pre-commit sample-config | out-file .pre-commit-config.yaml -encoding utf8

그러면 sample conifg 파일이 생성된다.

config 파일에 사용할 플러그 인들에 대한 정보를 작성해 준다. 활용할 플러그인은 총 세개이다.

black : 코드 포멧팅 / flake8 : 코드 린트 / isort : 파이썬 import 정리

 

포멧팅을 하는데 굳이 린팅을 할 필요가 있나 싶긴한데, 찾아보니 py파일 말고 문서같은 것들을 위해 린트가 필요하다고 하긴하는데,

자바같은 경우 말고도 꼭 필요한진 잘모르겠다. 그리고, black의 경우 따로 configuration을 제공하진 않는데(yapf는 어느정도 제공해주긴함) 근데 formatting 자체가 일관된 코드 스타일을 맞추기 위해서 하는 것이고, python의 경우 PEP8이라는 확고한 스타일이 있다보니 딱히 필요없긴 한 것 같다. 어쨋든 각 플러그인의 설정을 위해 setup.cfg 파일도 작성해 준다.

 

 

마지막으로 아래 명령어를 작성하면 .git/hook 경로에 pre-commit 파일이 생기고,

다음에 commit 하면 자동으로 pre-commit이 진행된다!

$ pre-commit install

 

 

 

'Git' 카테고리의 다른 글

[Git] hook을 활용한 통일성 있는 commit message  (0) 2022.08.01

pre-commit을 통해 코드의 통일성을 유지할 수 있는 것과같이

또다른 hook중 하나인 commit-msg를 통해서 commit 메세지도 관리해줄 수 있다.

이왕 pre-commit을 활용하는 김에 다른 hook들도 적용하면 좋을 것같아서 가능한대로 조금씩 적용해보려고 한다.

 

좋은 commit 메세지에 대한 조건은 여러가지가 있지만, 그 중 일부만 발췌하고 내가 필요한 부분을 수정하여 작성하였다. 

pre-commit 처럼 좀 접근성 쉽게 되면 참 좋았으련만, 대충 구글링해봐도 딱 내가 원하는 것은 없는 것같아서

이것저것 참고도하고 shell script 관해서 이리저리 뒤적거려서 작성해 보았다.

린트나 포멧팅과 같은 경우에는 아무래도 규정된 스타일이 언어마다 다르기 때문에 언어에 의존하여 작성이 되겠지만,

커밋 메시지의 경우에는 오히려 언어에 구애 받지 않는 것이 좋을 것 같아서 shell script로 작성했다.

shell script가 익숙하진 않아서 의도대로 제대로 구현한 건지는 모르겠다. 

일단, 몇 번의 테스트에서는 의도한대로 걸러지긴 했다!

 

강제하고자 했던 규칙

1. 이슈트래킹을 위해 제목의 맨 앞에 꼭 이슈 번호가 포함되어야함

2. 제목에 Type이 명시되어야함

3. 제목의 길이는 50자를 초과하면 안됨

4. 제목 다음엔 공백이 필수적으로 와야함

5. 본문의 길이는 72자를 초과하면 안됨

 

이외에, 커밋 메시지가 제목만 있을 경우 경고 메세지만 입력해주었다(굳이 설명이 없어도되는 커밋이 있을거라고 생각함)
참고) https://beomseok95.tistory.com/328

 

[Git] 좋은 커밋 메세지 작성하기위한 규칙들

좋은 커밋 메시지 작성하기 위한 규칙들 코드를 작성하면서 어려운것들중 하나는 이름을 어떻게 짓는지에 대한 고민 바로`Naming` 일 것입니다. 클래스, 함수, 변수 등등 많은 이름을 고민하지

beomseok95.tistory.com

 

이제 shell script로 각 항목들을 작성했다.

(script 실행 결과 0이 아닌 값을 return하면 커밋이 되지않기때문에, 오류로 취급할 값에 대해서은 1을 return해 줌)

먼저, 기본적으로 체크해줘야하는 부분에 대해서 작성했다.

BRANCH_NAME 은 나의 경우에는 branch 이름을 이슈 관리 번호로 주로 설정하기 때문에, 이슈번호를 메시지에 적기위해 받아두었다.

(밑에서 나오는 1) 규칙을 적용하지 않을 거라면 필요없음)

  • 주석 부분 삭제 : sed를 통해 시작부분(^)이 #인 라인 삭제함
  • 빈줄 삭제 : sed를 통해서 공백라인 삭제
  • 커밋 메시지 없는 경우 체크: 커밋메시지의 라인이 0인 경우가 커밋 메시지가 없은 경우로 체크
#!/bin/bash

COMMIT_EDITMSG=$1
BRANCH_NAME=$(git symbolic-ref --short HEAD)

# Remove comments
echo "$(sed -i -e '/^#.*/d' $COMMIT_EDITMSG)"

# Remove blank lines
echo "$(sed -i -e '/./,$!d' -e :a -e '/^\n*$/{$d;N;ba' -e '}' $COMMIT_EDITMSG)"

# Empty commit message
if [ "$(wc --l < $COMMIT_EDITMSG)" -eq 0 ]
then
	echo -e "\033[40;31mCommit failed:\033[0m Empty commit message."
	exit 1
fi

1) 이슈트래킹을 위해 제목의 맨 앞에 꼭 이슈 번호가 포함되어야함

커밋메시지 제목의 시작부분이 [이슈번호] 인지 체크하고, 아닐 경우 이슈번호인지 체크하고 [이슈번호]로 포멧팅 해주도록 작성했다. 사실 이슈번호 자체가 오타일 경우를 대비해서 정규표현식으로 체크해주면 어느정도 오타도 체크할 수 있을 것 같은데 오타라는게 어떻게 나올지도 모르고, 경우의 수를 모두 체크하기 복잡할 것같아서 커밋할 때 그냥 이슈번호를 아예 작성안하기로 스스로 결심했다. 그래서 사실 이슈번호로 시작하는 지 체크하는 것도 필요없을 것 같긴하다.

# Subject line should be contain Issue Number.
if ! [[ "$(head -n 1 $COMMIT_EDITMSG)" =~ ^"[$BRANCH_NAME]" ]]
then
	if [[ "$(head -n 1 $COMMIT_EDITMSG)" =~ ^"$BRANCH_NAME" ]]
	then
		echo -e "\033[40;33mCommit warning:\033[0m The Issue Number should be expressed in the form of [Jira Issue Number]."
		echo -e "\033[40;33mCommit warning:\033[0m Converted to the form of [Issue Number]."
		echo "$(sed -i -e "1s|$BRANCH_NAME|[$BRANCH_NAME]|g" $COMMIT_EDITMSG)"
	else
		echo -e "\033[40;33mCommit warning:\033[0m Subject line should be contain Issue Number."
		echo -e "\033[40;33mCommit warning:\033[0m Added [Issue Number].."
	echo "$(sed -i -e "1s/^/[$BRANCH_NAME] /" $COMMIT_EDITMSG)" 
	fi
fi

2) 제목에 Type이 명시되어야함

간단하다. 커밋메시지 파일의 첫번째 줄에 type에 해당하는 것이 몇 개(?) 들어있는지 체크하여 0 이면 에러 발생시켰다.

# Subject line should be contain what Type it is.
if [ "$(head -n 1 $COMMIT_EDITMSG | egrep -c '(\[+[feat|fix|docs|style|refactor|test|chore|etc]+\])' )" -eq 0 ]
then
	echo -e "\033[40;31mCommit failed:\033[0m Subject line should be contain what Type it is."
	exit 1
fi

3) 제목의 길이는 50자를 초과하면 안됨

간단히 wc를 통해 character 숫자를 체크했다.

# Subject line should be less than 50 characters.
if [ "$(head -n 1 $COMMIT_EDITMSG | wc -L)" -gt 50 ]
then
	echo -e "\033[40;31mCommit failed:\033[0m Subject line should be less than 50 characters."
	exit 1
fi​

4) 제목 다음엔 공백이 필수적으로 와야함
요게 좀 문제라면 문제인데, 커멧 메시지 파일의 2번째 줄이 공백이 아니면, 두번째 줄에 공백 삽입으로 하고 싶었는데 왜인지모르게 sed로 공백을 넣으면 아예 안들어가거나 두 줄씩 들어가길래, 아예 두 줄이 들어가게 두고 세번째 줄을 삭제하였다. 

# After subject line, line space is required.
if [ -n "$(sed -n '2p' $COMMIT_EDITMSG)" ]
then
	echo -e "\033[40;33mCommit warning:\033[0m After subject line, line space is required."
	echo -e "\033[40;33mCommit warning:\033[0m A line space is inserted after the subject line."
	echo "$(cat $COMMIT_EDITMSG | sed '1 a\\n')" > $COMMIT_EDITMSG
	echo "$(cat $COMMIT_EDITMSG | sed '2d')" > $COMMIT_EDITMSG 
fi

5) 본문의 길이는 72자를 초과하면 안됨

마찬가지로 wc 통해서 character 숫자 체크했다. 어쩌피 제목 50자는 위에서 체크했으니 그냥 커밋메시지 모든 라인에 대해서 수행했다.

# Every single description should be less than 72 characters. 
if [ "$(wc -L < $COMMIT_EDITMSG)" -gt 72 ]
then
	echo -e "\033[40;31mCommit failed:\033[0m Every single description should be less than 72 characters."
exit 1

 

'Git' 카테고리의 다른 글

[Git] Hooks 를 통한 Code  (0) 2022.09.19

+ Recent posts