🐚
shell スクリプトで頑張って semantic commit を実現する
はじめに
皆様コミットメッセージの規約は何を採用していますでしょうか?
Conventional Commits が有名だと思いますが、今のプロジェクトでは Semantic Commit Messages を採用しています。
これを shell スクリプトで楽してコミットメッセージを作ろうって魂胆です。
ちなみにコードはほとんど Chat-GPT(GPT4) で生成しています。
正直な話
git-cz とか commitizen をカスタマイズなりして使う方が良いです。
導入するのが政治的にめんどくさそうなので、git 管理外でよしなにする感じです。。
正直もうちょっといい方法がありそうな気はしています。
(コミットテンプレートとかでよしなにできないか・・・とかなんとか)
完成図
実行すると以下のようになります。
手順
- 任意の場所にシェルスクリプトファイルを作成します
# サンプルでは home ディレクトリに commit.sh というファイル名で作成します
cd ~
touch commit.sh
# 作成時は各種権限がないので追加します
chmod 777 ./commit.sh
- 任意のエディタで
~/commit.sh
を開き、以下の内容を貼り付けます
#!/bin/bash
# color
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
NC='\033[0m'
# 許可された type と scope の定義
types=(
"feat: ユーザー向けの新機能であり、ビルドスクリプトの新機能ではない"
"fix: ビルドスクリプトの修正ではなく、ユーザーのためのバグ修正"
"docs: ドキュメントの変更"
"style: 書式設定、セミコロンの欠落など"
"refactor: プロダクションコードのリファクタリング"
"test: 不足しているテストの追加、テストのリファクタリング"
"chore: gruntタスクの更新など、プロダクションコードの変更なし"
"update: node module をアップデート"
"spike: spike コミット(コメントあり)"
"spike-no-comment: spike コミット(コメントなし)"
)
# コンソールの履歴を削除
clear
# ステージされた変更がなければキャンセル
if [ -z "$(git diff --cached --shortstat 2> /dev/null)" ]; then
printf "${RED}コミットする変更がありません${NC}\n"
exit 1
fi
# ステージされた変更の表示
echo "ステージされた変更:"
printf "${GREEN}$(git diff --name-only --cached)${NC}\n"
# type の入力
PS3="Commit Type: "
select typeKey in "${types[@]}"; do
if [[ -n "$typeKey" ]]; then
type=$(echo $typeKey | cut -d: -f1)
printf "${BLUE}Selected Type: $(echo $type)${NC}\n"
break;
else
printf "${RED}Invalid selection${NC}\n"
exit 1
fi
done
# subject の入力(spike コミットのコメント無しの場合は省略)
if [ "$type" != "spike-no-comment" ]; then
while true; do
echo "Commit Subject:"
read -e subject
#
if [ -z "$subject" ]; then
printf "${YELLOW}コミットメッセージは空欄にできません。再度入力してください。${NC}\n"
else
break
fi
done
else
subject=""
fi
# コミットメッセージの生成
message="$type"
if [[ -n "$scope" ]]; then
message+="($scope)"
fi
if [[ -n "$subject" ]]; then
message+=": $subject"
fi
# pre-commit のチェックをスキップするかどうか
verify=""
if [[ "$type" == "spike" || "$type" == "spike-no-comment" ]]; then
# spike コミットの場合はチェックをスキップ
verify="--no-verify"
else
read -e -p "コミット前のチェックを省略しますか? (初期値: 省略しない) [y/n] " answer
if [[ "$answer" = "y" ]]; then
verify="--no-verify"
fi
fi
# 最終的なコミットメッセージをコンソールに表示(pre-commit のチェックに失敗したとき用)
printf "${BLUE}Commit Message --------------------------------------------${NC}\n"
printf "git commit -m '$message' $verify\n"
printf "${BLUE}-----------------------------------------------------------${NC}\n"
# コミットの実行
echo -e $message | git commit -F - $verify
- コマンド実行用にエイリアスを設定します
echo -e "alias commit='~/commit.sh'" >> ~/.bashrc
- 設定内容を更新
source ~/.bashrc
以上!
使い方
commit したいプロジェクト(ディレクトリ)で commit
と実行すれば作成したシェルが実行されます。
- ステージされている変更がない場合はコミットされずにキャンセルします
-
type
やscope
は左側に表示されている数字を入力します
正しく入力できればSelected Type: feat
のように表示されます
-
scope
に何も指定しない場合は4
(none: 未選択) を入力してください -
subject
は必須です
空のまま enter キーを押下すると再度入力をもとめられます -
detail
はオプションです
入力しない場合は空のまま enter キーを押下してください
余談
つけようとおもったけどつけなかった機能
よくある確認する系のスクリプトですが、いちいち y
を入力するのが面倒だったのでなくしました。
コミットに厳格なプロジェクトとかだと追加して良いかもです。
read -p "Are you sure you want to commit these changes? [y/n] " answer
if [[ "$answer" != "y" ]]; then
echo "Commit cancelled."
exit
fi
Discussion