#!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 source "$(dirname "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS semver function display_help() { uecho "$scriptname: gérer des numéros de version selon les règles du versionage sémantique v2.0.0 (http://semver.org/) 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. -g, --git [branch:]VERSIONFILE Prendre pour valeur de départ le contenu du fichier VERSIONFILE (qui vaut par défaut VERSION.txt) dans la branche BRANCH (qui vaut par défaut master) du dépôt git situé 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 du versionage sémantique --convert --no-convert Activer (resp. désactiver) la conversion automatique. Par défaut, si la version est au format classique 'x.z[.p]-rDD/MM/YYYY', elle est convertie automatiquement au format sémantique x.z.p+rYYYYMMDD --eq VERSION --ne VERSION --lt VERSION --le VERSION --gt VERSION --ge VERSION --same VERSION --diff VERSION Comparer avec la version spécifiée. Les opérateurs --eq, --ne, --lt, --le, --gt, et --ge ignorent l'identifiant de build (comme le demande la règle du versionage sémantique). Les opérateurs --same et --diff comparent aussi les identifiants de build. -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 en temps normal parce que cela va contre les règles du versionage 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 XXX ces fonctions ne sont pas encore implémentées -R, --final, --release Supprimer l'identifiant de prérelease -m, --metadata ID Spécifier un identifiant de build, à ajouter au numéro de version. -M, --vcs-metadata Spécifier l'identifiant à partir de la révision actuelle dans le gestionnaire de version. Note: pour le moment, seul git est supporté." } action=auto source=auto file= git= version= convert=auto operator= oversion= setversion= incversion= setprelease= setalpha= setbeta= setrc= setrelease= setmetadata= vcsmetadata= parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -f:,--file: '$set@ file; source=file' \ -g:,--git: '$set@ git; source=git' \ -s:,--string: '$set@ version; source=' \ --show action=show \ --check action=check \ --convert convert=1 \ --no-convert convert= \ --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; [ -z "$setprelease" ] && { setalpha=; setbeta=; setrc=; setrelease=1; }' \ -a,--alpha '$action=update; setalpha=1; setbeta=; setrc=; setrelease=' \ -b,--beta '$action=update; setalpha=; setbeta=1; setrc=; setrelease=' \ -r,--rc '$action=update; setalpha=; setbeta=; setrc=1; setrelease=' \ -R,--release,--final '$action=update; setalpha=; setbeta=; setrc=; setrelease=1' \ -m:,--metadata: '$action=update; set@ setmetadata' \ -M,--vcs-metadata '$action=update; vcsmetadata=1' \ @ args -- "$@" && set -- "${args[@]}" || die "$args" # Calculer la source if [ "$source" == auto ]; then source=file for i in VERSION.txt version.txt; do if [ -f "$i" ]; then file="$i" break fi done elif [ "$source" == file ]; then [ "$action" == auto ] && action=update fi [ "$source" == file -a -z "$file" ] && file=VERSION.txt [ "$action" == auto ] && action=show # Lire la version if [ "$source" == file ]; then [ -f "$file" ] && version="$(<"$file")" [ -n "$version" ] || version=0.0.0 elif [ "$source" == git ]; then splitfsep2 "$git" : branch name [ -n "$branch" ] || branch=master [ -n "$name" ] || name=VERSION.txt if git rev-parse --verify --quiet "$branch:$name" >/dev/null; then version="$(git cat-file blob "$branch:$name" 2>/dev/null)" fi [ -n "$version" ] || version=0.0.0 fi # Conversion éventuelle du numéro de version psemver_parse "$version" if [ "$convert" == auto ]; then [ -z "$valid" ] && convert=1 || convert= fi if [ -n "$convert" ]; then mversion="$(awkrun version="$version" ' function nbdot(s) { gsub(/[^.]/, "", s) return length(s) } BEGIN { if (version ~ /[0-9]+(\.[0-9]+)*(-r[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9])?$/) { metadata = "" # traiter release date pos = length(version) - 12 if (pos > 0) { rdate = substr(version, pos + 3) metadata = substr(rdate, 7, 4) substr(rdate, 4, 2) substr(rdate, 1, 2) version = substr(version, 1, pos) } # traiter metadata match(version, /[0-9]+(\.[0-9]+(\.[0-9]+)?)?/) pos = RLENGTH if (pos < length(version)) { if (metadata != "") metadata = metadata "." metadata = metadata substr(version, pos + 2) } version = substr(version, 1, pos) # ajouter les éléments manquants while (nbdot(version) < 2) { version = version ".0" } # afficher la version migrée au format semver if (metadata != "") print version "+" metadata else print version } }')" if [ -n "$mversion" ]; then version="$mversion" psemver_parse "$version" fi fi # Actions if [ "$action" == show ]; then if isatty; then estepi "La version actuelle est $version" else echo "$version" fi exit 0 fi if [ "$action" == check ]; then [ -n "$valid" ] || die "Numéro de version invalide: $version" elif [ "$action" == compare ]; then psemver_parse "$oversion" o 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 case "$(psemver_compare_prelease "" o)" in lt) exit 0;; esac 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 case "$(psemver_compare_prelease "" o)" in lt|eq) exit 0;; esac exit 1 ;; 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 case "$(psemver_compare_prelease "" o)" in gt) exit 0;; esac 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 case "$(psemver_compare_prelease "" o)" in gt|eq) exit 0;; esac exit 1 ;; esac elif [ "$action" == update ]; then [ -n "$valid" ] || die "Numéro de version invalide: $version" if [ -n "$file" ]; then if [ -f "$file" ]; then if isatty; then estepi "La version actuelle est $version" fi else if isatty; then ask_yesno "Le fichier $(ppath "$file") n'existe pas. Faut-il le créer?" O || die fi fi fi # forcer le numéro de version if [ -n "$setversion" ]; then psemver_setversion "$setversion" "" || die "Numéro de version invalide: $setversion" fi # Calculer metadata if [ -n "$vcsmetadata" ]; then setmetadata="$(git rev-parse --short HEAD)" || die fi # incrémenter les numéros de version if [ "$incversion" == auto ]; then if [ -n "$setrelease" -o -n "$setprelease" -o -n "$setmetadata" ]; then incversion= else incversion=menu fi fi if [ "$incversion" == menu ]; then psemver_copy x; psemver_incmajor x; psemver_setprelease "$setprelease" x; psemver_setmetadata "$setmetadata" x; psemver_setvar versionx x psemver_copy z; psemver_incminor z; psemver_setprelease "$setprelease" z; psemver_setmetadata "$setmetadata" z; psemver_setvar versionz z psemver_copy p; psemver_incpatchlevel p; psemver_setprelease "$setprelease" p; psemver_setmetadata "$setmetadata" p; psemver_setvar versionp p psemver_copy k; psemver_setprelease "$setprelease" k; psemver_setmetadata "$setmetadata" k; psemver_setvar versionk k nextvs=( "$versionx : maj incompatibles de l'API (-x)" "$versionz : maj compatibles de l'API (-z)" "$versionp : correction de bugs (-p)" "$versionk : ne pas incrémenter la version" ) nextv="${nextvs[1]}" simple_menu nextv nextvs \ -t "Incrémenter le numéro de version" \ -m "Veuillez choisir la prochaine version" case "${nextv%)}" in *-x) incversion=major;; *-z) incversion=minor;; *-p) incversion=patchlevel;; *) incversion=;; esac fi if [ -n "$incversion" ]; then case "$incversion" in major) psemver_incmajor;; minor) psemver_incminor;; patchlevel) psemver_incpatchlevel;; esac # Quand on incrémente, réinitialiser la valeur de prérelease et metadata psemver_setprelease psemver_setmetadata fi # spécifier prerelease if [ -n "$setrelease" ]; then psemver_setprelease "" elif [ -n "$setprelease" ]; then psemver_setprelease "$setprelease" || die "Identifiant de pre-release invalide: $setprelease" fi if [ -n "$setalpha" ]; then : #XXX elif [ -n "$setbeta" ]; then : #XXX elif [ -n "$setrc" ]; then : #XXX fi # spécifier metadata if [ -n "$setmetadata" ]; then psemver_setmetadata "$setmetadata" || die "Identifiant de build invalide: $setmetadata" fi # afficher le résultat final psemver_setvar version if [ -n "$file" ]; then echo "$version" >"$file" fi if isatty; then estepn "La nouvelle version est $version" else echo "$version" fi fi exit 0