I'm trying to write a commit-msg
hook for my git
project that checks if commit message accord with a particular style guide. However, it looks like something works differently into the bash
world regarding regexp. How could I accomplish my goal?
#!/usr/bin/env bash
read -r -d '' pattern << EOM
(?x) # Enable comments and whitespace insensitivity.
^ # Starting from the very beginning of the message
(feat|fix|docs|style|refactor|test|chore) # should be a type which might be one of the listed,
:[ ] # the type should be followed by a colon and whitespace,
(.{1,50})\n # then goes a subject that is allowed to be 50 chars long at most,
(?:\n((?:.{0,80}\n)+))? # then after an empty line goes optional body each line of which
# may not exceed 80 characters length.
$ # The body is considered everything until the end of the message.
EOM
message=$(cat "${1}")
if [[ ${message} =~ ${pattern} ]]; then
exit 0
else
error=$(tput setaf 1)
normal=$(tput sgr0)
echo "${error}The commit message does not accord with the style guide that is used on the project.${normal}"
echo "For more details see https://udacity.github.io/git-styleguide/"
exit 1
fi
I also tried writing this regexp in oneline, like as:
pattern="^(feat|fix|docs|style|refactor|test|chore):[ ](.{1,50})\n(?:\n((?:.{0,80}\n)+))?$"
And even tryed replacing \n
with $'\n'
but it didn't helped.
\n
with$'\n'
("^(feat|fix|docs|style|refactor|test|chore):"$'\s'"(.{1,50})"$'\n'"("$'\n'"((.{0,80}"$'\n'")+))?$"
). Now it works for multiline text inlined in variable when replace themessage
with an actual value but doesn't work withmessage=$(cat ${file_name})
. Could you, please, advise on it? – Denis Verhoturov Sep 20 '19 at 17:43"^(feat|fix|docs|style|refactor|test|chore):[ ](.{1,50})("$'\n'"("$'\n'"[^"$'\n'"]{0,80})+)?$"
- everything works fine now=) – Denis Verhoturov Sep 20 '19 at 18:48\n
. The command substitution inmessage=$(cat filename)
would remove all trailing newlines from the value, which might affect your original regex – ilkkachu Sep 20 '19 at 23:29