docs: 에이전트 작업 가이드 및 검증 스크립트 추가
This commit is contained in:
121
work/check-commit-message-rules.sh
Executable file
121
work/check-commit-message-rules.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
print_usage() {
|
||||
echo "Usage:"
|
||||
echo " $0"
|
||||
echo " $0 <commit-hash>"
|
||||
echo " $0 --message \"<commit-message>\""
|
||||
echo " $0 --message-file <file-path>"
|
||||
}
|
||||
|
||||
load_commit_message() {
|
||||
if [ $# -eq 0 ]; then
|
||||
local commit_ref="HEAD"
|
||||
echo "Checking latest commit..." >&2
|
||||
git log -1 --pretty=format:"%s%n%b" "$commit_ref"
|
||||
return
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
--message)
|
||||
shift
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "[FAIL] --message option requires a commit message"
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
echo "Checking provided commit message..." >&2
|
||||
printf '%s' "$*"
|
||||
;;
|
||||
--message-file)
|
||||
shift
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "[FAIL] --message-file option requires a file path"
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$1" ]; then
|
||||
echo "[FAIL] Commit message file not found: $1"
|
||||
exit 1
|
||||
fi
|
||||
echo "Checking commit message file: $1" >&2
|
||||
cat "$1"
|
||||
;;
|
||||
*)
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "[FAIL] Invalid arguments"
|
||||
print_usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local commit_ref="$1"
|
||||
if ! git rev-parse --verify "$commit_ref^{commit}" >/dev/null 2>&1; then
|
||||
echo "[FAIL] Invalid commit reference: $commit_ref"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Checking commit: $commit_ref" >&2
|
||||
git log -1 --pretty=format:"%s%n%b" "$commit_ref"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
commit_message=$(load_commit_message "$@")
|
||||
subject=$(printf '%s\n' "$commit_message" | head -n1)
|
||||
body=$(printf '%s\n' "$commit_message" | tail -n +2)
|
||||
|
||||
echo "Checking commit message format..."
|
||||
echo "Subject: $subject"
|
||||
|
||||
exit_code=0
|
||||
|
||||
if [ -z "$subject" ]; then
|
||||
echo "[FAIL] Subject must not be empty"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
subject_pattern='^([a-z]+)(\([a-z0-9._/-]+\))?(!)?: (.+)$'
|
||||
if [[ "$subject" =~ $subject_pattern ]]; then
|
||||
type="${BASH_REMATCH[1]}"
|
||||
description="${BASH_REMATCH[4]}"
|
||||
|
||||
echo "[PASS] Subject follows Conventional Commit format"
|
||||
echo "[PASS] Type is lowercase: $type"
|
||||
|
||||
if printf '%s\n' "$description" | grep -Eq '[가-힣]'; then
|
||||
echo "[PASS] Description contains Korean text"
|
||||
else
|
||||
echo "[FAIL] Description must contain Korean text"
|
||||
exit_code=1
|
||||
fi
|
||||
else
|
||||
echo "[FAIL] Subject must match: <type>(scope): <description>"
|
||||
echo " scope is optional, example: feat: 기능을 추가한다"
|
||||
exit_code=1
|
||||
fi
|
||||
|
||||
if [ -n "$body" ] && printf '%s\n' "$body" | grep -Eq '^Refs:'; then
|
||||
while IFS= read -r refs_line; do
|
||||
if ! printf '%s\n' "$refs_line" | grep -Eq '^Refs: #[0-9]+(, #[0-9]+)*$'; then
|
||||
echo "[FAIL] Refs footer format is invalid: $refs_line"
|
||||
echo " expected format: Refs: #123 or Refs: #123, #456"
|
||||
exit_code=1
|
||||
fi
|
||||
done < <(printf '%s\n' "$body" | grep -E '^Refs:')
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo "[PASS] Refs footer format is valid"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $exit_code -eq 0 ]; then
|
||||
echo "[PASS] Commit message follows AGENTS.md rules"
|
||||
else
|
||||
echo "[FAIL] Commit message violates AGENTS.md rules"
|
||||
fi
|
||||
|
||||
exit $exit_code
|
||||
Reference in New Issue
Block a user