Skip to content

Commit 685bbdc

Browse files
committed
Read version from package.json
Remove default fetch of version from VERSION file Updated comments
1 parent 1f2c3f3 commit 685bbdc

File tree

5 files changed

+455
-101
lines changed

5 files changed

+455
-101
lines changed

lib/helpers.sh

Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
#!/bin/bash
2+
3+
is_number() {
4+
case $1 in
5+
''|*[!0-9]*) return 0 ;;
6+
*) return 1 ;;
7+
esac
8+
}
9+
10+
# Show credits & help
11+
usage() {
12+
local SCRIPT_VER SCRIPT_AUTH_EMAIL SCRIPT_AUTH_NAME SCRIPT_HOME
13+
# NPM environment variables are fetched with cross-platform tool cross-env
14+
SCRIPT_VER=`cd $MODULE_DIR && npm run get-pkg-ver -s`
15+
SCRIPT_AUTH_NAME=`cd $MODULE_DIR && npm run get-pkg-auth -s`
16+
SCRIPT_AUTH_EMAIL=`cd $MODULE_DIR && npm run get-pkg-email -s`
17+
SCRIPT_NAME=`cd $MODULE_DIR && npm run get-pkg-name -s`
18+
SCRIPT_HOME=`cd $MODULE_DIR && npm run get-pkg-page -s`
19+
20+
echo -e "${GREEN}"\
21+
"_ _ ___ ___ ___ _ _ __ __ ___ "\
22+
"\n| | || __>| . \ ___ | . >| | || \ \| . \ "\
23+
"\n| ' || _> | /|___|| . \| ' || || _/ "\
24+
"\n|__/ |___>|_\_\ |___/\___/|_|_|_||_| "\
25+
"\n\t\t\t${LIGHTGRAY} ${BOLD}Version: $S_WARN${SCRIPT_VER}"
26+
27+
echo -e "${S_NORM}${BOLD}Description:${RESET}"\
28+
"\nThis script automates bumping the git software project's version automatically."\
29+
"\nIt does several things that are typically required for releasing a Git repository, like git tagging, automatic updating of CHANGELOG.md, and incrementing the version number in various JSON files."
30+
31+
echo -e "\n${S_NORM}${BOLD}Usage:${RESET}"\
32+
"\n${SCRIPT_NAME} [-v <version number>] [-m <release message>] [-j <file1>] [-j <file2>].. [-n] [-p] [-h]" 1>&2;
33+
34+
echo -e "\n${S_NORM}${BOLD}Options:${RESET}"
35+
echo -e "$S_WARN-v$S_NORM <version number>\tSpecify a manual version number"
36+
echo -e "$S_WARN-m$S_NORM <release message>\tCustom release message."
37+
echo -e "$S_WARN-f$S_NORM <filename.json>\tUpdate version number inside JSON files."\
38+
"\n\t\t\tFor multiple files, add a separate -f option for each one, for example:"\
39+
"\n\t\t\t${S_NORM}ver-bump -f src/plugin/package.json -f composer.json"
40+
echo -e "$S_WARN-p$S_NORM \t\t\tPush release branch to ORIGIN. "
41+
echo -e "$S_WARN-h$S_NORM \t\t\tShow this help message. \n"
42+
43+
echo -e "${S_NORM}${BOLD}Credits:${S_LIGHT}"\
44+
"\n${SCRIPT_AUTH_NAME} <${SCRIPT_AUTH_EMAIL}> ${RESET}"\
45+
"\n${SCRIPT_HOME}\n"
46+
}
47+
48+
# If there are no commits in repo, quit, because you can't tag with zero commits.
49+
check-commits-exist() {
50+
git rev-parse HEAD &> /dev/null
51+
if [ ! "$?" -eq 0 ]; then
52+
echo -e "\n${I_STOP} ${S_ERROR}Your current branch doesn't have any commits yet. Can't tag without at least one commit." >&2
53+
echo
54+
exit 1
55+
fi
56+
}
57+
58+
get-commit-msg() {
59+
echo Bumped $([ -n "${V_PREV}" ] && echo "${V_PREV} –>" || echo "to ") "$V_USR_INPUT"
60+
}
61+
62+
exit_abnormal() {
63+
usage # Show help
64+
exit 1
65+
}
66+
67+
# Process script options
68+
process-arguments() {
69+
local OPTIONS OPTIND OPTARG
70+
71+
# Get positional parameters
72+
while getopts ":v:p:m:f:hbn" OPTIONS; do # Note: Adding the first : before the flags takes control of flags and prevents default error msgs.
73+
case "$OPTIONS" in
74+
h )
75+
# Show help
76+
exit_abnormal
77+
;;
78+
v )
79+
# User has supplied a version number
80+
V_USR_SUPPLIED=$OPTARG
81+
;;
82+
m )
83+
REL_NOTE=$OPTARG
84+
# Custom release note
85+
echo -e "\n${S_LIGHT}Option set: ${S_NOTICE}Release note:" ${S_NORM}"'"$REL_NOTE"'"
86+
;;
87+
f )
88+
FLAG_JSON=true
89+
echo -e "\n${S_LIGHT}Option set: ${S_NOTICE}JSON file via [-f]: <${S_NORM}${OPTARG}${S_LIGHT}>"
90+
# Store JSON filenames(s)
91+
JSON_FILES+=($OPTARG)
92+
;;
93+
p )
94+
FLAG_PUSH=true
95+
PUSH_DEST=${OPTARG} # Replace default with user input
96+
echo -e "\n${S_LIGHT}Option set: ${S_NOTICE}Pushing to <${S_NORM}${PUSH_DEST}${S_LIGHT}>, as the last action in this script."
97+
;;
98+
n )
99+
FLAG_NOCOMMIT=true
100+
echo -e "\n${S_LIGHT}Option set: ${S_NOTICE}Disable commit after tagging."
101+
;;
102+
b )
103+
FLAG_NOBRANCH=true
104+
echo -e "\n${S_LIGHT}Option set: ${S_NOTICE}Disable committing to new branch."
105+
;;
106+
\? )
107+
echo -e "\n${I_ERROR}${S_ERROR} Invalid option: ${S_WARN}-$OPTARG" >&2
108+
echo
109+
exit_abnormal
110+
;;
111+
: )
112+
echo -e "\n${I_ERROR}${S_ERROR} Option ${S_WARN}-$OPTARG ${S_ERROR}requires an argument." >&2
113+
echo
114+
exit_abnormal
115+
;;
116+
esac
117+
done
118+
}
119+
120+
# Suggests version from VERSION file, or grabs from user supplied -v <version>.
121+
# If none is set, suggest default from options.
122+
123+
# - If <package.json> doesn't exist, warn + exit
124+
# - If -v specified, set version from that
125+
# - Else,
126+
# - Grab from package.json
127+
# - Suggest incremented number
128+
# - Give prompt to user to modify
129+
# - Set global
130+
131+
# According to SemVer 2.0.0, given a version number MAJOR.MINOR.PATCH, suggest incremented value:
132+
# — MAJOR version when you make incompatible API changes,
133+
# — MINOR version when you add functionality in a backwards compatible manner, and
134+
# — PATCH version when you make backwards compatible bug fixes.
135+
process-version() {
136+
137+
# If a version number is supplied by the user with [-v <version number>], then use it
138+
if [ -n "$V_USR_SUPPLIED" ]; then
139+
echo -e "\n${S_NOTICE}You selected version using [-v]:" "${S_WARN}${V_USR_SUPPLIED}"
140+
V_USR_INPUT="${V_USR_SUPPLIED}"
141+
else
142+
if [ -f $VER_FILE ] && [ -s $VER_FILE ]; then
143+
local IS_NO=0
144+
145+
# Get the existing version number
146+
V_PREV=$( sed -n 's/.*"version":.*"\(.*\)"\(,\)\{0,1\}/\1/p' $VER_FILE )
147+
148+
if [ -n "$V_PREV" ]; then
149+
150+
echo -e "\n${S_NOTICE}Current version read from <${S_QUESTION}${VER_FILE}${S_NOTICE}> file: ${S_QUESTION}$V_PREV"
151+
152+
V_PREV_LIST=(`echo $V_PREV | tr '.' ' '`)
153+
V_MAJOR=${V_PREV_LIST[0]}; V_MINOR=${V_PREV_LIST[1]}; V_PATCH=${V_PREV_LIST[2]};
154+
155+
is_number $V_MAJOR; (( IS_NO = $? ))
156+
is_number $V_MINOR; (( IS_NO = $? && $IS_NO ))
157+
158+
# If major & minor are numbers, then proceed to increment patch
159+
if [ $IS_NO = 1 ]; then
160+
is_number $V_PATCH;
161+
[ $? == 1 ] && V_PATCH=$((V_PATCH + 1)) # Increment
162+
V_SUGGEST="$V_MAJOR.$V_MINOR.$V_PATCH"
163+
else
164+
# If patch not a number, do nothing
165+
echo -e "\n${I_WARN} ${S_WARN}Warning: ${S_QUESTION}${V_PREV}${S_WARN} doesn't look like a SemVer compatible version number!\n"
166+
fi
167+
168+
else
169+
echo -e "\n${I_WARN} ${S_ERROR}Warning: <${S_QUESTION}${VER_FILE}${S_WARN}> doesn't contain a 'version' field!\n"
170+
fi
171+
else
172+
echo -ne "\n${S_WARN}Warning: <${S_QUESTION}${VER_FILE}${S_WARN}> "
173+
174+
if [ ! -f $VER_FILE ]; then
175+
echo "was not found!";
176+
elif [ ! -s $VER_FILE ]; then
177+
echo "is empty!";
178+
fi
179+
fi
180+
181+
# Confirm it with user
182+
echo -ne "\n${S_QUESTION}Enter a new version number or press <enter> to use [${S_NORM}$V_SUGGEST${S_QUESTION}]: "
183+
echo -ne "$S_WARN"
184+
read V_USR_INPUT
185+
186+
if [ "$V_USR_INPUT" = "" ]; then
187+
V_USR_INPUT="${V_SUGGEST}"
188+
fi
189+
fi
190+
}
191+
192+
# Only tag if tag doesn't already exist
193+
check-tag-exists() {
194+
TAG_CHECK_EXISTS=`git tag -l v"$V_USR_INPUT"`
195+
if [ -n "$TAG_CHECK_EXISTS" ]; then
196+
echo -e "\n${I_STOP} ${S_ERROR}Error: A release with that tag version number already exists!\n"
197+
exit 0
198+
fi
199+
}
200+
201+
# $1 : version
202+
# $2 : release note
203+
tag() {
204+
if [ -z "$2" ]; then
205+
# Default release note
206+
git tag -a "v$1" -m "Tag version $1."
207+
else
208+
# Custom release note
209+
git tag -a "v$1" -m "$2"
210+
fi
211+
echo -e "\n${I_OK} ${S_NOTICE}Added GIT tag"
212+
}
213+
214+
# Change `version:` value in JSON files, like packager.json, composer.json, etc
215+
bump-json-files() {
216+
# if [ "$FLAG_JSON" != true ]; then return; fi
217+
218+
JSON_PROCESSED=( ) # holds filenames after they've been changed
219+
220+
for FILE in "${JSON_FILES[@]}"; do
221+
if [ -f $FILE ]; then
222+
# Get the existing version number
223+
V_OLD=$( sed -n 's/.*"version":.*"\(.*\)"\(,\)\{0,1\}/\1/p' $FILE )
224+
225+
if [ "$V_OLD" = "$V_USR_INPUT" ]; then
226+
echo -e "\n${I_ERROR} ${S_WARN}File <${S_QUESTION}$FILE${S_WARN}> already contains version ${S_NORM}$V_OLD"
227+
else
228+
# Write to output file
229+
FILE_MSG=`sed -i .temp "s/\"version\":\(.*\)\"$V_OLD\"/\"version\":\1\"$V_USR_INPUT\"/g" $FILE 2>&1`
230+
231+
if [ "$?" -eq 0 ]; then
232+
echo -e "\n${I_OK} ${S_NOTICE}Updated file <${S_NORM}$FILE${S_NOTICE}> from ${S_QUESTION}$V_OLD ${S_NOTICE}-> ${S_QUESTION}$V_USR_INPUT"
233+
rm -f ${FILE}.temp
234+
# Add file change to commit message:
235+
GIT_MSG+="Updated $FILE, "
236+
else
237+
echo -e "\n${I_STOP} ${S_ERROR}Error\n$PUSH_MSG\n"
238+
fi
239+
fi
240+
241+
JSON_PROCESSED+=($FILE)
242+
else
243+
echo -e "\n${S_WARN}File <${S_NORM}$FILE${S_WARN}> not found."
244+
fi
245+
done
246+
# Stage files that were changed:
247+
[ -n "${JSON_PROCESSED}" ] && git add "${JSON_PROCESSED[@]}"
248+
}
249+
250+
# Handle VERSION file - for backward compatibility
251+
do-versionfile() {
252+
if [ -f VERSION ]; then
253+
GIT_MSG+="Updated VERSION, "
254+
echo $V_USR_INPUT > VERSION # Overwrite file
255+
# Stage file for commit
256+
git add VERSION
257+
258+
echo -e "\n${I_OK} ${S_NOTICE}Updated [${S_NORM}VERSION${S_NOTICE}] file."\
259+
"\n${I_WARN} ${S_ERROR}Deprecation warning: using a <${S_NORM}VERSION${S_ERROR}> file is deprecated since v0.2.0 — support will be removed in future versions."
260+
fi
261+
}
262+
263+
# Dump git log history to CHANGELOG.md
264+
do-changelog() {
265+
266+
# Log latest commits to CHANGELOG.md:
267+
# Get latest commits since last versio
268+
LOG_MSG=`git log --pretty=format:"- %s" $([ -n "$V_PREV" ] && echo "v${V_PREV}...HEAD") 2>&1`
269+
if [ ! "$?" -eq 0 ]; then
270+
echo -e "\n${I_STOP} ${S_ERROR}Error getting commit history since last version bump for logging to CHANGELOG.\n\n$LOG_MSG\n"
271+
exit 1
272+
fi
273+
274+
[ -f CHANGELOG.md ] && ACTION_MSG="Updated" || ACTION_MSG="Created"
275+
# Add info to commit message for later:
276+
GIT_MSG+="${ACTION_MSG} CHANGELOG.md, "
277+
278+
# Add heading
279+
echo "## $V_USR_INPUT ($NOW)" > tmpfile
280+
281+
# Log the bumping commit:
282+
# - The final commit is done after do-changelog(), so we need to create the log entry for it manually:
283+
echo "- ${GIT_MSG}$(get-commit-msg)" >> tmpfile
284+
# Add previous commits
285+
[ -n "$LOG_MSG" ] && echo "$LOG_MSG" >> tmpfile
286+
287+
echo -en "\n" >> tmpfile
288+
289+
if [ -f CHANGELOG.md ]; then
290+
# Append existing log
291+
cat CHANGELOG.md >> tmpfile
292+
else
293+
echo -e "\n${S_WARN}A [${S_NORM}CHANGELOG.md${S_WARN}] file was not found."
294+
fi
295+
296+
mv tmpfile CHANGELOG.md
297+
298+
# User prompts
299+
echo -e "\n${I_OK} ${S_NOTICE}${ACTION_MSG} [${S_NORM}CHANGELOG.md${S_NOTICE}] file"
300+
# Pause & allow user to open and edit the file:
301+
echo -en "\n${S_QUESTION}Make adjustments to [${S_NORM}CHANGELOG.md${S_QUESTION}] if required now. Press <enter> to continue."
302+
read
303+
304+
# Stage log file, to commit later
305+
git add CHANGELOG.md
306+
}
307+
308+
#
309+
check-branch-exist() {
310+
[ "$FLAG_NOBRANCH" = true ] && return
311+
312+
BRANCH_MSG=`git rev-parse --verify "${REL_PREFIX}${V_USR_INPUT}" 2>&1`
313+
if [ "$?" -eq 0 ]; then
314+
echo -e "\n${I_STOP} ${S_ERROR}Error: Branch <${S_NORM}${REL_PREFIX}${V_USR_INPUT}${S_ERROR}> already exists!\n"
315+
exit 1
316+
fi
317+
}
318+
319+
#
320+
do-branch() {
321+
[ "$FLAG_NOBRANCH" = true ] && return
322+
323+
echo -e "\n${S_NOTICE}Creating new release branch..."
324+
325+
BRANCH_MSG=`git branch "${REL_PREFIX}${V_USR_INPUT}" 2>&1`
326+
if [ ! "$?" -eq 0 ]; then
327+
echo -e "\n${I_STOP} ${S_ERROR}Error\n$BRANCH_MSG\n"
328+
exit 1
329+
else
330+
BRANCH_MSG=`git checkout "${REL_PREFIX}${V_USR_INPUT}" 2>&1`
331+
echo -e "\n${I_OK} ${S_NOTICE}${BRANCH_MSG}"
332+
fi
333+
334+
# REL_PREFIX
335+
}
336+
337+
# Stage & commit all files modified by this script
338+
do-commit() {
339+
[ "$FLAG_NOCOMMIT" = true ] && return
340+
341+
GIT_MSG+="$(get-commit-msg)"
342+
echo -e "\n${S_NOTICE}Committing..."
343+
COMMIT_MSG=`git commit -m "${GIT_MSG}" 2>&1`
344+
if [ ! "$?" -eq 0 ]; then
345+
echo -e "\n${I_STOP} ${S_ERROR}Error\n$COMMIT_MSG\n"
346+
exit 1
347+
else
348+
echo -e "\n${I_OK} ${S_NOTICE}$COMMIT_MSG"
349+
fi
350+
}
351+
352+
# Pushes files + tags to remote repo. Changes are staged by earlier functions
353+
do-push() {
354+
[ "$FLAG_NOCOMMIT" = true ] && return
355+
356+
if [ "$FLAG_PUSH" = true ]; then
357+
CONFIRM="Y"
358+
else
359+
echo -ne "\n${S_QUESTION}Push tags to <${S_NORM}${PUSH_DEST}${S_QUESTION}>? [${S_NORM}N/y${S_QUESTION}]: "
360+
read CONFIRM
361+
fi
362+
363+
case "$CONFIRM" in
364+
[yY][eE][sS]|[yY] )
365+
echo -e "\n${S_NOTICE}Pushing files + tags to <${S_NORM}${PUSH_DEST}${S_NOTICE}>..."
366+
PUSH_MSG=`git push "${PUSH_DEST}" v"$V_USR_INPUT" 2>&1` # Push new tag
367+
if [ ! "$?" -eq 0 ]; then
368+
echo -e "\n${I_STOP} ${S_WARN}Warning\n$PUSH_MSG"
369+
# exit 1
370+
else
371+
echo -e "\n${I_OK} ${S_NOTICE}$PUSH_MSG"
372+
fi
373+
;;
374+
esac
375+
}

lib/helper.sh renamed to lib/styles.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ S_ERROR="${RED}"
3232
I_OK="";
3333
I_TIME="";
3434
I_STOP="🚫";
35-
I_ERROR="";
36-
I_END="👋🏻"
35+
I_ERROR="";
36+
I_WARN="❗️";
37+
I_END="🏁";

0 commit comments

Comments
 (0)