##@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 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" # 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 } function semver_compare_prelease() { # args: prelease1 prelease2 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 } 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 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 } function semver_compare_metadata() { # args: metadata1 metadata2 # même algo que pour prelease semver_compare_prelease "$@" } 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"; } 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"; } 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 "$@" }