Skip to content

Instantly share code, notes, and snippets.

@hypersoft
Last active December 19, 2015 13:19
Show Gist options
  • Save hypersoft/5961125 to your computer and use it in GitHub Desktop.
Save hypersoft/5961125 to your computer and use it in GitHub Desktop.
Build No. Automated build number tracking utility
#!/bin/bash
declare -i MAJOR="0"
declare -i MINOR="0"
declare -i MINORMAX="99"
declare -i REVISION="0"
declare -i REVISIONMAX="9999"
buildnum ()
{
: "A self replicating build number database script";
: "Written by Triston J. Taylor (C) 2013 All Rights Reserved";
function noBiDiRequest () {
((generate)) || {
echo "$0: error: bi-directional request: set for information in progress; prognostic: terminate";
exit 1;
} 1>&2
};
function acceptFinalOption ()
{
noBiDiRequest;
(($# > 1)) && {
echo "$0: invocation error: option $1 must be the final argument";
exit 1
} 1>&2
};
function acceptFinalArgument ()
{
(($# > 2)) && {
echo "$0: invocation error: option $1 argument '$2' must be the final argument";
exit 1
} 1>&2
};
function catdb ()
{
printf "%s\n\n%s\n\n%s\n\n%s;\n\n" '#!/bin/bash' "`declare -p MAJOR MINOR MINORMAX REVISION REVISIONMAX`" "`declare -f buildnum`" 'buildnum "$@"'
};
local -i update=1 generate=1 report=1;
local target="$0";
while [[ "${1:0:1}" = - ]]; do
[[ $1 == '-g' ]] && {
acceptFinalOption "$@";
printf "%i.%i.%i\\n" $MAJOR $MINOR $REVISION;
return 0
};
: "Pass option -G to get the verbose current build info";
[[ $1 == '-G' ]] && {
acceptFinalOption "$@";
printf "Build No. %i.%i.%i\\n" $MAJOR $MINOR $REVISION;
return 0
};
: "Pass option -m to manually increment minor";
[[ $1 == '-m' ]] && {
let REVISION=$((REVISIONMAX + 1));
shift;
continue
};
: "Pass option -M to manually increment major";
[[ $1 == '-M' ]] && {
let MINOR=$((MINORMAX + 1));
shift;
continue
};
: "Pass option -p to preview the next build number";
[[ $1 == '-p' ]] && {
let update=0 generate=1;
shift;
continue
};
: "Pass option -P to preview the verbose next build number";
[[ $1 == '-P' ]] && {
printf "Build No. ";
let update=0 generate=1;
shift;
continue
};
: "Pass option -q to mute generate -> report";
: "This option adversely affects -p and -P";
[[ $1 == '-q' ]] && {
let report=0;
shift;
continue
};
: "Pass option -smm INTEGER to set the MINORMAX";
[[ $1 == '-smm' ]] && {
let MINORMAX=$2 generate=0;
shift 2;
continue
};
: "Pass option -gmm to get the MINORMAX";
[[ $1 == '-gmm' ]] && {
acceptFinalOption "$@";
echo MINORMAX=$MINORMAX;
return 0
};
: "Pass option -srm INTEGER to set the REVISIONMAX";
[[ $1 == '-srm' ]] && {
let REVISIONMAX=$2 generate=0;
shift 2;
continue
};
: "Pass option -grm to get the REVISIONMAX";
[[ $1 == '-grm' ]] && {
acceptFinalOption "$@";
echo REVISIONMAX=$REVISIONMAX;
return 0
};
: "Pass option -c to clear the build number database";
: "Pass option -c FILE to create a new build number database";
[[ $1 == '-c' ]] && {
acceptFinalArgument "$@";
declare -i MAJOR="0" MINOR="0" REVISION="0";
target="${2:-$target}";
catdb > "$target";
chmod +x "$target";
return 0
};
printf "$0: invocation error: unrecognized option: %s\n" "$1" 1>&2;
exit 1;
done;
((generate)) && {
let REVISION++;
(( REVISION > REVISIONMAX )) && {
let MINOR++ REVISION=0
};
(( MINOR > MINORMAX )) && {
let MAJOR++ MINOR=0 REVISION=0
};
((report)) && printf "%i.%i.%i\\n" $MAJOR $MINOR $REVISION
};
((update)) && catdb > "$target"
}
buildnum "$@";
@hypersoft
Copy link
Author

R8 introduces several new features by adding an internal generate flag. For example now we can do something like this:

./buildnum -c foo;
./foo
./foo -srm 0 -P

Which does not actually set REVISIONMAX on the database, because the -P option turns the update flag off and activates the generate flag (which the -s*m options) explicitly deactivate. The result is a preview of the next build number given the specified REVISIONMAX.

-srm and -smm can be used to set the REVISIONMAX, and MINORMAX respectively on the current database and new ones as well, created with -c option:

./buildnum -smm 99 -srm 999 -c foo

The -c option is a weird one (aren't they all...) When supplied, it must always be the last argument, because the input from other arguments affect its operation, as well as the fact that it terminates script execution.

External utilities can access the REVISIONMAX and MINORMAX components by supplying -grm and -gmm respectively.

@hypersoft
Copy link
Author

R9 adds error checking for options and arguments which must be supplied as the last invocation parameters.

@hypersoft
Copy link
Author

R10 adds bi-directional request exception handling and the ability to mute a generated report.

@hypersoft
Copy link
Author

R11 permits bi-di create exception

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment