Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break up functions #3

Merged
merged 7 commits into from Apr 7, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Expand Up @@ -17,20 +17,24 @@ Bash only (language agnostic) git release script for tagging and bagging a relea
* Grep

## TODO
- [ ] Write success cases for releaseable-deployed script

- [ ] Write a proper README
- [ ] Optionally force push of tags, otherwise ask for confirmation to send
- [ ] Make uniform variable style, either all capped variables or not
- [ ] Test mode should display processes it would run (--dry-run option)
- [ ] Verbose debug mode (display a lot more info)
- [ ] Split up functions and specs into more logical divisions (changelog, git) rather than one large support file
- [ ] Create Ruby gem branch and release as a gem. Use better OPTPARSER to use more human readable variables to pass to - der lying script
- [ ] Create Node NPM branch and release as an NPM.
- [ ] Create Python PIP branch and release as a PIP.
- [ ] Test on variety of systems and servers
- [ ] Fix issue in tests where the time can very rarely cross over a second boundary (make specs ignore seconds difference)
- [ ] Review argument naming and choose better letters
- [ ] Make test helpers for setting argument mapping (for easily changing in other wrappers)
- [ ] Make test helpers for generating the content (changing the style now will break a lot of tests)
- [ ] [potentially] Make CHANGELOG tagging dynamic (search for initial square brackets), with features + bugs on top of listing
- [ ] [potentially] Make CHANGELOG generation read in optional template, with wildcards to apply logic to view
- [x] Write success cases for releaseable-deployed script
- [*] Split up functions and specs into more logical divisions (changelog, git) rather than one large support file
- [*] Remove *.sh filenames and rely on shebangs on each executable file. Support files keep for editors to use.
- [*] Split into seperate github repo with migrated history
- [*] Load Travis-CI
Expand Down
2 changes: 1 addition & 1 deletion bin/releaseable
Expand Up @@ -63,7 +63,7 @@ usage examples:
"

#Supporting functions
. "${BASH_SOURCE[0]%/*}/../support/releaseable.sh"
. "${BASH_SOURCE[0]%/*}/../support/support-functions.sh"

############################################################
##### INPUT CAPTURE #####
Expand Down
12 changes: 8 additions & 4 deletions bin/releaseable-deployed
Expand Up @@ -78,7 +78,7 @@ usage examples:
"

#Supporting functions
. "${BASH_SOURCE[0]%/*}/../support/releaseable.sh"
. "${BASH_SOURCE[0]%/*}/../support/support-functions.sh"

############################################################
##### INPUT CAPTURE #####
Expand Down Expand Up @@ -126,15 +126,19 @@ if [ ! $SKIP_EXECUTE ]; then
#Checkout existing deployed tag
next_deploy_tag_name="${DEPLOYED_PREFIX}${DEPLOYED_TAG}"

if [[ $(check_tag_exists "$next_deploy_tag_name" && echo $?) = "0" ]]; then
#Delete existing
git tag -d $next_deploy_tag_name
fi;
git checkout -f --no-track -B "$next_deploy_tag_name" "$DEPLOYED_TAG"

#Capture versioning prefix from deployed tag
versioning_prefix=$(get_versioning_prefix_from_tag "$DEPLOYED_TAG")
#Capture versioning prefix from new deploy tag
versioning_prefix=$(get_versioning_prefix_from_tag "$next_deploy_tag_name")

#Find last deployed tag for this versioning style
last_tag_name=$(get_last_tag_name $versioning_prefix)

deployed_version_number=$(get_version_number_from_tag "$DEPLOYED_TAG")
deployed_version_number=$(get_version_number_from_tag "$next_deploy_tag_name")
if [[ "$START_POINT" = '' ]]; then
START_POINT=$last_tag_name
fi;
Expand Down
282 changes: 38 additions & 244 deletions support/releaseable.sh → support/changelog-functions.sh 100755 → 100644
@@ -1,211 +1,5 @@
#!/bin/bash -e

############################################################
##### GLOBALS #####
############################################################

TAG_VERSION_NUMBER_REGEX="([0-9]+)\\.([0-9]+)\\.([0-9]+)$"

############################################################
##### SUPPORT FUNCTIONS #####
############################################################

#Releaseable only
validate_version_type() {
#Confirm version type is in the accepted types
local v="$1"
local error_output="$2"

if [[ $v != "major" && $v != 'minor' && $v != 'patch' ]]; then
printf "incorrect versioning type: '%s'\\n" "$v" >&2
echo "Please set to one of 'major', 'minor' or 'patch'" >&2
echo "$error_output" >&2
exit 1
fi;
}

#Releaseable-deployed only
validate_deploy_tag() {
local t="$1"
local error_output="$2"

if [[ "$t" = '' ]]; then
echo "Required parameter: Please enter the deploy tag released."
echo "$error_output"
exit 1;
elif [[ "$(git tag -l $t )" = '' ]]; then
echo "Error: Unable to find tag '${t}'. Please check and try again."
exit 1;
fi;
}

check_tag_exists() {
local tag_find=$(git tag -l "$1")
if [[ "$tag_find" = '' ]]; then
return 1;
else
return 0;
fi;
}

ensure_git_directory() {
if [[ ! -d '.git' ]]; then
echo "Error - Not a git repository please run from the base of your git repo." >&2
exit 1
fi;
}

ensure_git_is_clean() {
local result=$(git status --porcelain)

if [[ "$result" != '' ]]; then
result=$(git status)
echo "Error - Current branch is in a dirty state, please commit your changes first."
echo "$result"
exit 1
fi;
}

versioning_prefix() {
if [[ $2 ]]; then
echo "${1}/${2}"
else
echo "${1}"
fi;
}

############################################################
##### TAG FUNCTIONS #####
############################################################

get_release_tags() {
local filter=""
local tag_names=""

if [[ $1 ]]; then
local tag_pattern=$1
filter="${tag_pattern}*"
fi;
tag_names=$(git tag -l $filter)

#<ref> tags/<release_prefix>/<version_prefix><version_number>
echo "$tag_names"
}

get_last_tag_name() {
local versioning_prefix=$1

tags=$(get_release_tags $versioning_prefix)
echo "$tags" | tail -1
}

get_versioning_prefix_from_tag() {
local tag_name="$1"
if [[ $tag_name =~ $TAG_VERSION_NUMBER_REGEX ]]; then
local version_number=$BASH_REMATCH
local version_prefix="${tag_name%%$version_number}"
else
echo "Error : Unable to determine version prefix from '${tag_name}'"
exit 1;
fi;
echo "${version_prefix}"
}

get_version_number_from_tag() {
local tag_name="$1"
if [[ $tag_name =~ $TAG_VERSION_NUMBER_REGEX ]]; then
local full_version=$BASH_REMATCH
else
echo "Error : Unable to determine version number from '${tag_name}'"
exit 1;
fi;
#full stop delimited version number
echo "$full_version"
}

get_next_version_number_from_tag() {
local versioning_type=$1
local tag_name=$2

if [[ "$versioning_type" = "" ]]; then
echo "Error : Versioning type required. eg. major"
exit 1;
fi;

if [[ $tag_name = '' ]]; then
#No original tag name for version prefix - start increment
local tag_name="0.0.0"
fi;

if [[ $tag_name =~ $TAG_VERSION_NUMBER_REGEX ]]; then
local full_version=$BASH_REMATCH
local major_version="${BASH_REMATCH[1]}"
local minor_version="${BASH_REMATCH[2]}"
local patch_version="${BASH_REMATCH[3]}"
else
echo "Error : Unable to determine version number from '${tag_name}'"
exit 1;
fi;

#Increment version
case "$versioning_type" in
'major' )
major_version=$(( $major_version + 1 ));;
'minor' )
minor_version=$(( $minor_version + 1 ));;
'patch' )
patch_version=$(( $patch_version + 1 ));;
esac

echo "${major_version}.${minor_version}.${patch_version}"
}

get_sha_for_tag_name() {
local result=$(git show-ref --tags --hash $1)
echo "$result"
}

get_sha_for_first_commit() {
local filter=$1
local result=$(git log --reverse --format="%H" $filter | head -1)
echo "$result"
}

get_commit_message_for_first_commit() {
local filter=$1
local result=$(git log --reverse --format="%s" $filter | head -1)
echo "$result"
}

get_commit_message_for_latest_commit() {
local filter=$1
local result=$(git log -n1 --format="%s" $filter)
echo "$result"
}

get_commits_between_points() {
local starting_point="$1" #optional
local end_point="$2" #optional
local log_filter="$3" #optional

local git_command="git log";
local log_options="--no-notes --format=%H"
local git_range=""

if [[ "$log_filter" != '' ]]; then
log_options="$log_options --grep="'"'"$log_filter"'"'""
fi;
if [[ "$starting_point" != '' && "$end_point" != '' ]]; then
git_range="${starting_point}^1..${end_point}";
elif [[ "$end_point" != '' ]]; then
git_range="${end_point}"
elif [[ "$starting_point" != '' ]]; then
git_range="${starting_point}^1..HEAD"
fi;

eval $git_command $log_options $git_range
}

############################################################
##### CHANGELOG FUNCTIONS #####
############################################################
Expand Down Expand Up @@ -311,6 +105,44 @@ ${bug_tag_lines}"
echo "$general_release_lines"
}

#generate_changelog_content "$last_tag_name" "$next_tag_name" ":all/:pulls_only"
generate_changelog_content() {
local release_name="$1"
local commit_filter="$2" #all_commits or pulls_only
local starting_point="$3" #optional
local end_point="$4" #optional
local changelog_format="--format=%s" #default -> display title

if [[ "$release_name" = "" ]]; then
echo "Error : Release name required for changelog generation."
exit 1;
fi;

case "$commit_filter" in
':all_commits' | 'all_commits' )
#No filter
commit_filter='';;
':pulls_only' | 'pulls_only' )
#Filter by merged pull requests only
commit_filter=$'^Merge pull request #.* from .*';
changelog_format="--format=%b";; #use body of pull requests
* )
echo "Error : Commit filter required. Please specify :all or :pulls_only."
exit 1;;
esac

local commits=$(get_commits_between_points "$starting_point" "$end_point" "$commit_filter")
local commit_output=$(get_changelog_text_for_commits "$changelog_format" $commits)
local release_date=$(get_current_release_date)

echo "$(changelog_divider)
|| Release: ${release_name}
|| Released on ${release_date}
$(changelog_divider)
${commit_output}
$(changelog_divider)"
}

#generate_version_file "$version_number" "$optional_file_name"
generate_version_file(){
local version_number="$1"
Expand Down Expand Up @@ -366,41 +198,3 @@ $existing_content" > $changelog_file;
exit 1;;
esac
}

#generate_changelog_content "$last_tag_name" "$next_tag_name" ":all/:pulls_only"
generate_changelog_content() {
local release_name="$1"
local commit_filter="$2" #all_commits or pulls_only
local starting_point="$3" #optional
local end_point="$4" #optional
local changelog_format="--format=%s" #default -> display title

if [[ "$release_name" = "" ]]; then
echo "Error : Release name required for changelog generation."
exit 1;
fi;

case "$commit_filter" in
':all_commits' | 'all_commits' )
#No filter
commit_filter='';;
':pulls_only' | 'pulls_only' )
#Filter by merged pull requests only
commit_filter=$'^Merge pull request #.* from .*';
changelog_format="--format=%b";; #use body of pull requests
* )
echo "Error : Commit filter required. Please specify :all or :pulls_only."
exit 1;;
esac

local commits=$(get_commits_between_points "$starting_point" "$end_point" "$commit_filter")
local commit_output=$(get_changelog_text_for_commits "$changelog_format" $commits)
local release_date=$(get_current_release_date)

echo "$(changelog_divider)
|| Release: ${release_name}
|| Released on ${release_date}
$(changelog_divider)
${commit_output}
$(changelog_divider)"
}