1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
#!/usr/bin/env bash
set -o errexit -o nounset -o pipefail
SEMVER_REGEX="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$"
PROG=semver
PROG_VERSION=1.0.0
VERSION_FILE=vulndb/version.txt
DEFAULT_VERSION=0.1.0
USAGE="\
Usage:
$PROG
$PROG init [<version>]
$PROG bump [(major|minor|patch|prerel <prerel>|build <build>) | --force <version>] [--pretend]
$PROG compare <version> [<oldversion>]
$PROG --help
$PROG --version
Arguments:
<version> A version must match the following regex pattern:
\"${SEMVER_REGEX}\".
In english, the version must match X.Y.Z(-PRERELEASE)(+BUILD)
where X, Y and Z are positive integers, PRERELEASE is an optionnal
string composed of alphanumeric characters and hyphens and
BUILD is also an optional string composed of alphanumeric
characters and hyphens.
<oldversion> See <version> definition.
<prerel> String that must be composed of alphanumeric characters and hyphens.
<build> String that must be composed of alphanumeric characters and hyphens.
Options:
-f, --force=<version> Forces a bump of any version without checking if it
respects semver bumping rules.
-p, --pretend Do not overwrite the project's version file, only
output what the new version string would be.
-v, --version Print the version of this tool.
-h, --help Print this help message.
Commands:
init initialize this project's version.
bump this project's version by one of major, minor, patch, prerel, build
or a forced potentialy conflicting version.
compare <version> to this project's version or to provided <oldversion>."
function warning {
echo -e "$1" >&2
}
function error {
echo -e "$1" >&2
exit 1
}
function usage-help {
error "$USAGE"
}
function usage-version {
echo -e "${PROG}: $PROG_VERSION"
exit 0
}
function validate-version {
local version=$1
if [[ "$version" =~ $SEMVER_REGEX ]]; then
# if a second argument is passed, store the result in var named by $2
if [ "$#" -eq "2" ]; then
local major=${BASH_REMATCH[1]}
local minor=${BASH_REMATCH[2]}
local patch=${BASH_REMATCH[3]}
local prere=${BASH_REMATCH[4]}
local build=${BASH_REMATCH[5]}
eval "$2=(\"$major\" \"$minor\" \"$patch\" \"$prere\" \"$build\")"
else
echo "$version"
fi
else
error "version $version does not match the semver scheme 'X.Y.Z(-PRERELEASE)(+BUILD)'. See help for more information."
fi
}
# this function will reverse-traverse folders until VERSION_FILE is found
# or '/' is reached.
function get-version {
while [ -w . ]; do
if [ -e $VERSION_FILE ]; then
validate-version "$(cat $VERSION_FILE)"
return 0
fi
pushd .. > /dev/null
done
error "Version file $VERSION_FILE not found, you may want to initialize this project with 'version init'"
}
function compare-version {
validate-version "$1" V
validate-version "$2" V_
# MAJOR, MINOR and PATCH should compare numericaly
for i in 0 1 2; do
case $((${V[$i]} - ${V_[$i]})) in
0) ;;
-[0-9]*) echo -1; return 0;;
[0-9]*) echo 1; return 0 ;;
esac
done
# PREREL should compare with the ASCII order.
if [[ "${V[3]}" > "${V_[3]}" ]]; then
echo 1; return 0;
elif [[ "${V[3]}" < "${V_[3]}" ]]; then
echo -1; return 0;
fi
echo 0
}
function cli-print {
get-version
exit 0
}
function command-init {
local version=""
case $# in
0) version="$DEFAULT_VERSION" ;;
1) version=$(validate-version "$1") ;;
2) usage-help;;
esac
if [ -e "$VERSION_FILE" ]; then
error "version file $VERSION_FILE exists, cannot initialize project. Either remove the current file or use 'version bump --force <newversion>'."
fi
echo "$version" | tee "$VERSION_FILE"
exit 0
}
function command-bump {
local new; local pretend=0; local version=$(get-version)
validate-version $version split
local major=${split[0]}
local minor=${split[1]}
local patch=${split[2]}
local prere=${split[3]}
local build=${split[4]}
while [[ $# -gt 0 ]]; do
case "$1" in
major) new="$(($major + 1)).0.0"; shift ;;
minor) new="${major}.$(($minor + 1)).0"; shift ;;
patch) new="${major}.${minor}.$(($patch + 1))"; shift ;;
prerel)
if [[ $# -lt 2 ]]; then
usage-help
else
new=$(validate-version "${major}.${minor}.${patch}-${2}")
shift 2
fi ;;
build)
if [[ $# -lt 2 ]]; then
usage-help
else
new=$(validate-version "${major}.${minor}.${patch}${prere}+${2}")
shift 2
fi ;;
--force|-f)
if [[ $# -lt 2 ]]; then
usage-help
else
new=$(validate-version "$2")
shift 2
fi ;;
--pretend|-p) pretend=1; shift ;;
"") break;;
*) usage-help ;;
esac
done
if [[ "$pretend" -eq 1 ]]; then
echo $new
else
echo $new | tee $VERSION_FILE
fi
exit 0
}
function command-compare {
local v; local v_; local version=$(get-version)
case $# in
0) usage-help ;;
1) v=$(validate-version "$1"); v_=$version ;;
2) v=$(validate-version "$1"); v_=$(validate-version "$2") ;;
esac
echo $(compare-version "$v" "$v_")
exit 0
}
case $# in
0) cli-print ;;
esac
case $1 in
--help|-h) echo -e "$USAGE"; exit 0;;
--version|-v) usage-version ;;
init) shift; command-init $@;;
bump) shift; command-bump $@;;
compare) shift; command-compare $@;;
*) echo "Unknown arguments: $@"; usage-help;;
esac
|