summaryrefslogtreecommitdiffstats
path: root/eclass/version.eclass
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2024-03-12 20:48:29 +0100
committerAnton Luka Šijanec <anton@sijanec.eu>2024-03-12 20:48:29 +0100
commita4c48186950ff6fc2fc90800d14eede98e8789a7 (patch)
tree9f0c10e4dfa0190040393c1ea5c6b05f7f0bcfc6 /eclass/version.eclass
parentsearc-0.0.27 (diff)
downloadg-a4c48186950ff6fc2fc90800d14eede98e8789a7.tar
g-a4c48186950ff6fc2fc90800d14eede98e8789a7.tar.gz
g-a4c48186950ff6fc2fc90800d14eede98e8789a7.tar.bz2
g-a4c48186950ff6fc2fc90800d14eede98e8789a7.tar.lz
g-a4c48186950ff6fc2fc90800d14eede98e8789a7.tar.xz
g-a4c48186950ff6fc2fc90800d14eede98e8789a7.tar.zst
g-a4c48186950ff6fc2fc90800d14eede98e8789a7.zip
Diffstat (limited to '')
-rw-r--r--eclass/version.eclass257
1 files changed, 257 insertions, 0 deletions
diff --git a/eclass/version.eclass b/eclass/version.eclass
new file mode 100644
index 0000000..b0f3264
--- /dev/null
+++ b/eclass/version.eclass
@@ -0,0 +1,257 @@
+# Copyright 2023
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: version.eclass
+# @MAINTAINER:
+# Ryan Qian <i@bitbili.net>
+# @AUTHOR:
+# Ryan Qian <i@bitbili.net>
+# @SUPPORTED_EAPIS: 7 8
+# @BLURB: functions to handle the version number
+# @DESCRIPTION:
+# This eclass provides functions to handle the version number.
+
+if [[ -z ${_ECLASS_VERSION} ]]; then
+_ECLASS_VERSION=1
+
+# @ECLASS_VARIABLE: VERSION_COMPARED_PARTS
+# @DESCRIPTION:
+# the version parts to compare, default is the full parts,
+# avaliable values are:
+# major # major parts
+# minor # major and minor parts
+# patch # major, minor and patch parts
+# full # major, minor, patch and pre-release parts
+VERSION_COMPARED_PARTS="full"
+
+# @FUNCTION: _version_compare_ver
+# @INTERNAL
+# @DESCRIPTION:
+# _version_compare_ver sub function
+_version_compare_ver() {
+ debug-print-function "${FUNCNAME}" "${@}"
+
+ local v0=${1} v1=${2} is_num=1 res=
+ if [[ ! ${v0} =~ ^[0-9]+$ ]] || [[ ! ${v1} =~ ^[0-9]+$ ]]; then
+ is_num=0
+ : "${v0/-1/\\/}"
+ : "${v1/-1/\\/}"
+ fi
+ if [[ ${is_num} == 1 ]]; then
+ if (( ${v0} > ${v1} )); then
+ res="g"
+ elif (( ${v0} == ${v1} )); then
+ res="e"
+ elif (( ${v0} < ${v1} )); then
+ res="l"
+ fi
+ else
+ if [[ ${v0} > ${v1} ]]; then
+ res="g"
+ elif [[ ${v0} == ${v1} ]]; then
+ res="e"
+ elif [[ ${v0} < ${v1} ]]; then
+ res="l"
+ fi
+ fi
+ echo -n "${res}"
+}
+
+# @FUNCTION: _version_compare
+# @INTERNAL
+# @DESCRIPTION:
+# _version_compare sub function
+_version_compare() {
+ debug-print-function "${FUNCNAME}" "${@}"
+
+ local v0 v1 vv0 vv1 len _len res
+ OIFS=$IFS; IFS="."
+ v0=(${1}) v1=(${2})
+ IFS=$OIFS
+ if [[ ${#v0[@]} -ge ${#v1[@]} ]]; then
+ len=${#v0[@]}
+ else
+ len=${#v1[@]}
+ fi
+ case $VERSION_COMPARED_PARTS in
+ major)
+ _len=1
+ ;;
+ minor)
+ _len=2
+ ;;
+ patch)
+ _len=3
+ ;;
+ esac
+ if [[ -n $_len && $_len -lt $len ]]; then
+ len=$_len
+ fi
+ for (( i=0; i<${len}; i++ )); do
+ vv0=${v0[$i]:--1}
+ vv1=${v1[$i]:--1}
+ res=$(_version_compare_ver ${vv0} ${vv1})
+ if [[ ${res} != "e" ]]; then
+ break
+ fi
+ done
+ echo -n "${res}"
+}
+
+# @FUNCTION: version_compare
+# @USAGE: g|ge|l|le|e STRING0 STRING1
+# @DESCRIPTION:
+# Compare the version numbers contained in the two strings to determine their precedence
+# according to the specifications defined in https://semver.org/spec/v2.0.0.html
+# The build metadata will be ignored.
+#
+# The prefixed package name will be removed automatically if exists.
+#
+# options:
+#
+# g: compare if the version contained in STRING0 is greater than the version in STRING1
+# ge: compare if the version contained in STRING0 is greater than or equal to the version in STRING1
+# l: compare if the version contained in STRING0 is less than the version in STRING1
+# le compare if the version contained in STRING0 is less than or equal to the version in STRING1
+# e: compare if the version contained in STRING0 is equal to the version in STRING1
+#
+# The return code is
+#
+# 0: when the above comparison holds
+# 1: when the above comparison does not hold
+#
+version_compare() {
+ debug-print-function "${FUNCNAME}" "${@}"
+
+ local LC_ALL=C
+ local action result
+ case ${1} in
+ g|ge|l|le|e)
+ action="${1}"
+ ;;
+ *)
+ die "unexpected argument '${1}'"
+ ;;
+ esac
+ shift
+
+ local -a str0 str1
+ local str0_pkgname str0_ver str0_pre
+ local str1_pkgname str1_ver str1_pre
+
+ OIFS=$IFS; IFS="-"
+ str0=( ${1} ) str1=( ${2} )
+ IFS=$OIFS
+
+ for _str in "str0" "str1"; do
+ local _strA="${_str}[@]" _strV="${_str}_ver" _strP="${_str}_pre" _strN="${_str}_pkgname"
+ for _s in "${!_strA}"; do
+ if [[ -n ${!_strV} ]]; then
+ eval "${_str}_pre=\"${_s}\""
+ elif [[ ${_s} =~ ^[vV]?[0-9]+\.? ]]; then
+ _s="${_s#v}"
+ eval "${_str}_ver=\"${_s#V}\""
+ else
+ if [[ -n ${!_strN} ]]; then
+ eval "${_str}_pkgname+=\"-\""
+ fi
+ eval "${_str}_pkgname+=\"${_s}\""
+ fi
+ done
+ done
+
+ if [[ ${str0_pkgname} != ${str1_pkgname} ]]; then
+ die "compare with different package names '${str0_pkgname}', '${str1_pkgname}'"
+ fi
+
+ result=$(_version_compare ${str0_ver} ${str1_ver})
+ if [[ ${result} == "e" ]]; then
+ result=$(_version_compare ${str0_pre:-zzzz} ${str1_pre:-zzzz})
+ fi
+
+ if [[ ${result} =~ [${action}] ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# @FUNCTION: version_make_range
+# @USAGE: CURRENT_RANGE NEW_CONDITION
+# @DESCRIPTION:
+# create a version range through the NEW_CONDITION
+# input format:
+# CURRENT_RANGE: ">[=] version-str <[=] version-str"
+# NEW_CONDITION: "(>|<)[=] version-str"
+# output:
+# NEW_RANGE: ">[=] version-str <[=] version-str"
+version_make_range() {
+ debug-print-function "${FUNCNAME}" "${@}"
+
+ if [[ -z $2 ]]; then
+ die "no new condition provided"
+ fi
+
+ local oS vS oE vE o v equal replace
+ read -r oS vS oE vE <<<"$1"
+ read -r o v <<<"$2"
+ if [[ ! $o =~ ^[\>\<]=?$ ]] || ! version_is_valid $v; then
+ die "wrong format of the new condition"
+ fi
+ if [[ ${o:1:1} == "=" ]]; then
+ equal=1
+ fi
+ case ${o:0:1} in
+ ">")
+ if [[ -z $oS ]]; then
+ replace=1
+ elif [[ ${oS:1:1} == "=" ]] && \
+ version_compare ge $v $vS; then
+ replace=1
+ else
+ if [[ -n $equal ]] && \
+ version_compare g $v $vS; then
+ replace=1
+ elif version_compare ge $v $vS; then
+ replace=1
+ fi
+ fi
+ if [[ -n $replace ]]; then
+ oS=$o
+ vS=$v
+ fi
+ ;;
+ "<")
+ if [[ -z $oE ]]; then
+ replace=1
+ elif [[ ${oE:1:1} == "=" ]] && \
+ version_compare le $v $vE; then
+ replace=1
+ else
+ if [[ -n $equal ]] && \
+ version_compare le $v $vE; then
+ replace=1
+ elif version_compare l $v $vE; then
+ replace=1
+ fi
+ fi
+ if [[ -n $replace ]]; then
+ oE=$o
+ vE=$v
+ fi
+ ;;
+ esac
+
+ echo -n "${oS:->=} ${vS:-0} ${oE:-<=} ${vE:-9999}"
+}
+
+# @FUNCTION: version_is_valid
+# @USAGE: version-str
+# @DESCRIPTION:
+# check the version-str is a valid semantic version
+version_is_valid() {
+ # TODO
+ :
+}
+
+fi