nutools/lib/ulib/semver

325 lines
11 KiB
Plaintext
Raw Normal View History

##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Versionnage sémantique
##@cooked nocomments
##@require base
uprovide semver
urequire base
2014-01-18 12:04:44 +04:00
function __semver_check_version() { [ -z "${1//[a-zA-Z0-9.+-]/}" ]; }
function __semver_check_prelease() { [ -z "${1//[a-zA-Z0-9.-]/}" ]; }
function __semver_check_metadata() { [ -z "${1//[a-zA-Z0-9.-]/}" ]; }
function semver_parse() {
# args: version majorV minorV patchlevelV preleaseV metadataV validV
local __p_ver="$1"
local __p_ma="${2:-major}" __p_mi="${3:-minor}" __p_pl="${4:-patchlevel}"
local __p_pr="${5:-prelease}" __p_md="${6:-metadata}" __p_va="${7:-valid}"
local __p_tmp
setv "$__p_ma" ""
setv "$__p_mi" ""
setv "$__p_pl" ""
array_new "$__p_pr"
array_new "$__p_md"
setv "$__p_va" ""
# vérifier les caractères valides
__semver_check_version "$__p_ver" || return 1
# extraire major
__p_tmp=
while [ "${__p_ver/#[0-9]/}" != "$__p_ver" ]; do
__p_tmp="$__p_tmp${__p_ver:0:1}"
__p_ver="${__p_ver:1}"
done
[ "${__p_ver:0:1}" == . ] || return 1
__p_ver="${__p_ver:1}"
setv "$__p_ma" "$__p_tmp"
2015-08-20 07:58:17 +04:00
# extraire minor
__p_tmp=
while [ "${__p_ver/#[0-9]/}" != "$__p_ver" ]; do
__p_tmp="$__p_tmp${__p_ver:0:1}"
__p_ver="${__p_ver:1}"
done
[ "${__p_ver:0:1}" == . ] || return 1
__p_ver="${__p_ver:1}"
setv "$__p_mi" "$__p_tmp"
# extraire patchlevel
__p_tmp=
while [ "${__p_ver/#[0-9]/}" != "$__p_ver" ]; do
__p_tmp="$__p_tmp${__p_ver:0:1}"
__p_ver="${__p_ver:1}"
done
[ -z "$__p_ver" -o "${__p_ver:0:1}" == - -o "${__p_ver:0:1}" == + ] || return 1
setv "$__p_pl" "$__p_tmp"
# extraire prelease
if [ "${__p_ver:0:1}" == - ]; then
__p_ver="${__p_ver:1}"
if [[ "$__p_ver" == *+* ]]; then
__p_tmp="${__p_ver%%+*}"
__p_ver="+${__p_ver##*+}"
else
__p_tmp="$__p_ver"
__p_ver=
fi
__semver_check_prelease "$__p_tmp" || return 1
array_split "$__p_pr" "$__p_tmp" .
fi
# extraire metadata
if [ "${__p_ver:0:1}" == + ]; then
__p_ver="${__p_ver:1}"
__p_tmp="$__p_ver"
__p_ver=
__semver_check_metadata "$__p_tmp" || return 1
array_split "$__p_md" "$__p_tmp" .
fi
# on doit avoir tout analysé
[ -z "$__p_ver" ] || return 1
setv "$__p_va" 1
return 0
}
function semver_incmajor() {
# args: majorV minorV patchlevelV preleaseV metadataV maven_update setprelease
if [ -z "$6" ]; then
setv "$1" $((${!1} + 1))
setv "$2" 0
setv "$3" 0
array_new "$4"
elif [ -z "$7" ]; then
# maven snapshot --> release
if [ ${!2} -ne 0 -o ${!3} -ne 0 ]; then
setv "$1" $((${!1} + 1))
setv "$2" 0
setv "$3" 0
fi
array_new "$4"
else
# maven release --> snapshot
setv "$2" $((${!2} + 1))
setv "$3" 0
array_split "$4" "$setprelease" .
fi
}
function semver_incminor() {
# args: majorV minorV patchlevelV preleaseV metadataV maven_update setprelease
if [ -z "$6" ]; then
setv "$2" $((${!2} + 1))
setv "$3" 0
array_new "$4"
elif [ -z "$7" ]; then
# maven snapshot --> release
if [ ${!3} -ne 0 ]; then
setv "$2" $((${!2} + 1))
setv "$3" 0
fi
array_new "$4"
else
# maven release --> snapshot
setv "$2" $((${!2} + 1))
setv "$3" 0
array_split "$4" "$setprelease" .
fi
}
function semver_incpatchlevel() {
# args: majorV minorV patchlevelV preleaseV metadataV maven_update setprelease
if [ -z "$6" ]; then
setv "$3" $((${!3} + 1))
array_new "$4"
elif [ -z "$7" ]; then
# maven snapshot --> release
:
else
# maven release --> snapshot
setv "$3" $((${!3} + 1))
array_split "$4" "$setprelease" .
fi
}
function semver_setversion() {
# args: version majorV minorV patchlevelV preleaseV metadataV
local __sv_ma __sv_mi __sv_svl __sv_svr __sv_md __sv_va
semver_parse "$1" __sv_ma __sv_mi __sv_pl __sv_pr __sv_md __sv_va
[ -n "$__sv_va" ] || return 1
setv "$2" "$__sv_ma"
setv "$3" "$__sv_mi"
setv "$4" "$__sv_pl"
array_copy "$5" __sv_pr
array_copy "$6" __sv_md
return 0
}
function semver_setprelease() {
# args: setprelease majorV minorV patchlevelV preleaseV metadataV
if [ -n "$1" ]; then
__semver_check_prelease "$1" || return 1
array_split "$5" "$1" .
else
array_new "$5"
fi
return 0
}
2014-01-18 12:14:14 +04:00
function semver_compare_prelease() {
# args: prelease1 prelease2
2014-01-18 23:07:41 +04:00
local -a __cp_pr1 __cp_pr2 __cp_len i __cp_v1 __cp_v2
array_copy __cp_pr1 "$1"
array_copy __cp_pr2 "$2"
if [ ${#__cp_pr1[*]} -eq 0 -a ${#__cp_pr2[*]} -eq 0 ]; then
# final == final
echo eq; return
elif [ ${#__cp_pr1[*]} -gt 0 -a ${#__cp_pr2[*]} -eq 0 ]; then
# prelease < final
echo lt; return
elif [ ${#__cp_pr1[*]} -eq 0 -a ${#__cp_pr2[*]} -gt 0 ]; then
# final > prelease
echo gt; return
fi
# calculer le nombre d'éléments à comparer dans les deux tableaux soit
# min(len(__cp_pr1), len(__cp_pr2))
__cp_len=${#__cp_pr1[*]}
[ ${#__cp_pr2[*]} -lt $__cp_len ] && __cp_len=${#__cp_pr2[*]}
# comparer __cp_len éléments
i=0
while [ $i -lt $__cp_len ]; do
__cp_v1="${__cp_pr1[$i]}"
__cp_v2="${__cp_pr2[$i]}"
if [ "$__cp_v1" == "$__cp_v2" ]; then
:
elif isnum "$__cp_v1" && isnum "$__cp_v2"; then
if [ $__cp_v1 -lt $__cp_v2 ]; then
echo lt; return
elif [ $__cp_v1 -gt $__cp_v2 ]; then
echo gt; return
fi
elif isnum "$__cp_v1"; then
echo lt; return
elif isnum "$__cp_v2"; then
echo gt; return
else
# comparaison chaine
if [ "$(echo "$__cp_v1"$'\n'"$__cp_v2" | LANG=C sort | head -n1)" == "$__cp_v1" ]; then
echo lt; return
else
echo gt; return
fi
fi
i=$(($i + 1))
done
# comparer ce qui reste
__cp_pr1=("${__cp_pr1[@]:$__cp_len}")
__cp_pr2=("${__cp_pr2[@]:$__cp_len}")
if [ ${#__cp_pr1[*]} -gt 0 ]; then
echo gt; return
elif [ ${#__cp_pr2[*]} -gt 0 ]; then
echo lt; return
fi
# en définitive, c'est égal
echo eq
2014-01-18 12:14:14 +04:00
}
function semver_setmetadata() {
# args: setmetadata majorV minorV patchlevelV preleaseV metadataV
if [ -n "$1" ]; then
__semver_check_metadata "$1" || return 1
array_split "$6" "$1" .
else
2015-03-05 09:43:00 +04:00
array_new "$6"
fi
return 0
}
function semver_addmetadata() {
# args: addmetadata majorV minorV patchlevelV preleaseV metadataV
if [ -n "$1" ]; then
__semver_check_metadata "$1" || return 1
local -a __sam_metadata
array_split __sam_metadata "$1" .
array_extend "$6" __sam_metadata
fi
return 0
}
2014-01-18 12:14:14 +04:00
function semver_compare_metadata() {
# args: metadata1 metadata2
2014-01-18 23:07:41 +04:00
# même algo que pour prelease
semver_compare_prelease "$@"
2014-01-18 12:14:14 +04:00
}
function semver_copy() {
# args: majorDV minorDV patchlevelDV preleaseDV metadataDV majorSV minorSV patchlevelSV preleaseSV metadataSV
setv "$1" "${!6}"
setv "$2" "${!7}"
setv "$3" "${!8}"
array_copy "$4" "$9"
array_copy "$5" "${10}"
}
function semver_build() {
# args: majorV minorV patchlevelV preleaseV metadataV
echo_ "${!1}.${!2}.${!3}"
array_isempty "$4" || recho_ "-$(array_join "$4" .)"
array_isempty "$5" || recho_ "+$(array_join "$5" .)"
echo ""
}
function semver_setvar() {
# args: versionV majorV minorV patchlevelV preleaseV metadataV
setv "$1" "$(semver_build "$2" "$3" "$4" "$5" "$6")"
}
################################################################################
# Les fonctions psemver_* sont comme semver_* mais les noms de variables sont
# standardisés (major, minor, pathchlevel, prelease, metadata) et l'on spécifie
# uniquement un préfixe pour les noms de variable
function psemver_parse() { semver_parse "$1" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata" "${2}valid"; }
function psemver_incmajor() { semver_incmajor "${1}major" "${1}minor" "${1}patchlevel" "${1}prelease" "${2}metadata" "$2" "$3"; }
function psemver_incminor() { semver_incminor "${1}major" "${1}minor" "${1}patchlevel" "${1}prelease" "${2}metadata" "$2" "$3"; }
function psemver_incpatchlevel() { semver_incpatchlevel "${1}major" "${1}minor" "${1}patchlevel" "${1}prelease" "${2}metadata" "$2" "$3"; }
function psemver_setversion() { semver_setversion "$1" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata"; }
function psemver_setprelease() { semver_setprelease "$1" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata"; }
2014-01-18 12:14:14 +04:00
function psemver_compare_prelease() { semver_compare_prelease "${1}prelease" "${2}prelease"; }
function psemver_setmetadata() { semver_setmetadata "$1" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata"; }
function psemver_addmetadata() { semver_addmetadata "$1" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata"; }
2014-01-18 12:14:14 +04:00
function psemver_compare_metadata() { semver_compare_metadata "${1}metadata" "${2}metadata"; }
function psemver_copy() { semver_copy "${1}major" "${1}minor" "${1}patchlevel" "${1}prelease" "${1}metadata" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata"; }
function psemver_build() { semver_build "${1}major" "${1}minor" "${1}patchlevel" "${1}prelease" "${1}metadata"; }
function psemver_setvar() { semver_setvar "$1" "${2}major" "${2}minor" "${2}patchlevel" "${2}prelease" "${2}metadata"; }
function psemver_setprmd() {
local setprelease="$2" resetmetadata="$3" setmetadata="$4" addmetadata="$5"
psemver_setprelease "$setprelease" "$1" || return 2
# XXX pas encore implémenté
local setalpha setbeta setrc
if [ -n "$setalpha" ]; then :
elif [ -n "$setbeta" ]; then :
elif [ -n "$setrc" ]; then :
fi
[ -n "$resetmetadata" ] && psemver_setmetadata "" "$1"
if [ -n "$setmetadata" ]; then
psemver_setmetadata "$setmetadata" "$1" || return 3
fi
if [ -n "$addmetadata" ]; then
psemver_addmetadata "$addmetadata" "$1" || return 4
fi
return 0
}
function psemver_incsetprmd() {
local setprelease="$3" resetmetadata="$4" setmetadata="$5" addmetadata="$6" maven_update="$7"
[ -n "$1" ] && "psemver_inc$1" "$2" "$maven_update" "$setprelease"
shift
psemver_setprmd "$@"
}