xref: /rockchip-linux_mpp/tools/changelog.sh (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1#!/bin/bash
2## Author LinkinStar / HermanChen
3
4# solve the space by IFS
5OLDIFS=$IFS
6IFS=`echo -en "\n\b"`
7echo -en $IFS
8
9declare -g changelog_file="CHANGELOG.md"
10declare -g git_repo_rootdir
11declare -g current_tag
12declare -g previous_tag
13declare -g prev_changelog
14declare -g prev_changelog_version
15declare -g prev_tag
16declare -g curr_tag
17
18# changelog version define
19declare -g version_tag
20
21function log_filter_and_print() {
22    local title=$1
23    local prefix=$2
24    local -a msgs=()
25    local msg_cnt=0
26    local prefix_len=${#prefix}
27
28    # filter log and find the matched prefix number
29    for msg in ${orig_logs[@]}
30    do
31        if [[ $msg == "$prefix"* ]]; then
32            msgs[msg_cnt]=$msg
33            let msg_cnt++
34
35            echo "$prefix commit $msg_cnt - ${msg}"
36        fi
37    done
38
39    if [ $msg_cnt -gt 0 ]; then
40        echo -e "### $title" >> ${changelog_file}
41
42        for msg in ${msgs[@]}
43        do
44            # check log mode
45            local pos=$prefix_len
46            local log
47
48            # message mode: prefix: xxxx
49            log=$(echo $msg | grep -i "^$prefix:")
50            #echo "pos $pos log $log"
51            if [ "$log" != "" ]; then
52                let pos++
53            fi
54
55            # remove extra space
56            log=$(echo ${msg:$pos} | sed -e 's/^[ ]*//g' | sed -e 's/[ ]*$//g')
57            echo -e "- $log" >> ${changelog_file}
58        done
59
60        echo -e "" >> ${changelog_file}
61    fi
62}
63
64usage="changelog helper script
65  use -t / --version to create a new tag commit and update CHANGELOG.md
66  by insert new version on top,
67
68  the basic commit message should be structured as follows:
69  <type>[optional scope]: <description>
70  [optional body]
71  [optional footer(s)]
72
73  Type
74  Must be one of the following:
75  feat: A new feature
76  fix: A bug fix
77  docs: Documentation only changes
78  style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
79  refactor: A code change that neither fixes a bug nor adds a feature
80  perf: A code change that improves performance
81  test: Adding missing or correcting existing tests
82  chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
83
84  https://www.conventionalcommits.org/zh-hans/v1.0.0/
85
86  .option('-t, --version', 'create a version tag with changelog update')
87  .option('-f, --file [file]', 'file to write to, defaults to ./CHANGELOG.md, use - for stdout', './CHANGELOG.md')
88  .option('-u, --repo-url [url]', 'specify the repo URL for commit links')
89"
90
91while [ $# -gt 0 ]; do
92    case $1 in
93        --help | -h)
94            echo "$usage"
95            exit 1
96            ;;
97        --version | -t)
98            version_tag=$2
99            shift
100            ;;
101        --file | -f)
102            changelog_file=$2
103            echo "save changelog to file ${changelog_file}"
104            shift
105            ;;
106        --repo-url | -u)
107            git_repo_rootdir=$2
108            echo "set repo rootdir to ${git_repo_rootdir}"
109            shift
110            ;;
111        *)
112            # skip invalid option
113            shift
114            ;;
115    esac
116    shift
117done
118
119# check git command
120if ! command -v git >/dev/null; then
121    >&2 echo "ERROR: git command is not available"
122    echo "$usage"
123    exit 1
124fi
125
126# if repo root is not set set sefault repo root
127if [ -z $git_repo_rootdir ]; then
128    git_repo_rootdir=$(git rev-parse --show-toplevel 2>/dev/null)
129fi
130
131# check repo root valid or not
132if [ -z ${git_repo_rootdir} ] || [ ! -d ${git_repo_rootdir} ]; then
133    echo "ERROR: can not found repo root"
134    echo "$usage"
135    exit 1
136fi
137
138# cd to rootdir
139cd $git_repo_rootdir
140
141# check version tag exist or not
142if [ -z ${version_tag} ]; then
143    echo "ERROR: can not run without a new version tag"
144    echo "$usage"
145    exit 1
146fi
147
148tag_log=$(git tag -v ${version_tag} | grep object)
149if [ ! -z ${tag_log} ]; then
150    echo "ERROR: can not run with an existing tag ${version_tag}"
151    echo "$usage"
152    exit 1
153fi
154
155# create new tag with empty commit
156git commit --allow-empty -s -m "docs: Update ${version_tag} CHANGELOG.md"
157tag_date=`date '+%Y-%m-%d'`
158git tag ${version_tag} -m "${version_tag} version at ${tag_date}"
159
160# if changelog file is not exist then create it
161if [[ ! -f ${changelog_file} ]]; then
162    touch ${changelog_file}
163else
164    # get old changelog
165    prev_changelog=$(cat $changelog_file)
166    prev_changelog_version=$(echo $prev_changelog | grep -E "## *.*.* *" | head -1 | awk '{ print $2 }')
167
168    rm -rf ${changelog_file}
169    touch ${changelog_file}
170fi
171
172# get current version info
173curr_ver=$(git describe --tags --long)
174curr_tag=$(git describe --tags --abbrev=0)
175prev_tag=$(git describe --tags --abbrev=0 "$curr_tag"^)
176date="$(date '+%Y-%m-%d')"
177
178echo "curr ver: ${curr_ver}"
179echo "curr tag: ${curr_tag}"
180echo "prev tag: ${prev_tag}"
181
182# dump log between two tags
183orig_logs=$(git log --pretty="%s" --no-merges $curr_tag...$prev_tag)
184echo "commits: from ${prev_tag} to ${curr_tag}"
185echo "${orig_logs}"
186
187# check unreleased version number
188unreleased_count=$(echo ${curr_ver} | grep -E "## *.*.* *" | head -1 | awk -F "-" '{ printf $2 }')
189echo "unreleased version count: ${unreleased_count}"
190
191# write unreleased information
192if [ "$unreleased_count" ] && [ $unreleased_count -gt 0 ]; then
193    echo -e "## Unreleased (${date})\n" >> ${changelog_file}
194
195    unreleased_logs=$(git log --pretty="%s" --no-merges HEAD...$curr_tag)
196    for msg in ${unreleased_logs[@]}
197    do
198        echo -e "- ${msg}" >> ${changelog_file}
199    done
200
201    echo -e "" >> ${changelog_file}
202else
203    echo -e "## $curr_tag ($date)" >> ${changelog_file}
204fi
205
206# write taged information
207log_filter_and_print "Feature"  "feat"
208log_filter_and_print "Fix"      "fix"
209log_filter_and_print "Docs"     "docs"
210log_filter_and_print "Style"    "Style"
211log_filter_and_print "Refactor" "refactor"
212log_filter_and_print "Perf"     "perf"
213log_filter_and_print "Test"     "test"
214log_filter_and_print "Chore"    "chore"
215
216echo -e "${prev_changelog}" >> ${changelog_file}
217
218# add CHANGELOG.md
219git add ${changelog_file}
220git commit --amend -C ${curr_ver}
221# update tag message
222git tag -f ${version_tag} -m "${version_tag} version at ${tag_date}"
223
224IFS=$OLDIFS
225