1200 lines
41 KiB
Bash
Executable File
1200 lines
41 KiB
Bash
Executable File
#!/bin/bash
|
|
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
|
|
|
SCRIPT_ALIASES=(
|
|
pfs:-s
|
|
pfa:-a
|
|
pfb:-b
|
|
pfe:-e
|
|
pfd:-d
|
|
)
|
|
|
|
ORIGEXT=pff
|
|
DEFAULT_ORIGEXTS=(".$ORIGEXT" .origine .default)
|
|
PFFCONF=.pff.conf # ne pas modifier
|
|
DEFAULT_PROTECTS=(/.git/ .svn/ /pff/ "/$PFFCONF")
|
|
|
|
PFFCONFVARS=(
|
|
"VERSION//Version actuellement installée"
|
|
-a
|
|
"PVERSIONS//Versions en attente d'intégration"
|
|
"PROFILES//Profils définis"
|
|
"ORIGEXTS=//Extensions origines"
|
|
)
|
|
|
|
if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then
|
|
# créer les liens
|
|
scriptname="$(basename -- "$0")"
|
|
for alias in "${SCRIPT_ALIASES[@]}"; do
|
|
alias="${alias%:*}"
|
|
ln -s "$scriptname" "$alias"
|
|
done
|
|
exit 0
|
|
elif [ $# -eq 1 -a "$1" == --nutools-completion ]; then
|
|
echo '
|
|
function __pff_profiles() {
|
|
local cwd="$(pwd)"
|
|
local pffdir="$cwd"
|
|
while true; do
|
|
if [ -f "$pffdir/'"$PFFCONF"'" -a -d "$pffdir/pff" ]; then
|
|
cd "$pffdir/pff"
|
|
/bin/ls -1d * | while read f; do
|
|
[ -d "$f" -a "$f" != Current ] || continue
|
|
f="$1$f"
|
|
if [[ "${f:0:2}" == -[eEn] ]]; then
|
|
echo -n -
|
|
echo "${f:1}"
|
|
else
|
|
echo "$f"
|
|
fi
|
|
done
|
|
cd "$cwd"
|
|
break
|
|
fi
|
|
[ "$pffdir" == / -o "$pffdir" == "$HOME" ] && break
|
|
pffdir="$(dirname -- "$pffdir")"
|
|
done
|
|
}
|
|
function __pfs_completion() {
|
|
local cur
|
|
_get_comp_words_by_ref cur
|
|
COMPREPLY=($(compgen -W "$(__pff_profiles)" "$cur"))
|
|
}
|
|
complete -F __pfs_completion -o bashdefault -o default pfs
|
|
function __pff_completion() {
|
|
local cur prev opt comp
|
|
_get_comp_words_by_ref cur prev
|
|
if [[ "$prev" == -*s ]]; then
|
|
COMPREPLY=($(compgen -W "$(__pff_profiles)" -- "$cur"))
|
|
elif [[ "$cur" == -*s* ]]; then
|
|
comp="${cur#-*s}"; opt="${cur:0:$((${#cur}-${#comp}))}"
|
|
COMPREPLY=($(compgen -W "$(__pff_profiles "$opt")" -- "$cur"))
|
|
fi
|
|
}
|
|
complete -F __pff_completion -o bashdefault -o default pff
|
|
'
|
|
exit 0
|
|
fi
|
|
|
|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
|
|
urequire DEFAULTS multiconf
|
|
|
|
function display_help() {
|
|
uecho "$scriptname: gestion de modifications locales
|
|
|
|
Un produit est distribué par un partenaire, et il faut maintenir certaines
|
|
modifications locales tout en continuant d'accepter des modififications de
|
|
l'upstream. Ce script aide à maintenir un tel scénario.
|
|
|
|
En général, la distribution upstream identifie les fichiers modifiables en leur
|
|
donnant une extension particulière, par exemple 'file.origine'. On peut aussi
|
|
décider de modifier des fichiers qui n'ont pas été prévus comme tels par
|
|
l'upstream. On peut aussi avoir plusieurs ensembles de modifications, rassemblés
|
|
en profils, e.g prod ou test pour les modifications à déployer en prod ou en
|
|
test.
|
|
|
|
Terminologie: Les fichiers pour lesquels il faut maintenir une version locale
|
|
sont appelés 'fichiers locaux', qu'ils viennent de la distribution upstream ou
|
|
non. Les autres fichiers qui proviennent de la distribution sont appelés
|
|
'fichiers upstream'. Les fichiers livrés dans la distribution upstream avec une
|
|
extension particulière pour indiquer qu'ils sont modifiables sont appelés
|
|
'fichiers origine'.
|
|
|
|
Les fichiers sont classés dans des profils spécifiques. Les profils reconnus
|
|
sont:
|
|
- Base est le profil des fichiers upstream non modifiés. Les fichiers origine
|
|
sont intégrés dans ce profil.
|
|
- Common est le profil des fichiers upstream modifiés. Tous les fichiers
|
|
devraient être modifiés dans ce profil.
|
|
- Les autres profils sont basés sur Common en priorité puis sur Base en cas de
|
|
non existence dans Common. Il peut s'agir de profils comme prod ou test, qui
|
|
contiennent des modifications spécifiques à différents cas d'utilisation.
|
|
|
|
USAGE
|
|
$scriptname [options]
|
|
|
|
COMMANDES / OPTIONS
|
|
Les arguments du script dépendent de la commande utilisée. Les commandes
|
|
supportées sont:
|
|
-0, --init [WORKDIR [ARCHIVE]]
|
|
Initialiser un répertoire pour le suivi des distributions upstream. Le
|
|
fichier $PFFCONF contient toutes les informations paramétrables sur la
|
|
gestion du projet.
|
|
--s, --origext .EXT
|
|
Ajouter une extension à la liste des extensions origines, c'est à dire
|
|
les fichiers identifiés dans la distribution upstream comme contenus
|
|
modifiables. Par défaut, les extensions suivantes sont reconnues:
|
|
${DEFAULT_ORIGEXTS[*]}
|
|
Cette option peut être utilisée autant de fois que nécessaire.
|
|
--k, --clear-origexts
|
|
Supprimer la liste par défaut des extensions origines. Cette option doit
|
|
être spécifiée avant l'option --origext pour construire une nouvelle
|
|
liste. La liste des extensions ne doit pas être vide. Si c'est le cas,
|
|
elle est modifiée pour contenir l'unique élément (.$ORIGEXT)
|
|
|
|
-N, --new ARCHIVE [WORKDIR]
|
|
-M, --new-only ARCHIVE [WORKDIR]
|
|
Intégrer une nouvelle distribution upstream, sous forme d'une archive ou
|
|
d'un répertoire. Les fichiers origine et les fichiers locaux sont placés
|
|
en attente d'intégration. Les autres sont intégrés sans modification.
|
|
La variante --new appelle automatiquement --patch après l'intégration de
|
|
l'archive.
|
|
-V, --version VERSION
|
|
Spécifier la version de l'archive qui est intégrée avec l'option --new.
|
|
Normalement, cette information est calculée automatiquement à partir du
|
|
nom de l'archive. Si la source est un répertoire ou une archive sans
|
|
numéro de version, cette option est requise.
|
|
-F, --full-archive
|
|
Intégrer une distribution complète. Par défaut, les archives avec
|
|
l'extension .war sont considérées commes des livraisons complètes. Si
|
|
la source est un répertoire ou une archive sans extension, l'une des
|
|
options -F ou -P est requise.
|
|
-P, --patch-archive
|
|
Intégrer un patch. Par défaut, les archives avec l'extension .zip sont
|
|
considérées comme des patches. Si la source est un répertoire ou une
|
|
archive sans extension, l'une des options -F ou -P est requise.
|
|
Avec une distribution de type patch, on considère que les fichiers
|
|
livrés ne sont pas des fichiers origines. Il n'y a donc aucun traitement
|
|
particulier: l'archive est simplement intégrée telle quelle.
|
|
--auto-unwrap
|
|
Si l'archive ne contient qu'un seul répertoire à la racine nommé d'après
|
|
le nom de base de l'archive, c'est le contenu de ce répertoire qui est
|
|
considéré. C'est l'option par défaut.
|
|
Le test est effectué avec et sans la version. Par exemple, si l'archive
|
|
est product-x.y.zip, et qu'elle contient un unique répertoire nommé
|
|
'product-x.y' ou 'product' alors intégrer le contenu de ce répertoire.
|
|
-E, --unwrap
|
|
Si l'archive ne contient qu'un seul répertoire à la racine, intégrer
|
|
inconditionellement le contenu de se répertoire.
|
|
--no-unwrap
|
|
Intégrer tel quel le contenu de l'archive.
|
|
|
|
-p, --patch [WORKDIR]
|
|
Intégrer les modifications entrantes sur les fichiers nouvellement
|
|
arrivés via l'option --new
|
|
|
|
-a, --add-global FILES...
|
|
Ajouter/Identifier un fichier comme un fichier local pour tous les
|
|
profils. Le fichier est copié dans le profil Base.
|
|
|
|
--locals [WORKDIR]
|
|
Lister les fichiers locaux
|
|
|
|
--profiles [WORKDIR]
|
|
Lister les profils valides
|
|
|
|
-s, --switch PROFILE [WORKDIR]
|
|
Basculer le profil courant
|
|
|
|
-b, --add-local FILES...
|
|
Ajouter/Identifier un fichier comme un fichier local et le rendre
|
|
spécifique au profil courant.
|
|
-e, --edit FILES...
|
|
Editer des fichiers, implique --add-local
|
|
|
|
-d, --diff [DESTP [WORKDIR]]
|
|
-d, --diff [SRCP DESTP [WORKDIR]]
|
|
Afficher la différence entre entre deux profils. Avec la première
|
|
syntaxe, comparer le profil courant au profil DESTP. Avec la deuxième
|
|
syntaxe, comparer le profil SRCP au DESTP.
|
|
-l, --list-names
|
|
N'afficher que les noms des fichiers qui sont différents
|
|
|
|
--infos [WORKDIR]
|
|
Afficher des informations sur le projet courant: profils, fichiers
|
|
locaux, profil courant, etc. C'est la commande par défaut.
|
|
Les fichiers locaux sont taggés avec les valeurs suivantes
|
|
${COULEUR_ROUGE}P${COULEUR_NORMALE} il existe un patch pour ce fichier dans le profil courant
|
|
${COULEUR_BLEUE}*${COULEUR_NORMALE} ce fichier local est spécifique à ce profil
|
|
$(get_color YELLOW)C${COULEUR_NORMALE} ce fichier local est spécifique au profil Common
|
|
-l, --show-all
|
|
Afficher tous les fichiers locaux au lieu de se contenter des fichiers
|
|
modifiés dans le profil courant."
|
|
}
|
|
|
|
# Nomenclature pour le nommage des fichiers traités:
|
|
# pfile: le chemin absolu du fichier dans le projet
|
|
# rfile: le chemin relatif du fichier dans le projet
|
|
# bfile: le chemin absolu du fichier dans pff/Base/
|
|
# Cfile: le chemin absolu du fichier dans pff/Common/
|
|
# cfile: le chemin absolu du fichier dans pff/Current/
|
|
# Pfile: le chemin absolu du fichier dans pff/ANYPROFILE/
|
|
# plink: la destination du lien pfile
|
|
# clink: la destination du lien cfile
|
|
# Plink: la destination du lien Pfile
|
|
|
|
function flexists() {
|
|
[ -e "$1" -o -L "$1" ]
|
|
}
|
|
|
|
function find_pffdir() {
|
|
# trouver le répertoire du projet pff à partir du répertoire $2(=.) et
|
|
# mettre le chemin absolu dans la variable $1(=pffdir)
|
|
# si le répertoire n'est pas trouvé, retourner 1
|
|
local destvar="${1:-pffdir}" pffdir
|
|
setx pffdir=abspath "${2:-.}"
|
|
while true; do
|
|
if [ -f "$pffdir/$PFFCONF" -a -d "$pffdir/pff" ]; then
|
|
local "$destvar"
|
|
upvar "$destvar" "$pffdir"
|
|
return 0
|
|
fi
|
|
[ "$pffdir" == / -o "$pffdir" == "$HOME" ] && break
|
|
setx pffdir=dirname -- "$pffdir"
|
|
done
|
|
return 1
|
|
}
|
|
|
|
function ensure_pffdir() {
|
|
# trouver le répertoire du projet pff à partir du répertoire $2(=.) et
|
|
# mettre le chemin absolu dans la variable $1(=pffdir)
|
|
# si le répertoire n'est pas trouvé, arrêter le script avec un code d'erreur
|
|
local destvar="${1:-pffdir}" pffdir
|
|
if find_pffdir pffdir "$2"; then
|
|
conf_init "${PFFCONFVARS[@]}"
|
|
source "$pffdir/$PFFCONF"
|
|
local "$destvar"; upvar "$destvar" "$pffdir"
|
|
return
|
|
fi
|
|
local msg="Projet pff introuvable (utiliser --init ?)"
|
|
[ -n "$2" ] && die "$2: $msg" || die "$msg"
|
|
}
|
|
|
|
function get_current_profile() {
|
|
# afficher le profil courant du projet pff $1, s'il est défini
|
|
local pffdir="$1"
|
|
[ -L "$pffdir/pff/.Current" ] && readlink "$pffdir/pff/.Current"
|
|
}
|
|
|
|
function get_profiles() {
|
|
# afficher tous les profils valides du projet pff $1
|
|
local pffdir="$1"
|
|
(for profile in "${PROFILES[@]}"; do echo "$profile"; done
|
|
list_dirs "$pffdir/pff") | sort -u | grep -vxF Current
|
|
}
|
|
|
|
function get_first_profile() {
|
|
# afficher le premier profil autre que Base du projet pff $1
|
|
get_profiles "$@" | grep -vxF Base | head -n1
|
|
}
|
|
|
|
function get_local_files() {
|
|
# afficher tous les fichiers locaux exprimés relativement au répertoire du
|
|
# projet pff $1
|
|
local pffdir="$1"
|
|
find "$pffdir/pff/Base" -type f | sed "s|^$pffdir/pff/Base/||" | grep -v '__pv-.*__$'
|
|
}
|
|
|
|
function multiups() {
|
|
# afficher un chemin vers le haut e.g ../../.. avec autant d'éléments que
|
|
# les répertoires du chemin relatif $1.
|
|
# méthode: commencer avec la valeur de départ $2 et préfixer avec autant de
|
|
# ../ que nécessaire. puis afficher le résultat.
|
|
local tmp="$1" link="$2"
|
|
setx tmp=dirname -- "$tmp"
|
|
while [ "$tmp" != . ]; do
|
|
[ -n "$link" ] && link="/$link"
|
|
link="..$link"
|
|
setx tmp=dirname -- "$tmp"
|
|
done
|
|
echo "$link"
|
|
}
|
|
|
|
function get_rfile() {
|
|
# obtenir le chemin relatif du fichier $1 exprimé par rapport au répertoire
|
|
# du projet pff $2. Si c'est un fichier d'un répertoire de profil,
|
|
# l'exprimer comme un chemin du répertoire de projet, e.g pff/Profile/path
|
|
# devient path
|
|
# retourner 1 si le chemin est invalide (est situé en dehors de pffdir ou
|
|
# pas dans un répertoire de profil)
|
|
local rfile="$1" pffdir="$2"
|
|
setx rfile=abspath "$rfile"
|
|
[ "${rfile#$pffdir/}" != "$rfile" ] || return 1
|
|
rfile="${rfile#$pffdir/}"
|
|
if [[ "$rfile" == pff/*/* ]]; then
|
|
rfile="${rfile#pff/*/}"
|
|
elif [[ "$rfile" == pff/* ]]; then
|
|
return 1
|
|
fi
|
|
echo "$rfile"
|
|
}
|
|
function get_pfile() {
|
|
# obtenir le chemin du fichier $1 exprimé par rapport au répertoire du
|
|
# profil $2 dans le répertoire de projet $3
|
|
# retourner 1 si le chemin est invalide (est situé en dehors de pffdir ou
|
|
# pas dans un répertoire de profil)
|
|
local pfile="$1" profile="$2" pffdir="$3"
|
|
setx pfile=abspath "$pfile"
|
|
[ "${pfile#$pffdir/}" != "$pfile" ] || return 1
|
|
pfile="${pfile#$pffdir/}"
|
|
if [[ "$pfile" == pff/*/* ]]; then
|
|
pfile="${pfile#pff/*/}"
|
|
elif [[ "$pfile" == pff/* ]]; then
|
|
return 1
|
|
fi
|
|
echo "$pffdir/pff/$profile/$pfile"
|
|
}
|
|
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() {
|
|
# afficher tous les fichiers de version
|
|
local pffdir="$1" rfile="$2" profile="${3:-Base}"
|
|
[ -d "$pffdir/pff/$profile" ] || return
|
|
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/||"
|
|
else
|
|
find "$pffdir/pff/$profile" \
|
|
-type f -name "*__pv-*__" -o \
|
|
-type l -name "*__pv-*__" \
|
|
| sed "s|^$pffdir/pff/$profile/||"
|
|
fi
|
|
}
|
|
|
|
function sync_vlfiles() {
|
|
# synchroniser les fichiers de version $3..@ dans tous les répertoires de
|
|
# profil, ou seulement le répertoire de profil $2 si la valeur n'est pas
|
|
# vide.
|
|
local pffdir="$1"; shift
|
|
local profile="$1"; shift
|
|
local -a profiles
|
|
if [ -n "$profile" ]; then
|
|
profiles=("$profile")
|
|
else
|
|
array_from_lines profiles "$(get_profiles "$pffdir" | grep -vxF Base)"
|
|
fi
|
|
local vlfile rfile prefix pfile plink tmp
|
|
for vlfile in "$@"; do
|
|
rfile="${vlfile%__pv-*__}"
|
|
for profile in "${profiles[@]}"; do
|
|
prefix="$pffdir/pff/$profile"
|
|
flexists "$prefix/$rfile" || continue
|
|
pfile="$prefix/$vlfile"
|
|
setx plink=multiups "$profile/$vlfile" "Base/$vlfile"
|
|
if [ -L "$pfile" ]; then
|
|
# correction éventuelle du lien existant
|
|
setx tmp=readlink "$pfile"
|
|
[ "$tmp" == "$plink" ] || ln -sfT "$plink" "$pfile"
|
|
else
|
|
ln -sf "$plink" "$pfile" || return
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
function select_profile() {
|
|
# sélectionner le profil $1 dans le projet pff $2. créer d'abord le profil
|
|
# s'il n'existe pas.
|
|
local profile="$1" pffdir="$2"
|
|
# créer le répertoire de profil si nécessaire
|
|
mkdir -p "$pffdir/pff/$profile" || return 1
|
|
# mettre à jour les liens
|
|
local -a lfiles; local lfile src dest
|
|
setx -a lfiles=get_local_files "$pffdir"
|
|
for lfile in "${lfiles[@]}"; do
|
|
src="$pffdir/pff/Current/$lfile"
|
|
if [ -f "$pffdir/pff/$profile/$lfile" ]; then
|
|
dest="$profile/$lfile"
|
|
elif [ "$profile" != Common -a -f "$pffdir/pff/Common/$lfile" ]; then
|
|
dest="Common/$lfile"
|
|
else
|
|
dest="Base/$lfile"
|
|
fi
|
|
setx dest=multiups "Current/$lfile" "$dest"
|
|
[ -L "$src" ] || mkdirof "$src"
|
|
ln -sfT "$dest" "$src"
|
|
done
|
|
# maj du lien "profil courant"
|
|
ln -sfT "$profile" "$pffdir/pff/.Current"
|
|
}
|
|
|
|
function autoinit() {
|
|
# vérifications automatiques: créer les répertoires de base nécessaire au
|
|
# fonctionnement de pff dans le projet pff $1
|
|
local pffdir="$1" profile
|
|
[ -d "$pffdir/pff/Current" ] || mkdir -p "$pffdir/pff/Current"
|
|
[ -d "$pffdir/pff/Base" ] || mkdir -p "$pffdir/pff/Base"
|
|
}
|
|
|
|
function autoselect() {
|
|
# vérification automatiques: sélectionner le premier profil défini si aucun
|
|
# profil n'est sélectionné dans le projet pff $1
|
|
local pffdir="$1" profile
|
|
if [ ! -L "$pffdir/pff/.Current" ]; then
|
|
setx profile=get_first_profile "$pffdir"
|
|
[ -n "$profile" ] || profile=Base
|
|
enote "Autosélection du profil $profile"
|
|
select_profile "$profile" "$pffdir"
|
|
fi
|
|
}
|
|
|
|
function autofix() {
|
|
autoinit "$1"
|
|
autoselect "$1"
|
|
}
|
|
|
|
################################################################################
|
|
# Commandes
|
|
|
|
#===========================================================
|
|
# pff --init
|
|
|
|
function init_cmd() {
|
|
local workdir="$1" archive="$2"
|
|
local pffdir
|
|
|
|
if [ -z "$workdir" ]; then
|
|
estep "Initialisation d'un nouveau projet pff"
|
|
read_value "Veuillez entrer le répertoire du projet" workdir
|
|
fi
|
|
if find_pffdir pffdir "$workdir"; then
|
|
enote "$(ppath "$pffdir"): est déjà un projet pff"
|
|
if ask_yesno "Voulez-vous vérifier la configuration et la mettre à jour?" O; then
|
|
conf_init "${PFFCONFVARS[@]}"
|
|
source "$pffdir/$PFFCONF"
|
|
conf_upgrade "$workdir/$PFFCONF"
|
|
conf_update -n "$workdir/$PFFCONF" ORIGEXTS
|
|
fi
|
|
return 0
|
|
fi
|
|
if [ ! -d "$workdir" ]; then
|
|
ewarn "$workdir: ce répertoire n'existe pas"
|
|
ask_yesno "Voulez-vous le créer?" O || return 1
|
|
mkdir -p "$workdir" || return 1
|
|
fi
|
|
enote "Initialisation d'un nouveau projet pff dans $workdir"
|
|
# fichier de configuration
|
|
conf_upgrade "$workdir/$PFFCONF" "${PFFCONFVARS[@]}"
|
|
if [ "${ORIGEXTS[*]}" != "${DEFAULT_ORIGEXTS[*]}" ]; then
|
|
conf_update "$workdir/$PFFCONF" ORIGEXTS
|
|
fi
|
|
# répertoire pff
|
|
mkdir -p "$workdir/pff"
|
|
[ -f "$workdir/pff/.gitignore" ] || echo >"$workdir/pff/.gitignore" "\
|
|
/Current/
|
|
/.Current"
|
|
autofix "$workdir"
|
|
return 0
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --new
|
|
|
|
function new__prepare_archive() {
|
|
# préparer l'archive fournie en la copiant dans un répertoire temporaire
|
|
# initialiser la variable $1(=srcdir) avec le chemin du répertoire résultat
|
|
local destvar="${1:-srcdir}"; shift
|
|
local destver="${1:-version}"; shift
|
|
local archive="$1" version="$2" disttype="$3" unwrap="$4"
|
|
|
|
local srcdir
|
|
if [ -f "$archive" ]; then
|
|
is_archive "$archive" || die "$archive: doit être un fichier archive"
|
|
[ -n "$version" ] || version="$(get_archive_version "$archive")"
|
|
archive="$(abspath "$archive")"
|
|
elif [ -d "$archive" ]; then
|
|
srcdir="$(abspath "$archive")"
|
|
archive=
|
|
else
|
|
die "$archive: fichier introuvable"
|
|
fi
|
|
|
|
read_value "Entrez un identifiant pour cette version" version "$version" || die
|
|
|
|
local tmpd
|
|
if [ -n "$archive" ]; then
|
|
if [ "$disttype" == auto ]; then
|
|
case "$archive" in
|
|
*.war)
|
|
enote "Auto-sélection du type distribution complète sur la base de l'extension .war"
|
|
disttype=full
|
|
;;
|
|
*.zip)
|
|
enote "Auto-sélection du type distribution de patch sur la base de l'extension .zip"
|
|
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"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
ac_set_tmpdir tmpd
|
|
estep "Extraction de $(ppath "$archive" "$cwd")"
|
|
extract_archive "$archive" "$tmpd" || die
|
|
srcdir="$tmpd"
|
|
|
|
if [ -n "$unwrap" ]; then
|
|
local -a files
|
|
array_lsall files "$srcdir" "*" ".*"
|
|
if [ "${#files[*]}" -eq 1 ]; then
|
|
local file="${files[0]}"
|
|
if [ "$unwrap" == auto ]; then
|
|
# nom de l'archive avec la version
|
|
local banv="$(get_archive_basename "$archive")"
|
|
# nom de l'archive sans la version
|
|
local ban="${banv%$(get_archive_versionsuffix "$archive")}"
|
|
local filename="$(basename "$file")"
|
|
[ "$filename" == "$banv" -o "$filename" == "$ban" ] || unwrap=
|
|
fi
|
|
[ -n "$unwrap" -a -d "$file" ] && srcdir="$file"
|
|
fi
|
|
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"
|
|
fi
|
|
|
|
ac_set_tmpdir tmpd
|
|
estep "Création d'une copie de travail de $(ppath "$srcdir" "$cwd")"
|
|
rsync ${QUIET:+-q} -a "$srcdir/" "$tmpd" || die
|
|
srcdir="$tmpd"
|
|
fi
|
|
|
|
local "$destvar"; upvar "$destvar" "$srcdir"
|
|
local "$destver"; upvar "$destver" "$version"
|
|
}
|
|
|
|
function new_cmd() {
|
|
local autopatch="$1" version="$2" disttype="$3" unwrap="$4"; shift; shift; shift; shift
|
|
local archive="$1" pffdir="$2"
|
|
|
|
ensure_pffdir pffdir "$pffdir"
|
|
|
|
## préparer la source: les fichiers entrants
|
|
local srcdir full
|
|
new__prepare_archive srcdir version "$archive" "$version" "$disttype" "$unwrap"
|
|
[ "$disttype" == full ] && full=1
|
|
|
|
## lister les fichiers dans la source et la destination
|
|
local workdir
|
|
ac_set_tmpdir workdir
|
|
|
|
# fichiers sources
|
|
local fnsrc0="$workdir/nsrc0" fosrc0="$workdir/osrc0"
|
|
>"$fnsrc0"
|
|
>"$fosrc0"
|
|
find "$srcdir" -type f | awkrun ORIGEXTS[@] prefix="$srcdir/" fnsrc="$fnsrc0" fosrc="$fosrc0" '{
|
|
found = 0
|
|
for (i = 1; i <= ORIGEXTS_count; i++) {
|
|
sub("^" prefix, "")
|
|
if ($0 ~ ORIGEXTS[i] "(/|$)") {
|
|
print >fosrc
|
|
found = 1
|
|
break
|
|
}
|
|
}
|
|
if (!found) {
|
|
print >fnsrc
|
|
}
|
|
}'
|
|
# fichiers destination
|
|
local -a find; local p
|
|
local fndest0="$workdir/ndest0" fldest0="$workdir/ldest0"
|
|
get_local_files "$pffdir" >"$fldest0"
|
|
for p in "${PROTECTS[@]}"; do
|
|
[ ${#find[*]} -gt 0 ] && find=("${find[@]}" -o)
|
|
if [ "${p#/}" != "$p" ]; then
|
|
# les fichiers à la racine
|
|
p="${p#/}"
|
|
if [ "${p%/}" != "$p" ]; then
|
|
find=("${find[@]}" -type d -path "$pffdir/${p%/}" -prune)
|
|
else
|
|
find=("${find[@]}" -type f -path "$pffdir/$p" -o -type l -path "$pffdir/$p")
|
|
fi
|
|
else
|
|
# fichiers n'importe où dans l'arborescence
|
|
if [ "${p%/}" != "$p" ]; then
|
|
find=("${find[@]}" -type d -name "${p%/}" -prune)
|
|
else
|
|
find=("${find[@]}" -type f -name "$p" -o -type l -name "$p")
|
|
fi
|
|
fi
|
|
done
|
|
[ ${#find[*]} -gt 0 ] && find=("${find[@]}" -o)
|
|
find=(find "$pffdir" "${find[@]}" -type f -print -o -type l -print)
|
|
"${find[@]}" | sed "s|^$pffdir/||" | grep -vxf "$fldest0" >"$fndest0"
|
|
|
|
## Traiter les fichiers normaux
|
|
|
|
local fnsrc="$workdir/nsrc" fndest="$workdir/ndest"
|
|
grep -vxf "$fldest0" "$fnsrc0" | csort >"$fnsrc"
|
|
csort "$fndest0" >"$fndest"
|
|
|
|
local fcreates="$workdir/creates" fdeletes="$workdir/deletes" fcds="$workdir/cds" fupdates="$workdir/updates"
|
|
>"$fcreates"
|
|
>"$fdeletes"
|
|
diff "$fnsrc" "$fndest" | awkrun fcreates="$fcreates" fupdates="$fupdates" fdeletes="$fdeletes" '{
|
|
c = substr($0, 1, 1)
|
|
f = substr($0, 3)
|
|
if (c == "<") print f >fcreates
|
|
else if (c == ">") print f >fdeletes
|
|
}'
|
|
cat "$fcreates" "$fdeletes" >"$fcds"
|
|
grep -vxf "$fcds" "$fnsrc" >"$fupdates"
|
|
local -a creates updates deletes r i have_creates have_updates have_deletes src dest
|
|
array_from_lines creates "$(<"$fcreates")"; [ ${#creates[*]} -gt 0 ] && have_creates=1 || have_creates=
|
|
array_from_lines updates "$(<"$fupdates")"; [ ${#updates[*]} -gt 0 ] && have_updates=1 || have_updates=
|
|
array_from_lines deletes "$(<"$fdeletes")"; [ ${#deletes[*]} -gt 0 ] && have_deletes=1 || have_deletes=
|
|
enote "Fichiers normaux: $((${#creates[*]} + ${#updates[*]})) au total, ${#creates[*]} nouveau(x)${full:+", ${#deletes[*]} à supprimer"}"
|
|
ask_any -i "Voulez-vous continuer?" +Od; r=$?
|
|
if [ $r == 2 ]; then
|
|
for i in "${updates[@]}"; do
|
|
echo " $i"
|
|
done
|
|
for i in "${creates[@]}"; do
|
|
echo "+$i"
|
|
done
|
|
if [ -n "$full" ]; then
|
|
for i in "${deletes[@]}"; do
|
|
echo "-$i"
|
|
done
|
|
fi
|
|
ask_yesno "Voulez-vous continuer?" O || return 1
|
|
elif [ $r == 1 ]; then
|
|
return 1
|
|
fi
|
|
|
|
if [ -n "$have_creates" -o -n "$have_updates" -o -n "$have_deletes" ]; then
|
|
ebegin "Copie des fichiers"
|
|
r=0
|
|
for i in "${creates[@]}"; do
|
|
mkdirof "$pffdir/$i"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
cp "$srcdir/$i" "$pffdir/$i"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
done
|
|
[ $r == 0 ] || { eend $r; return 1; }
|
|
for i in "${updates[@]}"; do
|
|
src="$srcdir/$i"
|
|
dest="$pffdir/$i"
|
|
if diff -q "$src" "$dest" >&/dev/null; then
|
|
# pas la peine de copier si les fichiers sont identiques
|
|
show_debug && edot 0 "$i: non modifié"
|
|
continue
|
|
fi
|
|
cat "$src" >"$dest"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
done
|
|
[ $r == 0 ] || { eend $r; return 1; }
|
|
if [ -n "$full" ]; then
|
|
# ne faire les suppression qu'en mode full
|
|
for i in "${deletes[@]}"; do
|
|
rm "$pffdir/$i"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
done
|
|
fi
|
|
eend $r
|
|
fi
|
|
|
|
## Traiter les fichiers origines
|
|
|
|
local ftmp="$workdir/tmp"
|
|
local fosrc="$workdir/osrc" flosrc="$workdir/losrc" flsrc="$workdir/lsrc" fldest="$workdir/ldest"
|
|
csort "$fosrc0" >"$fosrc"
|
|
>"$flsrc"
|
|
>"$flosrc"
|
|
awkrun <"$fosrc0" ORIGEXTS[@] flsrc="$flsrc" flosrc="$flosrc" '{
|
|
for (i = 1; i <= ORIGEXTS_count; i++) {
|
|
if ($0 ~ ORIGEXTS[i] "(/|$)") {
|
|
orig = $0
|
|
local = gensub(ORIGEXTS[i] "(/|$)", "\\1", 1, $0)
|
|
print local ":" orig >flosrc
|
|
print local >flsrc
|
|
break
|
|
}
|
|
}
|
|
}'
|
|
csort "$flsrc" >"$ftmp"; cat "$ftmp" >"$flsrc"
|
|
csort "$fldest0" >"$fldest"
|
|
|
|
local losrc lsrc osrc; local -a tmpa; declare -A losrcs
|
|
array_from_lines tmpa "$(<"$flosrc")"
|
|
for losrc in "${tmpa[@]}"; do
|
|
splitpair "$losrc" lsrc osrc
|
|
losrcs["$lsrc"]="$osrc"
|
|
done
|
|
|
|
>"$fcreates"
|
|
>"$fdeletes"
|
|
diff "$flsrc" "$fldest" | awkrun fcreates="$fcreates" fupdates="$fupdates" fdeletes="$fdeletes" '{
|
|
c = substr($0, 1, 1)
|
|
f = substr($0, 3)
|
|
if (c == "<") print f >fcreates
|
|
else if (c == ">") print f >fdeletes
|
|
}'
|
|
cat "$fcreates" "$fdeletes" >"$fcds"
|
|
grep -vxf "$fcds" "$flsrc" >"$fupdates"
|
|
array_from_lines creates "$(<"$fcreates")"; [ ${#creates[*]} -gt 0 ] && have_creates=1 || have_creates=
|
|
array_from_lines updates "$(<"$fupdates")"; [ ${#updates[*]} -gt 0 ] && have_updates=1 || have_updates=
|
|
enote "Fichiers origines: $((${#creates[*]} + ${#updates[*]})) au total, ${#creates[*]} nouveau(x)"
|
|
ask_any -i "Voulez-vous continuer?" +Od; r=$?
|
|
if [ $r == 2 ]; then
|
|
for i in "${updates[@]}"; do
|
|
echo " $i"
|
|
done
|
|
for i in "${creates[@]}"; do
|
|
echo "+$i"
|
|
done
|
|
ask_yesno "Voulez-vous continuer?" O || return 1
|
|
elif [ $r == 1 ]; then
|
|
return 1
|
|
fi
|
|
|
|
local vlfile; local -a vlfiles
|
|
if [ -n "$have_creates" -o -n "$have_updates" ]; then
|
|
ebegin "Copie des fichiers"
|
|
r=0
|
|
for i in "${creates[@]}"; do
|
|
src="$srcdir/${losrcs[$i]}"
|
|
dest="$pffdir/$i"
|
|
mkdirof "$dest"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
cp "$src" "$dest"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
add_global__link "$dest" "$pffdir"
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
done
|
|
[ $r == 0 ] || { eend $r; return 1; }
|
|
for i in "${updates[@]}"; do
|
|
src="$srcdir/${losrcs[$i]}"
|
|
vlfile="${i}__pv-${version}__"
|
|
dest="$pffdir/pff/Base/$vlfile"
|
|
mkdirof "$dest"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
cp "$src" "$dest"; r=$?
|
|
edot $r "$i"; [ $r == 0 ] || break
|
|
array_add vlfiles "$vlfile"
|
|
done
|
|
[ $r == 0 ] || { eend $r; return 1; }
|
|
eend $r
|
|
fi
|
|
|
|
sync_vlfiles "$pffdir" "" "${vlfiles[@]}"
|
|
array_addu PVERSIONS "$version"
|
|
conf_update "$pffdir/$PFFCONF" PVERSIONS
|
|
|
|
## Fin du traitement
|
|
ac_clean "$srcdir" "$workdir"
|
|
|
|
if [ -n "$autopatch" ]; then
|
|
# lancer la commande patch pour intégrer les modifications
|
|
patch_cmd "$pffdir"
|
|
fi
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --patch
|
|
|
|
function patch_cmd() {
|
|
local pffdir="$1"
|
|
|
|
ensure_pffdir pffdir "$pffdir"
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --add-global
|
|
|
|
function add_global__link() {
|
|
local pfile="$1" pffdir="$2"
|
|
local rfile bfile cfile plink clink tmp
|
|
|
|
setx rfile=get_rfile "$pfile" "$pffdir" || return
|
|
flexists "$pffdir/$rfile" || touch "$pffdir/$rfile"
|
|
|
|
setx bfile=get_bfile "$pfile" "$pffdir"
|
|
setx cfile=get_cfile "$pfile" "$pffdir"
|
|
setx plink=multiups "$rfile" "pff/Current/$rfile"
|
|
setx clink=multiups "Current/$rfile" "Base/$rfile"
|
|
if flexists "$bfile" && [ -L "$pfile" -a -L "$cfile" ]; then
|
|
: # ok pour les liens
|
|
else
|
|
# Création des liens pour $rfile
|
|
mkdirof "$bfile" || return
|
|
mv "$pfile" "$bfile" || return
|
|
[ -L "$pfile" ] || ln -sf "$plink" "$pfile" || return
|
|
mkdirof "$cfile" || return
|
|
[ -L "$cfile" ] || ln -sf "$clink" "$cfile" || return
|
|
fi
|
|
# correction éventuelle du lien existant
|
|
setx tmp=readlink "$pfile"
|
|
[ "$tmp" == "$plink" ] || ln -sfT "$plink" "$pfile"
|
|
return 0
|
|
}
|
|
|
|
function add_global_cmd() {
|
|
local pffdir file pfile
|
|
|
|
ensure_pffdir pffdir
|
|
for file in "$@"; do
|
|
if [ -d "$file" ]; then
|
|
ewarn "$file: est un répertoire. argument ignoré"
|
|
continue
|
|
elif flexists "$file"; then
|
|
:
|
|
else
|
|
ewarn "$file: fichier introuvable"
|
|
ask_yesno "Voulez-vous le créer?" O || continue
|
|
fi
|
|
setx pfile=abspath "$file"
|
|
setx rfile=get_rfile "$pfile" || {
|
|
eerror "$file: chemin invalide. argument ignoré"
|
|
continue
|
|
}
|
|
add_global__link "$pfile" "$pffdir" || return
|
|
done
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --locals
|
|
|
|
function list_locals_cmd() {
|
|
local pffdir="$1"
|
|
|
|
ensure_pffdir pffdir "$pffdir"
|
|
get_local_files "$pffdir"
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --profiles
|
|
|
|
function list_profiles_cmd() {
|
|
local pffdir="$1"
|
|
|
|
ensure_pffdir pffdir "$pffdir"
|
|
get_profiles "$pffdir"
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --switch
|
|
|
|
function switch_cmd() {
|
|
local profile="$1" pffdir="$2"
|
|
local -a profiles
|
|
|
|
[ -n "$profile" ] || profile=Base
|
|
|
|
ensure_pffdir pffdir "$pffdir"
|
|
autoinit "$pffdir"
|
|
setx -a profiles=get_profiles "$pffdir"
|
|
if ! array_contains profiles "$profile"; then
|
|
if ! array_contains PROFILES "$profile"; then
|
|
ewarn "$profile: ce profil n'existe pas"
|
|
ask_yesno "Voulez-vous le créer?" O || return 1
|
|
|
|
array_addu PROFILES "$profile"
|
|
conf_update "$pffdir/$PFFCONF" PROFILES
|
|
fi
|
|
fi
|
|
enote "Sélection du profil $profile"
|
|
select_profile "$profile" "$pffdir"
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --add-local
|
|
|
|
function add_local__link() {
|
|
local pfile="$1" profile="$2" pffdir="$3"
|
|
local rfile bfile pfile Pfile plink Plink
|
|
# vérifier validité du chemin
|
|
setx rfile=get_rfile "$pfile" "$pffdir" || return
|
|
flexists "$pffdir/$rfile" || touch "$pffdir/$rfile"
|
|
# vérifier la présence du lien global
|
|
setx bfile=get_bfile "$pfile" "$pffdir"
|
|
if ! flexists "$bfile"; then
|
|
add_global__link "$pfile" "$pffdir" || return
|
|
fi
|
|
# vérifier la présence du lien local
|
|
setx Pfile=get_pfile "$pfile" "$profile" "$pffdir"
|
|
flexists "$Pfile" && return 0
|
|
# créer le fichier local
|
|
setx Cfile=get_Cfile "$pfile" "$pffdir"
|
|
mkdirof "$Pfile"
|
|
if flexists "$Cfile"; then
|
|
# copier depuis le profil Common par défaut
|
|
cp "$Cfile" "$Pfile"
|
|
else
|
|
cp "$bfile" "$Pfile"
|
|
fi
|
|
# mettre à jour le profil courant
|
|
setx cfile=get_cfile "$pfile" "$pffdir"
|
|
setx clink=multiups "Current/$rfile" "$profile/$rfile"
|
|
ln -sf "$clink" "$cfile"
|
|
# intégrer les fichiers de version
|
|
local -a vlfiles
|
|
array_from_lines vlfiles "$(get_vlfiles "$pffdir" "$rfile")"
|
|
sync_vlfiles "$pffdir" "$profile" "${vlfiles[@]}"
|
|
return 0
|
|
}
|
|
|
|
function add_local_cmd() {
|
|
local pffdir file rfile pfile
|
|
local profile r
|
|
|
|
ensure_pffdir pffdir
|
|
setx profile=get_current_profile "$pffdir"
|
|
r=0
|
|
for file in "$@"; do
|
|
if [ -d "$file" ]; then
|
|
ewarn "$file: est un répertoire. argument ignoré"
|
|
continue
|
|
elif flexists "$file"; then
|
|
:
|
|
else
|
|
ewarn "$file: fichier introuvable"
|
|
ask_yesno "Voulez-vous le créer?" O || continue
|
|
fi
|
|
setx pfile=abspath "$file"
|
|
setx rfile=get_rfile "$pfile" || {
|
|
eerror "$file: chemin invalide. argument ignoré"
|
|
r=1
|
|
continue
|
|
}
|
|
add_local__link "$pfile" "$profile" "$pffdir" || {
|
|
ewarn "$file: erreur lors de la création du lien local"
|
|
r=1
|
|
continue
|
|
}
|
|
done
|
|
return $r
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --edit
|
|
|
|
function edit_cmd() {
|
|
local pffdir file rfile pfile Pfile
|
|
local profile r
|
|
local -a edits
|
|
|
|
ensure_pffdir pffdir
|
|
setx profile=get_current_profile "$pffdir"
|
|
enote "Edition des fichiers dans le profil $profile"
|
|
|
|
r=0
|
|
for file in "$@"; do
|
|
if [ -d "$file" ]; then
|
|
ewarn "$file: est un répertoire. argument ignoré"
|
|
continue
|
|
fi
|
|
setx pfile=abspath "$file"
|
|
setx rfile=get_rfile "$pfile" || {
|
|
eerror "$file: chemin invalide. argument ignoré"
|
|
r=1
|
|
continue
|
|
}
|
|
add_local__link "$pfile" "$profile" "$pffdir" || {
|
|
ewarn "$file: erreur lors de la création du lien local"
|
|
r=1
|
|
continue
|
|
}
|
|
setx Pfile=get_pfile "$pfile" "$profile" "$pffdir"
|
|
array_add edits "$Pfile"
|
|
done
|
|
|
|
"${EDITOR:-vi}" "${edits[@]}" || r=$?
|
|
return $r
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --diff
|
|
|
|
function diff_cmd() {
|
|
local list_names="$1"; shift
|
|
|
|
local pffdir profile srcp destp desc
|
|
case $# in
|
|
0)
|
|
ensure_pffdir pffdir
|
|
setx srcp=get_current_profile "$pffdir"
|
|
destp=
|
|
;;
|
|
1)
|
|
if withpath "$1"; then
|
|
ensure_pffdir pffdir "$1"
|
|
setx srcp=get_current_profile "$pffdir"
|
|
destp=
|
|
else
|
|
ensure_pffdir pffdir
|
|
setx srcp=get_current_profile "$pffdir"
|
|
destp="$1"
|
|
fi
|
|
;;
|
|
2)
|
|
if withpath "$2"; then
|
|
ensure_pffdir pffdir "$2"
|
|
setx srcp=get_current_profile "$pffdir"
|
|
destp="$1"
|
|
else
|
|
ensure_pffdir pffdir
|
|
srcp="$1"
|
|
destp="$2"
|
|
fi
|
|
;;
|
|
*)
|
|
ensure_pffdir pffdir "$3"
|
|
srcp="$1"
|
|
destp="$2"
|
|
;;
|
|
esac
|
|
[ "$destp" == "Common|Base" ] && destp=
|
|
if [ -z "$destp" ]; then
|
|
if [ "$srcp" == Base -o "$srcp" == Common ]; then
|
|
desc="pff --diff $srcp Base"
|
|
else
|
|
desc="pff --diff $srcp ${destp:-"Common|Base"}"
|
|
fi
|
|
else
|
|
desc="pff --diff $srcp $destp"
|
|
fi
|
|
|
|
local -a lfiles; local rfile bfile Cfile srcfile destfile
|
|
setx -a lfiles=get_local_files "$pffdir"
|
|
|
|
for rfile in "${lfiles[@]}"; do
|
|
setx srcfile=get_pfile "$pffdir/$rfile" "$srcp" "$pffdir"
|
|
flexists "$srcfile" || continue
|
|
if [ -n "$destp" ]; then
|
|
setx destfile=get_pfile "$pffdir/$rfile" "$destp" "$pffdir"
|
|
else
|
|
setx Cfile=get_Cfile "$pffdir/$rfile" "$pffdir"
|
|
setx bfile=get_bfile "$pffdir/$rfile" "$pffdir"
|
|
# si on précise pas le profil destination, sélectionner dans l'ordre
|
|
# Common ou Base
|
|
if [ "$srcp" == Base -o "$srcp" == Common ]; then
|
|
destfile="$bfile"
|
|
elif flexists "$Cfile"; then
|
|
destfile="$Cfile"
|
|
else
|
|
destfile="$bfile"
|
|
fi
|
|
fi
|
|
if [ -n "$list_names" ]; then
|
|
diff -q "$srcfile" "$destfile" >&/dev/null || echo "$srcfile"
|
|
else
|
|
[ -n "$desc" ] && echo "$desc"
|
|
desc=
|
|
diff -ur "$srcfile" "$destfile"
|
|
fi
|
|
done | page_maybe
|
|
}
|
|
|
|
#===========================================================
|
|
# pff --infos
|
|
|
|
function infos_cmd() {
|
|
local show_all="$1"; shift
|
|
local pffdir="$1"
|
|
local -a profiles vlfiles
|
|
local rfile Pfile flag
|
|
|
|
if find_pffdir pffdir "$pffdir"; then
|
|
ensure_pffdir pffdir "$pffdir"
|
|
autofix "$pffdir"
|
|
setx -a lfiles=get_local_files "$pffdir"
|
|
setx profile=get_current_profile "$pffdir"
|
|
setx -a profiles=get_profiles "$pffdir"
|
|
|
|
if [ ${#lfiles[*]} -gt 0 ]; then
|
|
[ ${#lfiles[*]} -gt 1 ] && estep "${#lfiles[*]} fichiers locaux" || estep "1 fichier local"
|
|
for rfile in "${lfiles[@]}"; do
|
|
setx -a vlfiles=get_vlfiles "$pffdir" "$rfile" "$profile"
|
|
setx Pfile=get_pfile "$pffdir/$rfile" "$profile" "$pffdir"
|
|
setx Cfile=get_Cfile "$pffdir/$rfile" "$pffdir"
|
|
if [ ${#vlfiles[*]} -gt 0 ]; then
|
|
flag="${COULEUR_ROUGE}P${COULEUR_NORMALE} "
|
|
elif [ -f "$Pfile" ]; then
|
|
flag="${COULEUR_BLEUE}*${COULEUR_NORMALE} "
|
|
elif [ "$profile" != Common -a -f "$Cfile" ]; then
|
|
flag="$(get_color YELLOW)C${COULEUR_NORMALE} "
|
|
elif [ -z "$show_all" ]; then
|
|
continue
|
|
else
|
|
flag=" "
|
|
fi
|
|
uecho " $flag$rfile"
|
|
done
|
|
else
|
|
estep "Pas de fichiers locaux définis"
|
|
fi
|
|
estep "Version courante: ${COULEUR_BLEUE}$VERSION${COULEUR_NORMALE}"
|
|
estep "Versions en attente: ${COULEUR_ROUGE}${PVERSIONS[*]}${COULEUR_NORMALE}"
|
|
[ -n "$profile" ] && estep "Profil courant: ${COULEUR_BLEUE}$profile${COULEUR_NORMALE}" || estep "${COULEUR_JAUNE}Pas de profil courant${COULEUR_NORMALE}"
|
|
[ ${#profiles[*]} -gt 0 ] && estep "Profils valides: ${profiles[*]}" || estep "Pas de profils définis"
|
|
elif [ -f "${pffdir:-.}/$PFFCONF" ]; then
|
|
: "${pffdir:=.}"
|
|
conf_init "${PFFCONFVARS[@]}"
|
|
source "$pffdir/$PFFCONF"
|
|
estep "[Projet pff déployé] Version courante: ${COULEUR_BLEUE}$VERSION${COULEUR_NORMALE}"
|
|
fi
|
|
}
|
|
|
|
################################################################################
|
|
# Programme principal
|
|
|
|
for script_alias in "${SCRIPT_ALIASES[@]}"; do
|
|
splitpair "$script_alias" src option
|
|
if [ "$scriptname" == "$src" ]; then
|
|
eval "set -- $option \"\$@\""
|
|
break
|
|
fi
|
|
done
|
|
|
|
QUIET=1 # masquer les messages de git et rsync?
|
|
VERYQUIET=1 # masquer les messages de git commit?
|
|
|
|
action=infos
|
|
autopatch=1
|
|
version=
|
|
disttype=auto
|
|
ORIGEXTS=("${DEFAULT_ORIGEXTS[@]}")
|
|
PROTECTS=("${DEFAULT_PROTECTS[@]}")
|
|
unwrap=auto
|
|
alternate=
|
|
args=(
|
|
--help '$exit_with display_help'
|
|
-0,--init action=init
|
|
--s:,--origext: '$add@ ORIGEXTS'
|
|
--k,--clear-origexts '$ORIGEXTS=()'
|
|
-N,--new action=new
|
|
-M,--new-only '$action=new; autopatch='
|
|
-V:,--version: version=
|
|
--auto-archive disttype=auto
|
|
-F,--full-archive disttype=full
|
|
-P,--patch-archive disttype=patch
|
|
--auto-unwrap unwrap=auto
|
|
--no-unwrap unwrap=
|
|
-E,--unwrap unwrap=1
|
|
-p,--patch action=patch
|
|
-a,--add-global action=add-global
|
|
--locals action=list-locals
|
|
--profiles action=list-profiles
|
|
-s,--switch action=switch
|
|
-b,--add-local action=add-local
|
|
-e,--edit action=edit
|
|
-d,--diff action=diff
|
|
--infos action=infos
|
|
-l,--list-names,--show-all alternate=1
|
|
)
|
|
parse_args "$@"; set -- "${args[@]}"
|
|
|
|
array_fix_paths ORIGEXTS
|
|
|
|
case "$action" in
|
|
init) init_cmd "$@";;
|
|
new) new_cmd "$autopatch" "$version" "$disttype" "$unwrap" "$@";;
|
|
patch) patch_cmd "$@";;
|
|
add-global) add_global_cmd "$@";;
|
|
list-locals) list_locals_cmd "$@";;
|
|
list-profiles) list_profiles_cmd "$@";;
|
|
switch) switch_cmd "$@";;
|
|
add-local) add_local_cmd "$@";;
|
|
edit) edit_cmd "$@";;
|
|
diff) diff_cmd "$alternate" "$@";;
|
|
infos) infos_cmd "$alternate" "$@";;
|
|
esac
|