commit 6474b0ba3ae624180293f4e38be3723c06dbf0c8 Author: yafox Date: Tue Nov 24 21:28:40 2020 +0000 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..12f1d98 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +format/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bd8c239 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2020 "yafox" + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README b/README new file mode 100644 index 0000000..af05285 --- /dev/null +++ b/README @@ -0,0 +1,68 @@ +vercmp +====== + +51 SLOC, not counting format scripts. + +vercmp evaluates a version comparison expression and prints "yes" if the +expression evaluates to true and "no" otherwise. + +vercmp can be extended with additional formats by adding a shell script defining +a `comparever` function to the `format` subdirectory. no `format` subdirectory +is included by default. to make bootstrapping easier, instructions for pulling +some are included in the makefile. if bootstrapping lix os, for example, the +following will `git clone` lix os' vercmp formats into the format directory: + + make lix-os-formats + +or, if wanting a basis for creating one's own formats using the same foundatiion +as lix os' formats: + + make bare-formats + +to install, just `make install`. + +usage: + + vercmp [format] + vercmp formats + +comparison string: + " " + +op: + == equal + >= greater than or equal + <= less than or equal + > greater than + < less than + +format: + the name of the format to use for parsing and comparing the versions. + see 'vercmp formats' for a list of formats. + (format scripts are kept in $VERCMPROOT/format) + +## examples + + $ vercmp "1.2.3 >= 3.2.1" + no + + $ vercmp "1.2 == 1.2" + yes + + $ vercmp "1.2+meta1 == 1.2+meta2" + yes + + $ vercmp "1.2+meta1 > 1.2-rc1+meta2" + yes + + $ vercmp "1.2-rc1 < 1.2-rc2" + yes + +## caveat + +vercmp format scripts assume both versions are in the same format. if this is +not the case, undefined behavior may ensue. even a simple variation like the +following can have unexpected results: + + $ vercmp "1.2 == 1.2.0" + no diff --git a/makefile b/makefile new file mode 100644 index 0000000..06b9e91 --- /dev/null +++ b/makefile @@ -0,0 +1,20 @@ +SRCDIR = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) +PREFIX ?= /usr +DESTDIR ?= $(PREFIX)/bin +VERCMPROOT ?= $(PREFIX)/share/vercmp +GITBASE ?= $(shell realpath $(shell git config --get remote.origin.url) | rev | \ + cut -d/ -f2- | rev) + +lix-os-vercmp: + git clone $(GITBASE)/vercmp-lix-os-formats format + +bare-vercmp: + git clone $(GITBASE)/vercmp-bare-formats format + +install: $(SRCDIR)/format + ln -sf $(SRCDIR) $(VERCMPROOT) + ln -sf $(VERCMPROOT)/vercmp.sh $(DESTDIR)/vercmp + +uninstall: + rm $(DESTDIR)/vercmp + rm $(VERCMPROOT) diff --git a/sloc.sh b/sloc.sh new file mode 100755 index 0000000..167e877 --- /dev/null +++ b/sloc.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# find all *.sh files not under `format`, strip all trailing whitespace, then +# all leading whitespace, then all lines starting with '#', then all empty +# lines, and then count the remaining lines. + +find . -name "*.sh" ! -path "**/format/**" \ +| xargs sed 's/[[:space:]]*$//g; s/^[[:space:]]*//g; s/^#.*$//g; /^$/d' \ +| wc -l - \ +| cut -d' ' -f1 + +# note that this script's ELOC is also included in the count. diff --git a/vercmp.sh b/vercmp.sh new file mode 100755 index 0000000..f5883f8 --- /dev/null +++ b/vercmp.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +set -e + +# if this is running on an interactive terminal (as opposed to in a script), +# and if tput is installed and knows some color codes... +if [ -t 1 ] && [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]; then + _clr="$(tput sgr0)" + _red="$(tput setaf 1)" +fi +err() { echo "$_red[ERR]$_clr $@" >&2; exit 1; } + +VERCMPROOT="$(dirname "$(readlink -f "$0")")" + +[ "$1" ] || cat <] + $(basename $0) formats + +comparison string: + " " + +op: + == equal + != not equal + >= greater than or equal + <= less than or equal + > greater than + < less than + +format: + the name of the format to use for parsing and comparing the versions. + see '$(basename $0) formats' for a list of formats. + (format scripts are kept in $VERCMPROOT/format) +EOF + +[ -d "$VERCMPROOT/format" ] \ +|| err "no format directory! install one. see makefile or README for details." + +if [ "$1" = "formats" ]; then + ls $VERCMPROOT/format/*.sh | sed -e 's/.*\/\(.*\).sh/\1/' + exit 0 +fi + +[ "$1" = "-f" ] && { fmt="$2"; shift; shift; } || fmt="default" + +# make $fmt available to version format scripts +export fmt + +v1="$(echo "$1" | awk '{ print $1 }')" +op="$(echo "$1" | awk '{ print $2 }')" +v2="$(echo "$1" | awk '{ print $3 }')" + +[ "$v2" ] || err "could not determine second version to use in comparison!" + +[ -e "$VERCMPROOT/format/$fmt.sh" ] || err "unrecognized version format: $fmt" + +. "$VERCMPROOT/format/$fmt.sh" + +# 'comparever' returns =, <, or > +relation="$(comparever $v1 $v2)" + +no() { echo "no" && exit 0; } +case $op in + '!=') [ "$relation" != "=" ] || no ;; + '=='|'='|'>'|'<'|'>='|'<=') [ "${op#*$relation}" != "${op}" ] || no ;; + *) err "unrecognized operator: $op" ;; +esac +echo "yes"