diff --git a/lib/bash_completion.d/ptools b/lib/bash_completion.d/ptools index 41b14d3..dd979a4 100644 --- a/lib/bash_completion.d/ptools +++ b/lib/bash_completion.d/ptools @@ -6,3 +6,7 @@ function __pdev_branches() { grep -v '^release-' | grep -v '^hotfix-' } +function __prel_branches() { + git for-each-ref --format='%(refname:short)' refs/heads | + grep -E '^(master$|release-)' +} diff --git a/lib/uinst/conf b/lib/uinst/conf index b4af74d..514714d 100644 --- a/lib/uinst/conf +++ b/lib/uinst/conf @@ -35,7 +35,7 @@ done # complétion programmable bcdir=lib/bash_completion.d ./pdev --nutools-completion >"$bcdir/pdev" -#./prel --nutools-completion >"$bcdir/prel" +./todo/prel --nutools-completion >"$bcdir/prel" #./pfix --nutools-completion >"$bcdir/pfix" # copier le fichier .nutoolsrc diff --git a/lib/ulib/ptools b/lib/ulib/ptools index b8f286a..c8b990f 100644 --- a/lib/ulib/ptools +++ b/lib/ulib/ptools @@ -6,36 +6,67 @@ uprovide ptools urequire vcs semver -function __get_branch() { - local branch="$1" - [ -n "$branch" ] || branch="$(git_get_branch)" - echo "$branch" -} - -function is_master_branch() { - local branch; branch="$(__get_branch "$1")" || return 2 - [ "$branch" == "master" ] -} -function is_develop_branch() { - local branch; branch="$(__get_branch "$1")" || return 2 - [ "$branch" == "develop" ] -} -function is_release_branch() { - local branch; branch="$(__get_branch "$1")" || return 2 - [[ "$branch" == release-* ]] -} -function is_hotfix_branch() { - local branch; branch="$(__get_branch "$1")" || return 2 - [[ "$branch" == hotfix-* ]] -} -function is_feature_branch() { - local branch; branch="$(__get_branch "$1")" || return 2 - [ "$branch" == "master" ] && return 1 - [ "$branch" == "develop" ] && return 1 - [[ "$branch" == release-* ]] && return 1 - [[ "$branch" == hotfix-* ]] && return 1 - return 0 +function is_any_branch() { + local branch="$1"; shift + if [ -z "$branch" ]; then + branch="$(git_get_branch)" || return 2 + fi + local spec r + for spec in "$@"; do + case "$spec" in + m|master) + [ -n "$r" ] || r=1 + [ "$branch" == "master" ] && return 0 + ;; + d|develop) + [ -n "$r" ] || r=1 + [ "$branch" == "develop" ] && return 0 + ;; + r|release) + [ -n "$r" ] || r=1 + [[ "$branch" == release-* ]] && return 0 + ;; + h|hotfix) + [ -n "$r" ] || r=1 + [[ "$branch" == hotfix-* ]] && return 0 + ;; + f|feature|t|topic) + [ -n "$r" ] || r=1 + [ "$branch" == "master" ] && continue + [ "$branch" == "develop" ] && continue + [[ "$branch" == release-* ]] && continue + [[ "$branch" == hotfix-* ]] && continue + return 0 + ;; + -m|-master) + [ -n "$r" ] || r=0 + [ "$branch" == "master" ] && return 1;; + -d|-develop) + [ -n "$r" ] || r=0 + [ "$branch" == "develop" ] && return 1;; + -r|-release) + [ -n "$r" ] || r=0 + [[ "$branch" == release-* ]] && return 1;; + -h|-hotfix) + [ -n "$r" ] || r=0 + [[ "$branch" == hotfix-* ]] && return 1;; + -f|-feature|-t|-topic) + [ -n "$r" ] || r=0 + [ "$branch" == "master" ] && continue + [ "$branch" == "develop" ] && continue + [[ "$branch" == release-* ]] && continue + [[ "$branch" == hotfix-* ]] && continue + return 1 + ;; + esac + done + return ${r:-1} } +function is_master_branch() { is_any_branch "$1" master; } +function is_develop_branch() { is_any_branch "$1" develop; } +function is_release_branch() { is_any_branch "$1" release; } +function is_hotfix_branch() { is_any_branch "$1" hotfix; } +function is_feature_branch() { is_any_branch "$1" feature; } function list_release_branches() { git_list_branches | grep '^release-' @@ -50,3 +81,332 @@ function list_feature_branches() { grep -v '^release-' | grep -v '^hotfix-' } + +################################################################################ +# Outils de haut niveau + +function pver() { + local DEFAULT_FILE=VERSION.txt + + local -a args + local action=auto + local source=auto + local file= + local git= + local version= + local convert=auto + local operator= + local oversion= + local setversion= + local incversion= + local setprelease= + local setalpha= + local setbeta= + local setrc= + local setrelease= + local setmetadata= + local vcsmetadata= + parse_opts "${PRETTYOPTS[@]}" \ + --help '$exit_with pver_display_help' \ + -f:,--file: '$set@ file; source=file' \ + -F:,--file-string: '$set@ file; source=file-string' \ + -g:,--git-string: '$set@ git; source=git-string' \ + -s:,--string: '$set@ version; source=string' \ + --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[@]}" || { eerror "$args"; return 1; } + + # Calculer la source + if [ "$source" == auto ]; then + source=file + for i in "$DEFAULT_FILE" 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="$DEFAULT_FILE" + [ "$action" == auto ] && action=show + + # Lire la version + if [ "$source" == file ]; then + [ -f "$file" ] && version="$(<"$file")" + elif [ "$source" == file-string ]; then + if [ -z "$file" ]; then + file="$DEFAULT_FILE" + elif [ -d "$file" ]; then + file="$file/$DEFAULT_FILE" + fi + [ -f "$file" ] && version="$(<"$file")" + file= + elif [ "$source" == git-string ]; then + splitfsep2 "$git" : branch name + [ -n "$branch" ] || branch=master + [ -n "$name" ] || name="$DEFAULT_FILE" + if git rev-parse --verify --quiet "$branch:$name" >/dev/null; then + version="$(git cat-file blob "$branch:$name" 2>/dev/null)" + fi + fi + [ -n "$version" ] || version=0.0.0 + + # Conversion éventuelle du numéro de version + psemver_parse "$version" + [ -n "$valid" ] && convert= + if [ "$convert" == auto ]; then + [ -z "$valid" ] && convert=1 + 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 + return 0 + fi + + if [ "$action" == check ]; then + [ -n "$valid" ] || { eerror "Numéro de version invalide: $version"; return 1; } + + 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}" ] || return 1 + done + array_eq prelease oprelease || return 1 + if [ "$operator" == same ]; then + array_eq metadata ometadata || return 1 + fi + return 0 + ;; + ne|diff) + for var in valid major minor patchlevel; do + ovar="o$var" + [ "${!var}" != "${!ovar}" ] && return 0 + done + ! array_eq prelease oprelease && return 0 + if [ "$operator" == diff ]; then + ! array_eq metadata ometadata && return 0 + fi + return 1 + ;; + lt) + [ -z "$valid" -a -z "$ovalid" ] && return 1 + [ "$major" -lt "$omajor" ] && return 0 + [ "$major" -gt "$omajor" ] && return 1 + [ "$minor" -lt "$ominor" ] && return 0 + [ "$minor" -gt "$ominor" ] && return 1 + [ "$patchlevel" -lt "$opatchlevel" ] && return 0 + [ "$patchlevel" -gt "$opatchlevel" ] && return 1 + case "$(psemver_compare_prelease "" o)" in + lt) return 0;; + esac + return 1 + ;; + le) + [ -z "$valid" -a -z "$ovalid" ] && return 1 + [ "$major" -lt "$omajor" ] && return 0 + [ "$major" -gt "$omajor" ] && return 1 + [ "$minor" -lt "$ominor" ] && return 0 + [ "$minor" -gt "$ominor" ] && return 1 + [ "$patchlevel" -lt "$opatchlevel" ] && return 0 + [ "$patchlevel" -gt "$opatchlevel" ] && return 1 + case "$(psemver_compare_prelease "" o)" in + lt|eq) return 0;; + esac + return 1 + ;; + gt) + [ -z "$valid" -a -z "$ovalid" ] && return 1 + [ "$major" -lt "$omajor" ] && return 1 + [ "$major" -gt "$omajor" ] && return 0 + [ "$minor" -lt "$ominor" ] && return 1 + [ "$minor" -gt "$ominor" ] && return 0 + [ "$patchlevel" -lt "$opatchlevel" ] && return 1 + [ "$patchlevel" -gt "$opatchlevel" ] && return 0 + case "$(psemver_compare_prelease "" o)" in + gt) return 0;; + esac + return 1 + ;; + ge) + [ -z "$valid" -a -z "$ovalid" ] && return 1 + [ "$major" -lt "$omajor" ] && return 1 + [ "$major" -gt "$omajor" ] && return 0 + [ "$minor" -lt "$ominor" ] && return 1 + [ "$minor" -gt "$ominor" ] && return 0 + [ "$patchlevel" -lt "$opatchlevel" ] && return 1 + [ "$patchlevel" -gt "$opatchlevel" ] && return 0 + case "$(psemver_compare_prelease "" o)" in + gt|eq) return 0;; + esac + return 1 + ;; + esac + + elif [ "$action" == update ]; then + [ -n "$valid" ] || { eerror "Numéro de version invalide: $version"; return 1; } + + 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 || return 1 + fi + fi + fi + + # forcer le numéro de version + if [ -n "$setversion" ]; then + psemver_setversion "$setversion" "" || { eerror "Numéro de version invalide: $setversion"; return 1; } + fi + + # Calculer metadata + if [ -n "$vcsmetadata" ]; then + setmetadata="$(git rev-parse --short HEAD)" || return 1 + 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" || { eerror "Identifiant de pre-release invalide: $setprelease"; return 1; } + 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" || { eerror "Identifiant de build invalide: $setmetadata"; return 1; } + 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 + + return 0 +} diff --git a/pver b/pver index e19fa25..3e43a3b 100755 --- a/pver +++ b/pver @@ -1,9 +1,9 @@ #!/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 +urequire DEFAULTS ptools -function display_help() { +function pver_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 @@ -83,325 +83,4 @@ OPTIONS gestionnaire de version. Note: pour le moment, seul git est supporté." } -DEFAULT_FILE=VERSION.txt - -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' \ - -F:,--file-string: '$set@ file; source=file-string' \ - -g:,--git-string: '$set@ git; source=git-string' \ - -s:,--string: '$set@ version; source=string' \ - --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 "$DEFAULT_FILE" 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="$DEFAULT_FILE" -[ "$action" == auto ] && action=show - -# Lire la version -if [ "$source" == file ]; then - [ -f "$file" ] && version="$(<"$file")" -elif [ "$source" == file-string ]; then - if [ -z "$file" ]; then - file="$DEFAULT_FILE" - elif [ -d "$file" ]; then - file="$file/$DEFAULT_FILE" - fi - [ -f "$file" ] && version="$(<"$file")" - file= -elif [ "$source" == git-string ]; then - splitfsep2 "$git" : branch name - [ -n "$branch" ] || branch=master - [ -n "$name" ] || name="$DEFAULT_FILE" - if git rev-parse --verify --quiet "$branch:$name" >/dev/null; then - version="$(git cat-file blob "$branch:$name" 2>/dev/null)" - fi -fi -[ -n "$version" ] || version=0.0.0 - -# Conversion éventuelle du numéro de version -psemver_parse "$version" -[ -n "$valid" ] && convert= -if [ "$convert" == auto ]; then - [ -z "$valid" ] && convert=1 -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 +pver "$@" diff --git a/todo/prel b/todo/prel index 9ae6370..fb2150e 100755 --- a/todo/prel +++ b/todo/prel @@ -1,6 +1,20 @@ #!/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 + +if [ $# -eq 1 -a "$1" == --nutools-completion ]; then + echo ' +function __prel_completion() { + local cur + _get_comp_words_by_ref cur + COMPREPLY=($(compgen -W "$(__prel_branches)" "$cur")) +} +complete -F __prel_completion prel +' + exit 0 +fi + +source "$(dirname "$0")/../lib/ulib/ulib" || exit 1 +#source "$(dirname "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS ptools # XXX ajouter la possibilité de faire des pré-releases, --alpha, --beta, --rc @@ -12,12 +26,17 @@ function display_help() { uecho "$scriptname: basculer sur une branche de release USAGE - $scriptname [options] [SOURCE] + $scriptname -u [SOURCE] + $scriptname -c [RELEASE [SOURCE]] + $scriptname -m|-l|-d [RELEASE] - Vérifier s'il n'y a pas de modifications locales. Sinon, proposer de faire un commit ou un stash. -- Si aucune branche de release n'existe, assumer -u -z pour préparer une release - mineure. Sinon, basculer simplement sur la branche de release. +- Avec l'option -c, s'il existe une branche de release, proposer de basculer + vers elle ou sur la branche master. Sinon, basculer sur la branche master. +- Avec l'option -u, proposer ou fixer une branche de release à créer. Si elle + existe déjà, basculer vers elle. Sinon, la créer en la basant sur SOURCE, qui + vaut par défaut develop OPTIONS -C, --projdir PROJDIR @@ -34,21 +53,42 @@ OPTIONS activée si la variable UTOOLS_VCS_OFFLINE est définie. --online Annuler l'effet de la variable UTOOLS_VCS_OFFLINE: forcer le mode online + + -c, --checkout + Basculer vers une branche de release existante. C'est l'option par + défaut. Si aucune branche de release n'existe, basculer vers master -u, --update - Préparer une release. Utiliser une des options -x, -z ou -p pour - spécifier le type de release à préparer. S'il faut créer une nouvelle - branche, la baser sur la branche SOURCE, qui vaut par défaut develop + Préparer une nouvelle release. Utiliser une des options -x, -z ou -p + pour spécifier le type de release à préparer. Si la branche qui serait + créée pour le type de release existe déjà, basculer vers cette branche. + S'il faut la créer, la baser sur la branche SOURCE, qui vaut par défaut + develop + --menu -x, --major -z, --minor -p, --patchlevel - Utilisé avec l'option -u, préparer respectivement une release majeure, - mineure (par défaut), et pour correction de bug. + Utilisé avec l'option -u, soit afficher un menu pour choisir la version + de la nouvelle release (par défaut), soit préparer respectivement une + release majeure, mineure, ou pour correction de bug. + -v-OPT + Avec l'option -u, spécifier une option de pver permettant de choisir la + version de la nouvelle release. Les options supportées sont -v, -l, -a, + -b, -r et -R. Par exemple, si la version actuelle sur la branche master + est 0.2.3, les options '-uz -v-lbeta' permettent de préparer la release + 0.3.0-beta + En principe, cette option n'a pas à être utilisée, puisque dans une + branche de release, on peut faire vivre les versions de pré-release + jusqu'à la release finale. Ainsi, la branche de release est nommée + d'après la version finale, mais le projet peut recevoir une version de + pré-release incrémentale. + -m, --merge Si la branche actuelle est une branche de release, ou s'il existe une branche de release, la merger dans master, puis dans develop, puis la supprimer. Puis basculer sur la branche master. - Si la branche actuelle est une branche de topic et qu'il n'existe aucune - branche de release, assumer les options -u -z -m + S'il n'existe pas de branche de release, proposer de fusionner les + modifications de la branche develop dans la branche master, sans + préparer de branche de release au préalable. -l, --log Afficher les modifications actuellement effectuée dans la branche de release par rapport à develop. @@ -59,12 +99,27 @@ OPTIONS projdir= origin=origin +action=checkout +incversion= +pver_opts=() +log= +diff= parse_opts "${PRETTYOPTS[@]}" \ --help '$exit_with display_help' \ -C:,--projdir: projdir= \ -O:,--origin: origin= \ -o,--offline UTOOLS_VCS_OFFLINE=1 \ --online UTOOLS_VCS_OFFLINE= \ + -c,--checkout '$action=checkout' \ + -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' \ + -v: '$action=update; add@ pver_opts' \ + -m,--merge action=merge \ + -l,--log '$action=diff; log=1' \ + -d,--diff '$action=diff; diff=1' \ @ args -- "$@" && set -- "${args[@]}" || die "$args" if [ -n "$projdir" ]; then @@ -72,3 +127,68 @@ if [ -n "$projdir" ]; then fi git_ensure_gitvcs + +setx branch=git_get_branch + +if [ "$action" == branch ]; then + : + #setx major=pver -g "" -ux + #setx minor=pver -g "" -uz + #setx patchlevel=pver -g "" -up + #release="release-$minor" + #branches=("release-$major" "release-$minor" "release-$patchlevel" master) + #simple_menu release branches \ + # -t "Basculer vers une nouvelle release branch" \ + # -m "Veuillez choisir la branche à créer" +fi + +if [ "$action" == checkout ]; then + release="$1" + source="${2:-develop}" + + if [ -z "$release" ]; then + setx -a branches=list_release_branches + + if [ ${#branches[*]} -eq 0 ]; then + # en l'absence de branche de release, basculer sur master + release=master + elif [ ${#branches[*]} -eq 1 ]; then + # s'il n'y en a qu'une, la prendre + release="${branches[0]}" + else + # sinon, donner le choix dans un menu + array_add branches master + default_branch="$branch" + array_contains branches "$default_branch" || default_branch="${branches[0]}" + simple_menu release branches -d "$default_branch" \ + -t "Basculer vers une release branch" \ + -m "Veuillez choisir la branche vers laquelle basculer" + fi + fi + + # On est peut-être déjà sur la bonne branche + if git_is_branch "$release"; then + if [ -z "$UTOOLS_VCS_OFFLINE" ]; then + git_track_branch "$release" "$origin" + fi + exit 0 + fi + + # Créer/basculer vers une release branch + git_ensure_cleancheckout + is_any_branch "$release" master release || die "$release: ce n'est pas une release branch" + if git_have_branch "$release"; then + git checkout "$release" + else + estepn "\ +Vous allez créer la nouvelle release branch ${COULEUR_VERTE}$release${COULEUR_NORMALE} +à partir de la branche source ${COULEUR_BLEUE}$source${COULEUR_NORMALE}" + ask_yesno "Voulez-vous continuer?" O || die + + git_ensure_branch "$release" "$source" "$origin" + [ $? -eq 2 ] && die "Impossible de créer la branche $release. Veuillez vérifier que la branche $source existe" + git checkout "$release" + fi + + exit $? +fi