2023-07-24 09:52:21 +08:00
|
|
|
#!/bin/bash
|
|
|
|
## Author LinkinStar / HermanChen
|
|
|
|
|
|
|
|
# solve the space by IFS
|
|
|
|
OLDIFS=$IFS
|
|
|
|
IFS=`echo -en "\n\b"`
|
|
|
|
echo -en $IFS
|
|
|
|
|
|
|
|
declare -g changelog_file="CHANGELOG.md"
|
|
|
|
declare -g git_repo_rootdir
|
|
|
|
declare -g current_tag
|
|
|
|
declare -g previous_tag
|
|
|
|
declare -g prev_changelog
|
|
|
|
declare -g prev_changelog_version
|
|
|
|
declare -g prev_tag
|
|
|
|
declare -g curr_tag
|
|
|
|
|
|
|
|
# changelog version define
|
2023-10-31 10:42:46 +08:00
|
|
|
declare -g version_tag
|
2023-07-24 09:52:21 +08:00
|
|
|
|
|
|
|
function log_filter_and_print() {
|
|
|
|
local title=$1
|
|
|
|
local prefix=$2
|
|
|
|
local -a msgs=()
|
|
|
|
local msg_cnt=0
|
|
|
|
local prefix_len=${#prefix}
|
|
|
|
|
|
|
|
# filter log and find the matched prefix number
|
|
|
|
for msg in ${orig_logs[@]}
|
|
|
|
do
|
|
|
|
if [[ $msg == "$prefix"* ]]; then
|
|
|
|
msgs[msg_cnt]=$msg
|
|
|
|
let msg_cnt++
|
|
|
|
|
|
|
|
echo "$prefix commit $msg_cnt - ${msg}"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ $msg_cnt -gt 0 ]; then
|
|
|
|
echo -e "### $title" >> ${changelog_file}
|
|
|
|
|
|
|
|
for msg in ${msgs[@]}
|
|
|
|
do
|
|
|
|
# check log mode
|
|
|
|
local pos=$prefix_len
|
|
|
|
local log
|
|
|
|
|
|
|
|
# message mode: prefix: xxxx
|
|
|
|
log=$(echo $msg | grep -i "^$prefix:")
|
|
|
|
#echo "pos $pos log $log"
|
|
|
|
if [ "$log" != "" ]; then
|
|
|
|
let pos++
|
|
|
|
fi
|
|
|
|
|
|
|
|
# remove extra space
|
|
|
|
log=$(echo ${msg:$pos} | sed -e 's/^[ ]*//g' | sed -e 's/[ ]*$//g')
|
|
|
|
echo -e "- $log" >> ${changelog_file}
|
|
|
|
done
|
|
|
|
|
|
|
|
echo -e "" >> ${changelog_file}
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
usage="changelog helper script
|
2023-10-31 10:42:46 +08:00
|
|
|
use -t / --version to create a new tag commit and update CHANGELOG.md
|
|
|
|
by insert new version on top,
|
|
|
|
|
2023-07-24 09:52:21 +08:00
|
|
|
the basic commit message should be structured as follows:
|
|
|
|
<type>[optional scope]: <description>
|
|
|
|
[optional body]
|
|
|
|
[optional footer(s)]
|
|
|
|
|
|
|
|
Type
|
|
|
|
Must be one of the following:
|
|
|
|
feat: A new feature
|
|
|
|
fix: A bug fix
|
|
|
|
docs: Documentation only changes
|
|
|
|
style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
|
|
|
refactor: A code change that neither fixes a bug nor adds a feature
|
|
|
|
perf: A code change that improves performance
|
|
|
|
test: Adding missing or correcting existing tests
|
|
|
|
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
|
|
|
|
|
|
|
|
https://www.conventionalcommits.org/zh-hans/v1.0.0/
|
|
|
|
|
2023-10-31 10:42:46 +08:00
|
|
|
.option('-t, --version', 'create a version tag with changelog update')
|
|
|
|
.option('-f, --file [file]', 'file to write to, defaults to ./CHANGELOG.md, use - for stdout', './CHANGELOG.md')
|
|
|
|
.option('-u, --repo-url [url]', 'specify the repo URL for commit links')
|
2023-07-24 09:52:21 +08:00
|
|
|
"
|
|
|
|
|
|
|
|
while [ $# -gt 0 ]; do
|
|
|
|
case $1 in
|
|
|
|
--help | -h)
|
|
|
|
echo "$usage"
|
|
|
|
exit 1
|
|
|
|
;;
|
2023-10-31 10:42:46 +08:00
|
|
|
--version | -t)
|
|
|
|
version_tag=$2
|
2023-07-24 09:52:21 +08:00
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--file | -f)
|
|
|
|
changelog_file=$2
|
|
|
|
echo "save changelog to file ${changelog_file}"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
--repo-url | -u)
|
|
|
|
git_repo_rootdir=$2
|
|
|
|
echo "set repo rootdir to ${git_repo_rootdir}"
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
# skip invalid option
|
|
|
|
shift
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
|
|
|
# check git command
|
|
|
|
if ! command -v git >/dev/null; then
|
|
|
|
>&2 echo "ERROR: git command is not available"
|
2023-10-31 10:42:46 +08:00
|
|
|
echo "$usage"
|
2023-07-24 09:52:21 +08:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# if repo root is not set set sefault repo root
|
|
|
|
if [ -z $git_repo_rootdir ]; then
|
|
|
|
git_repo_rootdir=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
|
|
fi
|
|
|
|
|
|
|
|
# check repo root valid or not
|
|
|
|
if [ -z ${git_repo_rootdir} ] || [ ! -d ${git_repo_rootdir} ]; then
|
|
|
|
echo "ERROR: can not found repo root"
|
2023-10-31 10:42:46 +08:00
|
|
|
echo "$usage"
|
2023-07-24 09:52:21 +08:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# cd to rootdir
|
|
|
|
cd $git_repo_rootdir
|
|
|
|
|
2023-10-31 10:42:46 +08:00
|
|
|
# check version tag exist or not
|
|
|
|
if [ -z ${version_tag} ]; then
|
|
|
|
echo "ERROR: can not run without a new version tag"
|
|
|
|
echo "$usage"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
tag_log=$(git tag -v ${version_tag} | grep object)
|
|
|
|
if [ ! -z ${tag_log} ]; then
|
|
|
|
echo "ERROR: can not run with an existing tag ${version_tag}"
|
|
|
|
echo "$usage"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# create new tag with empty commit
|
|
|
|
git commit --allow-empty -s -m "docs: Update ${version_tag} CHANGELOG.md"
|
|
|
|
tag_date=`date '+%Y-%m-%d'`
|
|
|
|
git tag ${version_tag} -m "${version_tag} version at ${tag_date}"
|
|
|
|
|
2023-07-24 09:52:21 +08:00
|
|
|
# if changelog file is not exist then create it
|
|
|
|
if [[ ! -f ${changelog_file} ]]; then
|
|
|
|
touch ${changelog_file}
|
|
|
|
else
|
|
|
|
# get old changelog
|
|
|
|
prev_changelog=$(cat $changelog_file)
|
|
|
|
prev_changelog_version=$(echo $prev_changelog | grep -E "## *.*.* *" | head -1 | awk '{ print $2 }')
|
|
|
|
|
|
|
|
rm -rf ${changelog_file}
|
|
|
|
touch ${changelog_file}
|
|
|
|
fi
|
|
|
|
|
|
|
|
# get current version info
|
|
|
|
curr_ver=$(git describe --tags --long)
|
|
|
|
curr_tag=$(git describe --tags --abbrev=0)
|
|
|
|
prev_tag=$(git describe --tags --abbrev=0 "$curr_tag"^)
|
|
|
|
date="$(date '+%Y-%m-%d')"
|
|
|
|
|
|
|
|
echo "curr ver: ${curr_ver}"
|
|
|
|
echo "curr tag: ${curr_tag}"
|
|
|
|
echo "prev tag: ${prev_tag}"
|
|
|
|
|
|
|
|
# dump log between two tags
|
|
|
|
orig_logs=$(git log --pretty="%s" --no-merges $curr_tag...$prev_tag)
|
|
|
|
echo "commits: from ${prev_tag} to ${curr_tag}"
|
|
|
|
echo "${orig_logs}"
|
|
|
|
|
|
|
|
# check unreleased version number
|
|
|
|
unreleased_count=$(echo ${curr_ver} | grep -E "## *.*.* *" | head -1 | awk -F "-" '{ printf $2 }')
|
|
|
|
echo "unreleased version count: ${unreleased_count}"
|
|
|
|
|
|
|
|
# write unreleased information
|
|
|
|
if [ "$unreleased_count" ] && [ $unreleased_count -gt 0 ]; then
|
|
|
|
echo -e "## Unreleased (${date})\n" >> ${changelog_file}
|
|
|
|
|
|
|
|
unreleased_logs=$(git log --pretty="%s" --no-merges HEAD...$curr_tag)
|
|
|
|
for msg in ${unreleased_logs[@]}
|
|
|
|
do
|
|
|
|
echo -e "- ${msg}" >> ${changelog_file}
|
|
|
|
done
|
|
|
|
|
|
|
|
echo -e "" >> ${changelog_file}
|
|
|
|
else
|
|
|
|
echo -e "## $curr_tag ($date)" >> ${changelog_file}
|
|
|
|
fi
|
|
|
|
|
|
|
|
# write taged information
|
|
|
|
log_filter_and_print "Feature" "feat"
|
|
|
|
log_filter_and_print "Fix" "fix"
|
|
|
|
log_filter_and_print "Docs" "docs"
|
|
|
|
log_filter_and_print "Style" "Style"
|
|
|
|
log_filter_and_print "Refactor" "refactor"
|
|
|
|
log_filter_and_print "Perf" "perf"
|
|
|
|
log_filter_and_print "Test" "test"
|
|
|
|
log_filter_and_print "Chore" "chore"
|
|
|
|
|
|
|
|
echo -e "${prev_changelog}" >> ${changelog_file}
|
|
|
|
|
2023-10-31 10:42:46 +08:00
|
|
|
# add CHANGELOG.md
|
|
|
|
git add ${changelog_file}
|
|
|
|
git commit --amend -C ${curr_ver}
|
2023-12-08 15:49:39 +08:00
|
|
|
# update tag message
|
|
|
|
git tag -f ${version_tag} -m "${version_tag} version at ${tag_date}"
|
2023-10-31 10:42:46 +08:00
|
|
|
|
2023-07-24 09:52:21 +08:00
|
|
|
IFS=$OLDIFS
|