ajout de array_eq

ajout de ulib/semver et uversion pour la gestion des versions sémantiques
This commit is contained in:
Jephte CLAIN 2014-01-18 02:05:45 +04:00
parent e2d354dadb
commit f1918c19e6
4 changed files with 391 additions and 1 deletions

View File

@ -1 +1 @@
17
18

View File

@ -516,6 +516,19 @@ function array_fillrange() {
done
array_copy "$1" __af_vs
}
function array_eq() {
# tester l'égalité des tableaux $1 et $2
local __ae_c1="#$1[*]" __ae_c2="#$2[*]"
[ ${!__ae_c1} -eq ${!__ae_c2} ] || return 1
local __ae_v1s="$1[@]" __ae_v1
local __ae_v2 __ae_i=0
for __ae_v1 in "${!__ae_v1s}"; do
__ae_v2="$2[$__ae_i]"
[ "$__ae_v1" == "${!__ae_v2}" ] || return 1
__ae_i=$(($__ae_i + 1))
done
return 0
}
function array_contains() {
# tester si le tableau dont le nom est $1 contient la valeur $2
local __ac_v

124
ulib/semver Normal file
View File

@ -0,0 +1,124 @@
##@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_parse() {
local _ver="$1" _ma="${2:-major}" _mi="${3:-minor}" _pl="${4:-patchlevel}" _pr="${5:-prelease}" _md="${6:-metadata}" _va="${7:-valid}"
local _tmp
set_var "$_ma" ""
set_var "$_mi" ""
set_var "$_pl" ""
array_new "$_pr"
array_new "$_md"
set_var "$_va" ""
# vérifier les caractères valides
[ -z "${_ver//[a-zA-Z0-9.+-]/}" ] || return 1
# extraire major
_tmp=
while [ "${_ver/#[0-9]/}" != "$_ver" ]; do
_tmp="$_tmp${_ver:0:1}"
_ver="${_ver:1}"
done
[ "${_ver:0:1}" == . ] || return 1
_ver="${_ver:1}"
set_var "$_ma" "$_tmp"
# extraire minor
_tmp=
while [ "${_ver/#[0-9]/}" != "$_ver" ]; do
_tmp="$_tmp${_ver:0:1}"
_ver="${_ver:1}"
done
[ "${_ver:0:1}" == . ] || return 1
_ver="${_ver:1}"
set_var "$_mi" "$_tmp"
# extraire patchlevel
_tmp=
while [ "${_ver/#[0-9]/}" != "$_ver" ]; do
_tmp="$_tmp${_ver:0:1}"
_ver="${_ver:1}"
done
[ -z "$_ver" -o "${_ver:0:1}" == - -o "${_ver:0:1}" == + ] || return 1
set_var "$_pl" "$_tmp"
# extraire prelease
if [ "${_ver:0:1}" == - ]; then
_ver="${_ver:1}"
if [[ "$_ver" == *+* ]]; then
_tmp="${_ver%%+*}"
_ver="+${_ver##*+}"
else
_tmp="$_ver"
_ver=
fi
array_split "$_pr" "$_tmp" .
fi
# extraire metadata
if [ "${_ver:0:1}" == + ]; then
_ver="${_ver:1}"
[[ "$_ver" == *+* ]] && return 1
_tmp="$_ver"
_ver=
array_split "$_md" "$_tmp" .
fi
# on doit avoir tout analysé
[ -z "$_ver" ] || return 1
set_var "$_va" 1
return 0
}
function semver_incmajor() {
set_var "$1" $((${!1} + 1))
set_var "$2" 0
set_var "$3" 0
array_new "$4"
}
function semver_incminor() {
set_var "$2" $((${!2} + 1))
set_var "$3" 0
array_new "$4"
}
function semver_incpatchlevel() {
set_var "$3" $((${!3} + 1))
array_new "$4"
}
function semver_setprelease() {
# XXX analyser $1 et spliter avant de copier dans le tableau $5
if [ "$1" ]; then
set_array "$5" @ "$1"
else
array_new "$5"
fi
}
function semver_setmetadata() {
# XXX analyser $1 et spliter avant de copier dans le tableau $6
if [ "$1" ]; then
set_array "$6" @ "$1"
else
array_new "$5"
fi
}
function semver_build() {
echo_ "${!1}.${!2}.${!3}"
array_isempty "$4" || rawecho_ "-$(array_join "$4" .)"
array_isempty "$5" || rawecho_ "+$(array_join "$5" .)"
echo ""
}
function semver_setvar() {
set_var "$1" "$(semver_build "$2" "$3" "$4" "$5" "$6")"
}

253
uversion Executable file
View File

@ -0,0 +1,253 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/ulib/ulib" || exit 1; urequire DEFAULTS semver
function display_help() {
uecho "$scriptname: gérer des numéros de version
USAGE
$scriptname [options]
OPTIONS
-f, --file VERSIONFILE
Gérer le numéro de version se trouvant dans le fichier spécifié. Le
fichier est créé si nécessaire. C'est l'option par défaut si un fichier
nommé VERSION.txt se trouve dans le répertoire courant.
-s, --string VERSION
Prendre pour valeur de départ le numéro de version spécifié
--show
Afficher le numéro de version. C'est l'action par défaut
--check
Vérifier que le numéro de version est conforme aux règles des versions
sémantiques (http://semver.org/)
--eq VERSION
--ne VERSION
--lt VERSION
--le VERSION
--gt VERSION
--ge VERSION
--same VERSION
--diff VERSION
Comparer avec la version spécifiée
eq, ne, lt, le, gt, ge ne testent pas la valeur des metadata
same et diff comparent aussi la valeur des metadata
-v, --set-version VERSION
Spécifier un nouveau numéro de version qui écrase la valeur actuelle.
Cette option ne devrait pas être utilisée parce qu'elle ne respecte pas
les règles du versionnage sémantique.
-u, --update
Mettre à jour le numéro de version.
--menu
Afficher un menu permettant de choisir le composant de la version à
incrémenter
-x, --major
Augmenter le numéro de version majeure
-z, --minor
Augmenter le numéro de version mineure. C'est la valeur par défaut.
-p, --patchlevel
Augmenter le numéro de patch
-l, --prelease ID
Spécifier un identifiant de prérelease, à ajouter au numéro de version.
-a, --alpha
-b, --beta
-r, --rc
Spécifier une pré-release de type alpha, beta, ou rc. Si la version est
déjà dans ce type, augmenter la dernière valeur numérique des composants
de l'identifiant, e.g. alpha deviant alpha.1, beta-1.2 devient beta-1.3,
rc1 devient rc2
-R, --final, --release
Supprimer l'identifiant de prérelease
-m, --metadata ID
Spécifier un identifiant de build, à ajouter au numéro de version."
}
action=auto
source=auto
file=
version=
operator=
oversion=
setversion=
incversion=
setprelease=
setalpha=
setbeta=
setrc=
setfinal=
setmetadata=
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \
-f:,--file: '$set@ file; source=' \
-s:,--string: '$set@ version; source=' \
--show action=show \
--check action=check \
--eq: '$action=compare; operator=eq; set@ oversion' \
--ne: '$action=compare; operator=ne; set@ oversion' \
--lt: '$action=compare; operator=lt; set@ oversion' \
--le: '$action=compare; operator=le; set@ oversion' \
--gt: '$action=compare; operator=gt; set@ oversion' \
--ge: '$action=compare; operator=ge; set@ oversion' \
-v:,--set-version: '$action=update; set@ setversion; incversion=' \
-u,--update '$action=update; [ -z "$incversion" ] && incversion=auto' \
--menu '$action=update; incversion=menu' \
-x,--major '$action=update; incversion=major' \
-z,--minor '$action=update; incversion=minor' \
-p,--patchlevel '$action=update; incversion=patchlevel' \
-l:,--prelease:,--prerelease: '$action=update; set@ setprelease' \
-a,--alpha '$action=update; setalpha=1; setbeta=; setrc=; setfinal=' \
-b,--beta '$action=update; setalpha=; setbeta=1; setrc=; setfinal=' \
-r,--rc '$action=update; setalpha=; setbeta=; setrc=1; setfinal=' \
-R,--release,--final '$action=update; setalpha=; setbeta=; setrc=; setfinal=1' \
-m:,--metadata: '$action=update; set@ setmetadata' \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
# Calculer la source
if [ "$source" == auto ]; then
for i in VERSION.txt version.txt; do
if [ -f "$i" ]; then
file="$i"
break
fi
done
[ -n "$file" ] || file=VERSION.txt
elif [ -n "$file" ]; then
[ "$action" == auto ] && action=update
fi
[ "$action" == auto ] && action=show
# Lire la version
if [ -n "$file" ]; then
[ -f "$file" ] && version="$(<"$file")"
[ -n "$version" ] || version=0.0.0
fi
# Actions
estepi "La version actuelle est $version"
[ "$action" == show ] && exit 0
# forcer le numéro de version
# XXX implémenter semver_setversion qui change juste la partie
# major.minor.patchlevel et ne touche pas au reste. une fois que cela sera fait,
# la ligne suivante doit être supprimée et le code de setversion doit être
# mis dans la partie "update"
[ -n "$setversion" ] && version="$setversion"
semver_parse "$version" major minor patchlevel prelease metadata valid
if [ "$action" == check ]; then
[ -n "$valid" ] || die "Numéro de version invalide: $version"
elif [ "$action" == compare ]; then
semver_parse "$oversion" omajor ominor opatchlevel oprelease ometadata ovalid
case "$operator" in
eq|same)
for var in valid major minor patchlevel; do
ovar="o$var"
[ "${!var}" == "${!ovar}" ] || exit 1
done
array_eq prelease oprelease || exit 1
if [ "$operator" == same ]; then
array_eq metadata ometadata || exit 1
fi
exit 0
;;
ne|diff)
for var in valid major minor patchlevel; do
ovar="o$var"
[ "${!var}" != "${!ovar}" ] && exit 0
done
! array_eq prelease oprelease && exit 0
if [ "$operator" == diff ]; then
! array_eq metadata ometadata && exit 0
fi
exit 1
;;
lt)
[ -z "$valid" -a -z "$ovalid" ] && exit 1
[ "$major" -lt "$omajor" ] && exit 0
[ "$major" -gt "$omajor" ] && exit 1
[ "$minor" -lt "$ominor" ] && exit 0
[ "$minor" -gt "$ominor" ] && exit 1
[ "$patchlevel" -lt "$opatchlevel" ] && exit 0
[ "$patchlevel" -gt "$opatchlevel" ] && exit 1
# XXX tester prelease
exit 1
;;
le)
[ -z "$valid" -a -z "$ovalid" ] && exit 1
[ "$major" -lt "$omajor" ] && exit 0
[ "$major" -gt "$omajor" ] && exit 1
[ "$minor" -lt "$ominor" ] && exit 0
[ "$minor" -gt "$ominor" ] && exit 1
[ "$patchlevel" -lt "$opatchlevel" ] && exit 0
[ "$patchlevel" -gt "$opatchlevel" ] && exit 1
# XXX tester prelease
exit 0
;;
gt)
[ -z "$valid" -a -z "$ovalid" ] && exit 1
[ "$major" -lt "$omajor" ] && exit 1
[ "$major" -gt "$omajor" ] && exit 0
[ "$minor" -lt "$ominor" ] && exit 1
[ "$minor" -gt "$ominor" ] && exit 0
[ "$patchlevel" -lt "$opatchlevel" ] && exit 1
[ "$patchlevel" -gt "$opatchlevel" ] && exit 0
# XXX tester prelease
exit 1
;;
ge)
[ -z "$valid" -a -z "$ovalid" ] && exit 1
[ "$major" -lt "$omajor" ] && exit 1
[ "$major" -gt "$omajor" ] && exit 0
[ "$minor" -lt "$ominor" ] && exit 1
[ "$minor" -gt "$ominor" ] && exit 0
[ "$patchlevel" -lt "$opatchlevel" ] && exit 1
[ "$patchlevel" -gt "$opatchlevel" ] && exit 0
# XXX tester prelease
exit 0
;;
esac
elif [ "$action" == update ]; then
if [ -n "$file" -a ! -f "$file" ]; then
ask_yesno "Le fichier $(ppath "$file") n'existe pas. Faut-il le créer?" O || die
fi
# incrémenter les numéros de version
[ "$incversion" == auto ] && incversion=minor #menu
case "$incversion" in
menu) eerror "non implémenté";; #XXX
major) semver_incmajor major minor patchlevel prelease metadata;;
minor) semver_incminor major minor patchlevel prelease metadata;;
patchlevel) semver_incpatchlevel major minor patchlevel prelease metadata;;
esac
# spécifier prerelease
if [ -n "$setfinal" ]; then
semver_setprelease "" major minor patchlevel prelease metadata
elif [ -n "$setprelease" ]; then
semver_setprelease "$setprelease" major minor patchlevel prelease metadata
fi
if [ -n "$setalpha" ]; then
:
elif [ -n "$setbeta" ]; then
:
elif [ -n "$setrc" ]; then
:
fi
# spécifier metadata
[ -n "$setmetadata" ] && semver_setmetadata "$setmetadata" major minor patchlevel prelease metadata
semver_setvar version major minor patchlevel prelease metadata
if [ -n "$file" ]; then
echo "$version" >"$file"
fi
estepn "La nouvelle version est $version"
fi
exit 0