git-release 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'git_release/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "git-release"
8
+ spec.version = GitRelease::VERSION
9
+ spec.authors = ["Tom Meier"]
10
+ spec.email = ["tom@venombytes.com"]
11
+ spec.description = %q{Changelog and release tag generator from GIT}
12
+ spec.summary = %q{Generate changelog from git commits and tag your release versions}
13
+ spec.homepage = "http://github.com/tommeier/git-release"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1 @@
1
+ require "git_release/version"
@@ -0,0 +1,3 @@
1
+ module GitRelease
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,200 @@
1
+ #!/bin/bash -e
2
+
3
+ ############################################################
4
+ ##### CHANGELOG FUNCTIONS #####
5
+ ############################################################
6
+
7
+ get_current_release_date() {
8
+ echo $( date "+%A %d %B, %Y %l:%M%p" )
9
+ }
10
+
11
+ changelog_divider() {
12
+ echo "+=========================================================+"
13
+ }
14
+
15
+ changelog_footer() {
16
+ local output=""
17
+ ! read -d '' output <<"EOF"
18
+ || _____ _ _ ||
19
+ || / ____| | | | ||
20
+ || | | | |__ __ _ _ __ __ _ ___| | ___ __ _ ||
21
+ || | | | '_ \\ / _` | '_ \\ / _` |/ _ \\ |/ _ \\ / _` | ||
22
+ || | |____| | | | (_| | | | | (_| | __/ | (_) | (_| | ||
23
+ || \\_____|_| |_|\\__,_|_| |_|\\__, |\\___|_|\\___/ \\__, | ||
24
+ || __/ | __/ | ||
25
+ || |___/ |___/ ||
26
+ || ||
27
+ EOF
28
+ echo "$(changelog_divider)
29
+ $output
30
+ $(changelog_divider)"
31
+ }
32
+
33
+ get_changelog_text_for_commits() {
34
+ #Pass in commits array of SHA's
35
+ #Return formatted changelog text, with tags handled
36
+ #Optional first argument for the format "--format=%H"
37
+ local previous_shopt_extglob=$(shopt -p extglob)
38
+ local existing_shopt_nocasematch=$(shopt -p nocasematch)
39
+ shopt -s nocasematch
40
+ shopt -s extglob
41
+
42
+ local commit_shas=($@)
43
+
44
+ local feature_tag_lines=""
45
+ local bug_tag_lines=""
46
+ local security_tag_lines=""
47
+ local general_release_lines=""
48
+
49
+ local log_format="--format=%s"
50
+ local log_format_matcher="\-\-format\="
51
+
52
+ #Capture line by line unless first argument provides a custom format
53
+ for i in "${!commit_shas[@]}"; do
54
+ if [[ "${i}" = '0' ]]; then
55
+ if echo "${commit_shas[$i]}" | grep -q "${log_format_matcher}"; then
56
+ log_format="${commit_shas[$i]}";
57
+ continue;
58
+ fi;
59
+ fi;
60
+
61
+ local body_result="`git show -s ${log_format} ${commit_shas[$i]}`"
62
+ local newline=$'\n'
63
+ regex="^\s*\[(features?|bugs?|security)\]\s*(.*)\s*$"
64
+ if [[ $body_result =~ $regex ]]; then
65
+ #Tagged entry
66
+ local full_tag=$BASH_REMATCH
67
+ local tag_type="${BASH_REMATCH[1]}"
68
+ #Remove leading spaces (regex in bash capturing always)
69
+ local tag_content="${BASH_REMATCH[2]##*( )}"
70
+ #Add leading 2 spaces with bullet point for tagged line prefix & remove trailing spaces
71
+ tag_content=" ${tag_content%%*( )}${newline}"
72
+ #Sort matching tags
73
+ case "$tag_type" in
74
+ [fF][eE][aA][tT][uU][rR][eE] | [fF][eE][aA][tT][uU][rR][eE][sS] )
75
+ feature_tag_lines+="${tag_content}";;
76
+ [bB][uU][gG] | [bB][uU][gG][sS] )
77
+ bug_tag_lines+="$tag_content";;
78
+ [sS][eE][cC][uU][rR][iI][tT][yY] )
79
+ security_tag_lines+="$tag_content";;
80
+ * )
81
+ general_release_lines+="$tag_content";;
82
+ esac;
83
+ else
84
+ #Normal entry
85
+ general_release_lines+="$body_result${newline}"
86
+ fi;
87
+ done;
88
+
89
+ #Return previous setup for bash
90
+ eval $previous_shopt_extglob
91
+ eval $existing_shopt_nocasematch
92
+
93
+ if [[ $feature_tag_lines != '' ]]; then
94
+ echo "Features:
95
+ ${feature_tag_lines}"
96
+ fi;
97
+ if [[ $security_tag_lines != '' ]]; then
98
+ echo "Security:
99
+ ${security_tag_lines}"
100
+ fi;
101
+ if [[ $bug_tag_lines != '' ]]; then
102
+ echo "Bugs:
103
+ ${bug_tag_lines}"
104
+ fi;
105
+ echo "$general_release_lines"
106
+ }
107
+
108
+ #generate_changelog_content "$last_tag_name" "$next_tag_name" ":all/:pulls_only"
109
+ generate_changelog_content() {
110
+ local release_name="$1"
111
+ local commit_filter="$2" #all_commits or pulls_only
112
+ local starting_point="$3" #optional
113
+ local end_point="$4" #optional
114
+ local changelog_format="--format=%s" #default -> display title
115
+
116
+ if [[ "$release_name" = "" ]]; then
117
+ echo "Error : Release name required for changelog generation."
118
+ exit 1;
119
+ fi;
120
+
121
+ case "$commit_filter" in
122
+ ':all_commits' | 'all_commits' )
123
+ #No filter
124
+ commit_filter='';;
125
+ ':pulls_only' | 'pulls_only' )
126
+ #Filter by merged pull requests only
127
+ commit_filter=$'^Merge pull request #.* from .*';
128
+ changelog_format="--format=%b";; #use body of pull requests
129
+ * )
130
+ echo "Error : Commit filter required. Please specify :all or :pulls_only."
131
+ exit 1;;
132
+ esac
133
+
134
+ local commits=$(get_commits_between_points "$starting_point" "$end_point" "$commit_filter")
135
+ local commit_output=$(get_changelog_text_for_commits "$changelog_format" $commits)
136
+ local release_date=$(get_current_release_date)
137
+
138
+ echo "$(changelog_divider)
139
+ || Release: ${release_name}
140
+ || Released on ${release_date}
141
+ $(changelog_divider)
142
+ ${commit_output}
143
+ $(changelog_divider)"
144
+ }
145
+
146
+ #generate_version_file "$version_number" "$optional_file_name"
147
+ generate_version_file(){
148
+ local version_number="$1"
149
+ if [[ "$version_number" = "" ]]; then
150
+ echo "Error : Version number required for version file generation."
151
+ exit 1;
152
+ fi;
153
+ if [[ "$2" != '' ]]; then
154
+ local version_file="$2"
155
+ else
156
+ local version_file="VERSION" #optional
157
+ fi;
158
+
159
+ touch $version_file
160
+ echo "${version_number}" > $version_file
161
+ }
162
+
163
+ #generate_changelog_file "$changelog_content" ":overwrite/:append" "$optional_file_name"
164
+ generate_changelog_file(){
165
+ local changelog_content="$1"
166
+ local generate_strategy="$2"
167
+
168
+ if [[ "$changelog_content" = "" ]]; then
169
+ echo "Error : Changelog content required for version file generation."
170
+ exit 1;
171
+ fi;
172
+ if [[ "$3" != '' ]]; then
173
+ local changelog_file="$3"
174
+ else
175
+ local changelog_file="CHANGELOG" #optional
176
+ fi;
177
+
178
+ case "$generate_strategy" in
179
+ ':overwrite' | 'overwrite' )
180
+ #Overwrite;
181
+ echo "$changelog_content
182
+ $(changelog_footer)" > $changelog_file;;
183
+ ':append' | 'append' )
184
+ if [[ ! -f $changelog_file ]]; then
185
+ #Initialise new file
186
+ touch $changelog_file;
187
+ echo "$changelog_content
188
+ $(changelog_footer)" > $changelog_file
189
+ else
190
+ #Append to start of file
191
+ local existing_content=$(cat $changelog_file);
192
+
193
+ echo "$changelog_content
194
+ $existing_content" > $changelog_file;
195
+ fi;;
196
+ * )
197
+ echo "Error : Generate strategy required. Please specify :overwrite or :append."
198
+ exit 1;;
199
+ esac
200
+ }
@@ -0,0 +1,78 @@
1
+ #!/bin/bash -e
2
+
3
+ ############################################################
4
+ ##### GIT FUNCTIONS #####
5
+ ############################################################
6
+
7
+ check_tag_exists() {
8
+ local tag_find=$(git tag -l "$1")
9
+ if [[ "$tag_find" = '' ]]; then
10
+ return 1;
11
+ else
12
+ return 0;
13
+ fi;
14
+ }
15
+
16
+ ensure_git_directory() {
17
+ if [[ ! -d '.git' ]]; then
18
+ echo "Error - Not a git repository please run from the base of your git repo." >&2
19
+ exit 1
20
+ fi;
21
+ }
22
+
23
+ ensure_git_is_clean() {
24
+ local result=$(git status --porcelain)
25
+
26
+ if [[ "$result" != '' ]]; then
27
+ result=$(git status)
28
+ echo "Error - Current branch is in a dirty state, please commit your changes first."
29
+ echo "$result"
30
+ exit 1
31
+ fi;
32
+ }
33
+
34
+ get_sha_for_tag_name() {
35
+ local result=$(git show-ref --tags --hash $1)
36
+ echo "$result"
37
+ }
38
+
39
+ get_sha_for_first_commit() {
40
+ local filter=$1
41
+ local result=$(git log --reverse --format="%H" $filter | head -1)
42
+ echo "$result"
43
+ }
44
+
45
+ get_commit_message_for_first_commit() {
46
+ local filter=$1
47
+ local result=$(git log --reverse --format="%s" $filter | head -1)
48
+ echo "$result"
49
+ }
50
+
51
+ get_commit_message_for_latest_commit() {
52
+ local filter=$1
53
+ local result=$(git log -n1 --format="%s" $filter)
54
+ echo "$result"
55
+ }
56
+
57
+ get_commits_between_points() {
58
+ local starting_point="$1" #optional
59
+ local end_point="$2" #optional
60
+ local log_filter="$3" #optional
61
+
62
+ local git_command="git log";
63
+ local log_options="--no-notes --format=%H"
64
+ local git_range=""
65
+
66
+ if [[ "$log_filter" != '' ]]; then
67
+ log_options="$log_options --grep="'"'"$log_filter"'"'""
68
+ fi;
69
+ if [[ "$starting_point" != '' && "$end_point" != '' ]]; then
70
+ git_range="${starting_point}^1..${end_point}";
71
+ elif [[ "$end_point" != '' ]]; then
72
+ git_range="${end_point}"
73
+ elif [[ "$starting_point" != '' ]]; then
74
+ git_range="${starting_point}^1..HEAD"
75
+ fi;
76
+
77
+ eval $git_command $log_options $git_range
78
+ }
@@ -0,0 +1,125 @@
1
+ #!/bin/bash -e
2
+
3
+ ############################################################
4
+ ##### GLOBALS #####
5
+ ############################################################
6
+
7
+ TAG_VERSION_NUMBER_REGEX="([0-9]+)\\.([0-9]+)\\.([0-9]+)$"
8
+
9
+ ############################################################
10
+ ##### SUPPORT FUNCTIONS #####
11
+ ############################################################
12
+
13
+ validate_version_type() {
14
+ #Confirm version type is in the accepted types
15
+ local v="$1"
16
+ local error_output="$2"
17
+
18
+ if [[ $v != "major" && $v != 'minor' && $v != 'patch' ]]; then
19
+ printf "incorrect versioning type: '%s'\\n" "$v" >&2
20
+ echo "Please set to one of 'major', 'minor' or 'patch'" >&2
21
+ echo "$error_output" >&2
22
+ exit 1
23
+ fi;
24
+ }
25
+
26
+ #git-release-deployed only
27
+ validate_deploy_tag() {
28
+ local t="$1"
29
+ local error_output="$2"
30
+
31
+ if [[ "$t" = '' ]]; then
32
+ echo "Required parameter: Please enter the deploy tag released."
33
+ echo "$error_output"
34
+ exit 1;
35
+ elif [[ "$(git tag -l $t )" = '' ]]; then
36
+ echo "Error: Unable to find tag '${t}'. Please check and try again."
37
+ exit 1;
38
+ fi;
39
+ }
40
+
41
+ ############################################################
42
+ ##### TAG FUNCTIONS #####
43
+ ############################################################
44
+
45
+ get_release_tags() {
46
+ local filter=""
47
+ local tag_names=""
48
+
49
+ if [[ $1 ]]; then
50
+ local tag_pattern=$1
51
+ filter="${tag_pattern}*"
52
+ fi;
53
+ tag_names=$(git tag -l $filter)
54
+
55
+ #<ref> tags/<release_prefix><version_number>
56
+ echo "$tag_names"
57
+ }
58
+
59
+ get_last_tag_name() {
60
+ local versioning_prefix=$1
61
+
62
+ local tags=$(get_release_tags $versioning_prefix)
63
+ echo "$tags" | tail -1
64
+ }
65
+
66
+ get_versioning_prefix_from_tag() {
67
+ local tag_name="$1"
68
+ if [[ $tag_name =~ $TAG_VERSION_NUMBER_REGEX ]]; then
69
+ local version_number=$BASH_REMATCH
70
+ local version_prefix="${tag_name%%$version_number}"
71
+ else
72
+ echo "Error : Unable to determine version prefix from '${tag_name}'"
73
+ exit 1;
74
+ fi;
75
+ echo "${version_prefix}"
76
+ }
77
+
78
+ get_version_number_from_tag() {
79
+ local tag_name="$1"
80
+ if [[ $tag_name =~ $TAG_VERSION_NUMBER_REGEX ]]; then
81
+ local full_version=$BASH_REMATCH
82
+ else
83
+ echo "Error : Unable to determine version number from '${tag_name}'"
84
+ exit 1;
85
+ fi;
86
+ #full stop delimited version number
87
+ echo "$full_version"
88
+ }
89
+
90
+ get_next_version_number_from_tag() {
91
+ local versioning_type=$1
92
+ local tag_name=$2
93
+
94
+ if [[ "$versioning_type" = "" ]]; then
95
+ echo "Error : Versioning type required. eg. major"
96
+ exit 1;
97
+ fi;
98
+
99
+ if [[ $tag_name = '' ]]; then
100
+ #No original tag name for version prefix - start increment
101
+ local tag_name="0.0.0"
102
+ fi;
103
+
104
+ if [[ $tag_name =~ $TAG_VERSION_NUMBER_REGEX ]]; then
105
+ local full_version=$BASH_REMATCH
106
+ local major_version="${BASH_REMATCH[1]}"
107
+ local minor_version="${BASH_REMATCH[2]}"
108
+ local patch_version="${BASH_REMATCH[3]}"
109
+ else
110
+ echo "Error : Unable to determine version number from '${tag_name}'"
111
+ exit 1;
112
+ fi;
113
+
114
+ #Increment version
115
+ case "$versioning_type" in
116
+ 'major' )
117
+ major_version=$(( $major_version + 1 ));;
118
+ 'minor' )
119
+ minor_version=$(( $minor_version + 1 ));;
120
+ 'patch' )
121
+ patch_version=$(( $patch_version + 1 ));;
122
+ esac
123
+
124
+ echo "${major_version}.${minor_version}.${patch_version}"
125
+ }
@@ -0,0 +1,30 @@
1
+ #!/bin/sh -e
2
+
3
+ #Language specific naming, to be overridden by whichever language is being used
4
+
5
+ ARG_ASSIGNER=" " #Argument assigner. space or = for assigning arguments
6
+ ARG_PREFIX="-" #Argument prefix (used in help text display such as '-' for '-v')
7
+ #Arguments for running script
8
+ ARG_VERSION="v"
9
+ ARG_DEPLOYED_TAG="d"
10
+ ARG_RELEASE_PREFIX="p"
11
+ ARG_START="s"
12
+ ARG_FINISH="f"
13
+ ARG_APPEND="A"
14
+ ARG_PULL_REQUESTS="P"
15
+ ARG_CHANGELOG="C"
16
+ ARG_VERSION_FILE="V"
17
+ ARG_FORCE="F"
18
+ ARG_HELP_TEXT="h"
19
+
20
+ #Display arg with language specific assigner and prefix
21
+ arg_for() {
22
+ local arg="$1"
23
+ local val="$2"
24
+ if [[ $val != '' ]]; then
25
+ echo "${ARG_PREFIX}${1}${ARG_ASSIGNER}${2}"
26
+ else
27
+ echo "${ARG_PREFIX}${1}"
28
+ fi;
29
+ }
30
+