diff --git a/pff b/pff index ebe7dd4..3fe622f 100755 --- a/pff +++ b/pff @@ -2,8 +2,11 @@ # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 SCRIPT_ALIASES=( - pfs:-s + pf0:-0 + pfn:-N + pfg:-g pfb:-b + pfs:-s pfa:-a pfe:-e pfd:-d @@ -106,7 +109,7 @@ complete -F __pff_completion -o bashdefault -o default pff fi source "$(dirname "$0")/lib/ulib/ulib" || exit 1 -urequire DEFAULTS multiconf +urequire DEFAULTS multiconf vcs function display_help() { uecho "$scriptname: gestion de modifications locales @@ -198,7 +201,7 @@ supportées sont: --no-unwrap Intégrer tel quel le contenu de l'archive. - --patch [WORKDIR] + -g, --patch [WORKDIR] Intégrer les modifications entrantes sur les fichiers nouvellement arrivés via l'option --new --ask-commit @@ -398,7 +401,7 @@ function get_bfile() { get_pfile "$1" Base "$2"; } function get_Cfile() { get_pfile "$1" Common "$2"; } function get_cfile() { get_pfile "$1" Current "$2"; } -function get_vlfiles() { +function get_vlfiles_nostrip() { # afficher tous les fichiers de version local pffdir="$1" rfile="$2" profile="${3:-Base}" version="$4" [ -d "$pffdir/pff/$profile" ] || return @@ -406,28 +409,28 @@ function get_vlfiles() { if [ -n "$rfile" ]; then find "$pffdir/pff/$profile" \ -type f -path "$pffdir/pff/$profile/${rfile}__pv-${version}__" -o \ - -type l -path "$pffdir/pff/$profile/${rfile}__pv-${version}__" \ - | sed "s|^$pffdir/pff/$profile/||" + -type l -path "$pffdir/pff/$profile/${rfile}__pv-${version}__" else find "$pffdir/pff/$profile" \ -type f -name "*__pv-${version}__" -o \ - -type l -name "*__pv-${version}__" \ - | sed "s|^$pffdir/pff/$profile/||" + -type l -name "*__pv-${version}__" fi else if [ -n "$rfile" ]; then find "$pffdir/pff/$profile" \ -type f -path "$pffdir/pff/$profile/${rfile}__pv-*__" -o \ - -type l -path "$pffdir/pff/$profile/${rfile}__pv-*__" \ - | sed "s|^$pffdir/pff/$profile/||" + -type l -path "$pffdir/pff/$profile/${rfile}__pv-*__" else find "$pffdir/pff/$profile" \ -type f -name "*__pv-*__" -o \ - -type l -name "*__pv-*__" \ - | sed "s|^$pffdir/pff/$profile/||" + -type l -name "*__pv-*__" fi fi } +function get_vlfiles() { + local pffdir="$1" rfile="$2" profile="${3:-Base}" version="$4" + get_vlfiles_nostrip "$@" | sed "s|^$pffdir/pff/$profile/||" +} function sync_vlfiles() { # synchroniser les fichiers de version $3..@ dans tous les répertoires de @@ -594,7 +597,7 @@ function new__prepare_archive() { disttype=patch ;; *) - die "L'extension de l'archive n'est pas reconnue. Vous devez spécifier l'une des options --full-archive ou --patch-archive" + die "L'extension de l'archive n'est pas reconnue. Vous devez spécifier l'une des options -F ou -H" ;; esac fi @@ -622,7 +625,7 @@ function new__prepare_archive() { fi elif [ -d "$srcdir" ]; then if [ "$disttype" == auto ]; then - die "La source est un répertoire. Vous devez spécifier l'une des option --full-archive ou --patch-archive" + die "La source est un répertoire. Vous devez spécifier l'une des option -F ou -H" fi ac_set_tmpdir tmpd @@ -636,7 +639,7 @@ function new__prepare_archive() { } function new_cmd() { - local autopatch="$1" version="$2" disttype="$3" unwrap="$4"; shift; shift; shift; shift + local autopatch="$1" version="$2" disttype="$3" unwrap="$4" commit_policy="$5"; shift; shift; shift; shift; shift local archive="$1" pffdir="$2" ensure_pffdir pffdir "$pffdir" @@ -870,7 +873,8 @@ function new_cmd() { if [ -n "$autopatch" ]; then # lancer la commande patch pour intégrer les modifications - patch_cmd "$pffdir" + ask_yesno "Voulez-vous passer à l'intégration de cette version?" O && + patch_cmd "$commit_policy" "$pffdir" fi } @@ -878,68 +882,164 @@ function new_cmd() { # pff --patch function patch_cmd() { - local commit="$1" pffdir="$2" - local was_patched eop_version patched_profile - local pversion profile - local -a profiles vlfiles + local commit_policy="$1" pffdir="$2" + local gitproject was_patched eop_version + local version profile rcfile curdir workdir controldir + local -a profiles vlfiles tmpfiles ensure_pffdir pffdir "$pffdir" + + # est-ce un projet suivi dans git? + (cd "$pffdir"; git_check_gitvcs) && gitproject=1 || gitproject= + array_from_lines profiles "$(get_user_profiles "$pffdir")" + if array_contains profiles Common; then + # toujours traiter Common en dernier + array_del profiles Common + array_add profiles Common + fi while true; do - was_patched= - for pversion in "${PVERSIONS[@]}"; do + # si pas de version en cours, il n'y a rien à patcher + [ ${#PVERSIONS[*]} -gt 0 ] || break + + eop_version= + for version in "${PVERSIONS[@]}"; do have_profile_vlfiles= have_base_vlfiles= for profile in "${profiles[@]}"; do - array_from_lines vlfiles "$(get_vlfiles "$pffdir" "" "$profile" "$pversion")" + array_from_lines vlfiles "$(get_vlfiles_nostrip "$pffdir" "" "$profile" "$version")" if [ ${#vlfiles[*]} -gt 0 ]; then have_profile_vlfiles=1 break fi done [ -n "$have_profile_vlfiles" ] && break - array_from_lines vlfiles "$(get_vlfiles "$pffdir" "" Base "$pversion")" - if [ ${#vlfiles[*]} -gt 0 ]; then - have_base_vlfiles=1 - break - fi + array_from_lines vlfiles "$(get_vlfiles_nostrip "$pffdir" "" Base "$version")" + have_base_vlfiles=1 + break done if [ -n "$have_profile_vlfiles" ]; then # il faut patcher les fichiers du profil - echo "Il faut patcher avec les modifications de ces fichiers: ${vlfiles[*]}" #XXX intégrer les modifications dans les fichiers de patch pour le profil - #was_patched=1 + etitle "Intégration de la version $version dans le profil $profile" + [ -n "$rcfile" ] || ac_set_tmpfile rcfile + [ -n "$workdir" ] && ac_clean "$workdir" + ac_set_tmpdir workdir + [ -n "$controldir" ] && ac_clean "$controldir" + ac_set_tmpdir controldir + curdir="$(pwd)" + cd "$workdir" + git init -q . + git checkout -q --orphan upstream + # rajouter les fichiers de Base dans la branche upstream + for vlfile in "${vlfiles[@]}"; do + setx bfile=get_bfile "${vlfile%__pv-${version}__}" "$pffdir" + setx rfile=get_rfile "$bfile" "$pffdir" + mkdirof "$rfile" + cp -a "$bfile" "$rfile" + done + git add -A + git commit -qm "Base" + # créer la branche v$version depuis upstream + git checkout -qb "v$version" + # rajouter les fichiers de Common s'ils existent (sauf si la branche c'est Common ^^) + if [ "$profile" != Common ]; then + for vlfile in "${vlfiles[@]}"; do + setx Cfile=get_Cfile "${vlfile%__pv-${version}__}" "$pffdir" + if [ -e "$Cfile" -o -L "$Cfile" ]; then + setx rfile=get_rfile "$Cfile" "$pffdir" + mkdirof "$rfile" + cp -a "$Cfile" "$rfile" + fi + done + git add -A + git commit -qm "Common" + fi + # rajouter les fichiers du profil + for vlfile in "${vlfiles[@]}"; do + setx pfile=get_pfile "${vlfile%__pv-${version}__}" "$profile" "$pffdir" + setx rfile=get_rfile "$pfile" "$pffdir" + mkdirof "$rfile" + cp -a "$pfile" "$rfile" + done + git add -A + git commit -qm "$profile" + # rebasculer vers upstream et rajouter les fichiers de patch + git checkout -q upstream + for vlfile in "${vlfiles[@]}"; do + setx rfile=get_rfile "${vlfile%__pv-${version}__}" "$pffdir" + mkdirof "$rfile" + cp -L "$vlfile" "$rfile" + done + git add -A + git commit -qm "$version" + # basculer vers la branche de version et tenter de merger upstream dans version + git checkout -q "v$version" + if git merge --no-commit upstream; then + # tout s'est bien passé + git commit -qm "v$version --> $profile" + else + # il y a eu une erreur. laisser l'utilisateur décider quoi faire + echo >"$rcfile" "# +[ -f /etc/bash.bashrc ] && . /etc/bash.bashrc +[ -f ~/.bashrc ] && . ~/.bashrc +$(qvals source "$ULIBDIR/ulib") +urequire DEFAULTS +function abort() { $(qvals touch "$controldir/ABORT"); exit; } +$(qvals cd "$workdir") +$(qvals eerror "Une erreur s'est produite: examinez la situation et faites les corrections nécessaires") +$(qvals eimportant "Puis tapez exit pour valider l'intégration de la version") +$(qvals eimportant "Sinon, tapez abort pour arrêter l'intégration de cette version") +" + "${SHELL:-bash}" --rcfile "$rcfile" + fi + [ -f "$controldir/ABORT" ] && break + # récupérer les versions modifiées et supprimer les fichiers de patch + for vlfile in "${vlfiles[@]}"; do + setx pfile=get_pfile "${vlfile%__pv-${version}__}" "$profile" "$pffdir" + setx rfile=get_rfile "$pfile" "$pffdir" + cp -a "$rfile" "$pfile" + rm "$vlfile" + done + cd "$curdir" + eend elif [ -n "$have_base_vlfiles" ]; then # il faut intégrer la nouvelle version dans Base - echo "Ces fichiers deviennent les nouveaux fichiers référence: ${vlfiles[*]}" #XXX le fichier de patch devient le nouveau fichier référence dans Base - #was_patched=1; eop_version=1 - #array_del PVERSIONS "$pversion" - #conf_update "$pffdir/$PFFCONF" PVERSIONS + etitle "Finaliser intégration de la version $version" + for vlfile in "${vlfiles[@]}"; do + bfile="${vlfile%__pv-${version}__}" + mv "$vlfile" "$bfile" + done + eop_version=1 + VERSION="$version" + array_del PVERSIONS "$VERSION" + conf_update "$pffdir/$PFFCONF" VERSION PVERSIONS + eend fi - # s'arrêter quand il n'y a plus de modifications - [ -n "$was_patched" ] || break - - local ask default - if [ -n "$eop_version" ]; then - msg="Intégration de la version $version" - else - msg="Correction du profil $patched_profile pour la version $version" - fi - if [ "$commit" == ask ]; then + if [ -n "$gitproject" ]; then + local commit default if [ -n "$eop_version" ]; then - enote "Vous avez terminé l'intégration des patches de la version $version" - default=O + msg="Intégration de la version $version" else - einfo "Vous avez intégré les patches de la version $version pour le profil $patched_profile" - default=N + msg="Correction du profil $profile pour la version $version" fi - ask_yesno "Voulez-vous enregistrer les modifications dans git?" $default || commit= - fi - if [ -n "$commit" ]; then - git add -A && git commit -m "$msg" || return - if [ -z "$UTOOLS_VCS_OFFLINE" ]; then - git push + commit="$commit_policy" + if [ "$commit" == ask ]; then + if [ -n "$eop_version" ]; then + enote "Vous avez terminé l'intégration des patches de la version $version" + default=O + else + einfo "Vous avez intégré les patches de la version $version pour le profil $profile" + default=N + fi + ask_yesno "Voulez-vous enregistrer les modifications dans git?" $default || commit= + fi + if [ -n "$commit" ]; then + git add -A && git commit -qm "$msg" || return + if [ -z "$UTOOLS_VCS_OFFLINE" ]; then + git push -q + fi fi fi done @@ -1334,7 +1434,7 @@ disttype=auto ORIGEXTS=("${DEFAULT_ORIGEXTS[@]}") PROTECTS=("${DEFAULT_PROTECTS[@]}") unwrap=auto -commit=ask +commit_policy=ask profile= alternate= args=($parse_mode @@ -1351,10 +1451,10 @@ args=($parse_mode --auto-unwrap unwrap=auto --no-unwrap unwrap= -E,--unwrap unwrap=1 - --patch action=patch - --ask-commit commit=ask - -c,--comit commit=1 - --no-commit commit= + -g,--patch action=patch + --ask-commit commit_policy=ask + -c,--comit commit_policy=1 + --no-commit commit_policy= -b,--add-global action=add-global --locals action=list-locals --profiles action=list-profiles @@ -1375,8 +1475,8 @@ array_fix_paths ORIGEXTS case "$action" in init) init_cmd "$@";; -new) new_cmd "$autopatch" "$version" "$disttype" "$unwrap" "$@";; -patch) patch_cmd "$commit" "$@";; +new) new_cmd "$autopatch" "$version" "$disttype" "$unwrap" "$commit_policy" "$@";; +patch) patch_cmd "$commit_policy" "$@";; add-global) add_global_cmd "$@";; list-locals) list_locals_cmd "$@";; list-profiles) list_profiles_cmd "$@";;