Repository navigation
Expand file tree
/
Copy pathcommit-msg.bash
More file actions
executable file
·103 lines (83 loc) · 4.35 KB
/
Copy pathcommit-msg.bash
File metadata and controls
executable file
·103 lines (83 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env bash
# Get the commit message file path from the first argument
commit_msg_file="$1"
# Read the commit message
commit_msg=$(cat "$commit_msg_file")
# Colors for output
red='\033[0;31m'
yellow='\033[1;33m'
no_color='\033[0m'
# Get the first line (subject)
subject=$(echo "$commit_msg" | head -n1)
# Get the second line
second_line=$(echo "$commit_msg" | sed -n '2p')
# Get the third line
third_line=$(echo "$commit_msg" | sed -n '3p')
# Get the rest of the message (body)
body=$(echo "$commit_msg" | tail -n +4)
# Check subject length (max 80 characters)
if [ ${#subject} -gt 80 ]; then
echo -e "${yellow}Warning: Commit message subject is too long (max 80 characters)${no_color}"
echo -e "Current length: ${#subject} characters"
fi
# Check if second line is blank
if [ ! -z "$second_line" ]; then
echo -e "${yellow}Warning: Second line should be blank${no_color}"
fi
# Check third line format
if [ ! -z "$third_line" ]; then
if [[ "$third_line" =~ ^(refs|ref:) ]]; then
echo -e "${red}Error: Third line should not start with 'refs' or 'ref:'${no_color}" >&2
echo -e "Use a supported keyword like 'ref', 'close', 'fixes', 'related to', or 'contributes to' followed by an issue link (or 'no ref')" >&2
echo -e "${yellow}Press Enter to edit the message...${no_color}" >&2
read < /dev/tty # Wait for Enter key press from the terminal
# Get the configured Git editor
editor=$(git var GIT_EDITOR)
if [ -z "$editor" ]; then
editor=${VISUAL:-${EDITOR:-vi}} # Fallback logic similar to Git
fi
# Re-open the editor on the commit message file, connected to the terminal
$editor "$commit_msg_file" < /dev/tty
# Re-read the potentially modified commit message after editing
commit_msg=$(cat "$commit_msg_file")
# Need to update related variables as well
subject=$(echo "$commit_msg" | head -n1)
second_line=$(echo "$commit_msg" | sed -n '2p')
third_line=$(echo "$commit_msg" | sed -n '3p')
body=$(echo "$commit_msg" | tail -n +4)
# Re-check the third line *again* after editing
if [[ "$third_line" =~ ^(refs|ref:) ]]; then
echo -e "${red}Error: Third line still starts with 'refs' or 'ref:'. Commit aborted.${no_color}" >&2
exit 1 # Abort commit if still invalid
fi
# If fixed, the script will continue to the next checks
fi
if ! [[ "$third_line" =~ ^(close|closes|closed|closing|fix|fixes|fixed|fixing|resolve|resolves|resolved|resolving|complete|completes|completed|completing|ref|references|part\ of|related\ to|contributes\ to|towards)\ .*$ ]] \
&& ! [[ "$third_line" == "no ref" ]]; then
echo -e "${yellow}Warning: Third line should start with a supported issue-link keyword (for example: 'ref', 'close', 'fixes', 'related to', or 'contributes to') or be 'no ref'${no_color}" >&2
fi
fi
# Check for body content (why explanation)
if [ -z "$body" ]; then
echo -e "${yellow}Warning: Missing explanation of why this change was made${no_color}"
echo -e "The body should explain: why this, why now, why not something else?"
fi
# Give concise release-note guidance. Whether a change is user-facing requires
# human judgment, so these notices are informative rather than enforcement.
first_word="${subject%% *}"
contributor_emojis="✨ 🎨 🐛 🌐 💡"
if [[ "$first_word" =~ ^(✨|🎨|🐛|🌐|💡|🔒)$ ]]; then
echo -e "${yellow}Notice: Keep the emoji only for a significant user-facing PR title or squash commit.${no_color}"
elif [[ -n "$(printf '%s' "$first_word" | LC_ALL=C tr -d '\000-\177')" ]]; then
echo -e "${yellow}Warning: Unsupported leading emoji. Use one of: ${contributor_emojis}${no_color}"
echo -e "Emoji selection only matters for user-facing PR titles and squash commits."
else
echo -e "${yellow}Notice: If this is a significant user-facing PR title or squash commit, add one of: ${contributor_emojis}${no_color}"
fi
# Check for past tense verbs in subject
past_tense_words="Fixed|Changed|Updated|Improved|Added|Removed|Reverted|Moved|Released|Bumped|Cleaned"
if ! echo "$subject" | grep -iE "$past_tense_words" > /dev/null; then
echo -e "${yellow}Warning: Subject line should use past tense${no_color}"
echo -e "Use one of: Fixed, Changed, Updated, Improved, Added, Removed, Reverted, Moved, Released, Bumped, Cleaned"
fi
exit 0