From b583fa54a61792a0ea3914d5d9954846c3bb8957 Mon Sep 17 00:00:00 2001 From: Rick Barenthin Date: Mon, 23 May 2022 04:13:41 +0200 Subject: [PATCH] feat(scripts): changelog script --- scripts/changelog.sh | 138 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100755 scripts/changelog.sh diff --git a/scripts/changelog.sh b/scripts/changelog.sh new file mode 100755 index 0000000..0cf190a --- /dev/null +++ b/scripts/changelog.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env sh + +config_file=.version.json + +reverse() { + if which tac >/dev/null 2>&1; then + tac + else + tail -r + fi +} + +generate_config() { + sha="$(git rev-parse --short HEAD)" + ( + echo '{' + echo '"version": "0.0.0",' + echo '"sha": "'"$sha"'"' + echo '}' + ) | jq . > $config_file +} + +get_git_commits() { + since_hash="$(jq '.sha' < $config_file | tr -d '"')" + git rev-list "$since_hash..HEAD" +} + +get_git_commit_subject() { + git show -s --format=%s "$1" +} + +get_git_commit_body() { + git show -s --format=%b "$1" +} + +get_commit_type() { + echo "$1" | sed -r -n 's/([a-z]+)(\(?|:?).*/\1/p' +} + +get_commit_scope() { + echo "$1" | sed -r -n 's/[a-z]+\(([^)]+)\).*/\1/p' +} + +get_commit_description() { + echo "$1" | sed -r -n 's/.*:[ ]+(.*)/\1/p' +} + +get_commit_footer() { + with_colon=$(echo "$1" | sed -n '/^[A-Za-z-]\{1,\}: /,//{p;}') + with_hash=$(echo "$1" | sed -n '/^[A-Za-z-]\{1,\} #/,//{p;}') + + if [ ${#with_colon} -gt ${#with_hash} ]; then + echo "$with_colon" + else + echo "$with_hash" + fi +} + +get_commit_body() { + pattern=$(get_commit_footer "$1" | head -n 1) + if [ -n "$pattern" ]; then + echo "$1" | sed -e "/$pattern/,\$d" + else + echo "$1" + fi +} + +is_breaking_change() { + if echo "$1" | grep -q '!' || echo "$2" | grep -q 'BREAKING[ -]CHANGE: '; then + echo "yes" + else + echo "no" + fi +} + +get_breaking_change() { + with_colon=$(echo "$1" | sed -n '/^BREAKING[ -]CHANGE: /,/^[A-Za-z-]\{1,\}: /{ s/BREAKING[ -]CHANGE: \(.*\)/\1/; /^[A-Za-z-]\{1,\}: /!p;}') + with_hash=$(echo "$1" | sed -n '/^BREAKING[ -]CHANGE: /,/^[A-Za-z-]\{1,\} #/{ s/BREAKING[ -]CHANGE: \(.*\)/\1/; /^[A-Za-z-]\{1,\} #/!p;}') + if [ -n "$with_colon" ] && ! echo "$with_colon" | grep -q '[A-Za-z-]\{1,\} #'; then + echo "$with_colon" + else + echo "$with_hash" + fi +} + +generate_changelog_entry() { + is_patch=0 + is_minor=0 + is_major=0 + for commit in $(get_git_commits); do + git_subject=$(get_git_commit_subject "$commit") + git_body=$(get_git_commit_body "$commit") + + type=$(get_commit_type "$git_subject") + scope=$(get_commit_scope "$git_subject") + description=$(get_commit_description "$git_subject") + body=$(get_commit_body "$git_body") + footer=$(get_commit_footer "$git_body") + breakingchange=$(get_breaking_change "$footer") + isbreaking=$(is_breaking_change "$git_subject" "$footer") + if [ "$isbreaking" = "yes" ] && [ -z "$breakingchange" ]; then + breakingchange="$body" + fi + + echo "--------------------------------" + echo "Subject : $git_subject" + echo "Body: $git_body" + echo + echo "********************************" + echo + echo " - type : $type" + echo " - scope : $scope" + echo " - description : $description" + echo " - body : $body" + echo " - footer : $footer" + echo " - breakingchange : $breakingchange" + echo " - isbreaking : $isbreaking" + echo + echo "--------------------------------" + echo + echo + done; +} + + +init() { + if [ ! -f "$config_file" ]; then + echo "Generating a config ... " + generate_config + echo "Done" + else + echo "Using existing config" + fi + + generate_changelog_entry +} + +init \ No newline at end of file