dk: support pff
This commit is contained in:
parent
425e8a5642
commit
5a444a65b9
164
dk
164
dk
|
@ -1,6 +1,7 @@
|
|||
#!/bin/bash
|
||||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
source "$(dirname "$0")/lib/ulib/auto" || exit 1
|
||||
urequire pff
|
||||
|
||||
function display_help() {
|
||||
uecho "$scriptname: outil pour faciliter l'utilisation de docker
|
||||
|
@ -181,8 +182,8 @@ OPTIONS build
|
|||
app_URL= # url du dépôt
|
||||
app_DEVEL_SRCDIR= # répertoire source en mode devel
|
||||
app_DEST= # répertoire dans lequel faire le checkout
|
||||
app_PROFILE_ORIGIN= # origine spécifique à un profil
|
||||
app_PROFILE_BRANCH= # branche spécifique à un profil
|
||||
app_PROFILE_ORIGIN= # origine spécifique au profil 'PROFILE'
|
||||
app_PROFILE_BRANCH= # branche spécifique au profil 'PROFILE'
|
||||
app_ORIGIN= # ou... origine par défaut de la branche
|
||||
app_BRANCH= # ou... branche par défaut
|
||||
app_TYPE= # type de projet (composer par défaut)
|
||||
|
@ -220,6 +221,14 @@ VARIABLES de update-apps.conf
|
|||
- si le chemin est absolu ou relatif, lancer la commande telle quelle
|
||||
- s'il n'y a pas de chemin, alors ce doit être le nom d'une fonction
|
||||
existante auquel on enlève le préfixe update_apps_func_
|
||||
Au moment où la commande est lancée, le répertoire courant est celui du
|
||||
projet. Les variables suivantes sont disponibles:
|
||||
URL= # url du dépôt
|
||||
DEVEL_SRCDIR= # répertoire source en mode devel
|
||||
DEST= # répertoire dans lequel faire le checkout
|
||||
ORIGIN= # ou... origine par défaut de la branche
|
||||
BRANCH= # ou... branche par défaut
|
||||
TYPE= # type de projet (composer par défaut)
|
||||
COMPOSER_ACTION
|
||||
vaut 'install' par défaut. Indique ce qu'il faut faire pour un projet de
|
||||
type 'composer' après avoir lancé les commandes de AFTER_UPDATE. Les
|
||||
|
@ -231,7 +240,19 @@ FONCTIONS de update-apps.conf
|
|||
SRCDIR/config/sqlmig vers DESTDIR/config/mariadb/sqlmig
|
||||
Si SRCDIR ne se termine pas par '/config/sqlmig' ou si DESTDIR ne se
|
||||
termine pas par '/config/mariadb/sqlmig', rajouter ces suffixes
|
||||
automatiquement, sauf si une valeur NOFIX est spécifiée."
|
||||
automatiquement, sauf si une valeur NOFIX est spécifiée.
|
||||
pff [MAPS [PFFDIR]]
|
||||
Si PFFDIR est un projet pff, mettre à jour le profil pff en fonction du
|
||||
profil de déploiement.
|
||||
MAPS détermine le mapping entre profil de déploiement (prod, test,
|
||||
devel) et le profil pff. Il s'agit d'une liste de valeurs séparées par
|
||||
des virgules de la forme DEST[:SRC]
|
||||
- Une valeur de la forme 'DEST:SRC' fait correspondre le profil de
|
||||
déploiement SRC au profil pff 'DEST'
|
||||
- Une valeur de la forme 'DEST' force le choix du profil pff DEST quel
|
||||
que soit le profil de déploiement
|
||||
- La valeur par défaut si aucun profil de déploiement ne correspond est
|
||||
de forcer le premier profil défini"
|
||||
}
|
||||
|
||||
function echo_lines() { local IFS=$'\n'; echo "$*"; }
|
||||
|
@ -441,7 +462,7 @@ function build_set_options() {
|
|||
function update_apps_func_sqlmig() {
|
||||
local destdir="$1" srcdir="$2" nofix="$3"
|
||||
[ -n "$destdir" ] || destdir=db
|
||||
[ -n "$srcdir" ] || srcdir="$dest"
|
||||
[ -n "$srcdir" ] || srcdir="$DEST"
|
||||
|
||||
if [ -z "$nofix" ]; then
|
||||
[ "${destdir%/config/mariadb/sqlmig}" != "$destdir" ] || destdir="$destdir/config/mariadb/sqlmig"
|
||||
|
@ -467,6 +488,48 @@ function update_apps_func_sqlmig() {
|
|||
return 0
|
||||
}
|
||||
|
||||
function update_apps_func_pff() {
|
||||
local maps="$1" pffdir="${2:-$DEST}"
|
||||
[ -f "$pffdir/$PFF_CONF" ] || return 0
|
||||
|
||||
source "$pffdir/$PFF_CONF"
|
||||
pff_autofix "$pffdir"
|
||||
|
||||
local map src dest
|
||||
array_split maps "$maps" ,
|
||||
for map in "${maps[@]}"; do
|
||||
if [ -z "$map" ]; then
|
||||
continue
|
||||
elif [[ "$map" == *:* ]]; then
|
||||
# mapping de profil
|
||||
splitpair "$map" dest src
|
||||
if [ "$src" == "$PROFILE" ]; then
|
||||
if array_contains PROFILES "$dest"; then
|
||||
estep "Sélection du profil pff $dest"
|
||||
pff_select_profile "$dest" "$pffdir"
|
||||
return 0
|
||||
fi
|
||||
eerror "$dest: profil invalide, il a été ignoré"
|
||||
fi
|
||||
else
|
||||
# forcer le profil
|
||||
dest="$map"
|
||||
if array_contains PROFILES "$dest"; then
|
||||
estep "Sélection du profil pff $dest"
|
||||
pff_select_profile "$dest" "$pffdir"
|
||||
return 0
|
||||
fi
|
||||
eerror "$dest: profil invalide, il a été ignoré"
|
||||
fi
|
||||
done
|
||||
# sélectionner le premier profil
|
||||
setx dest=pff_get_first_profile "$pffdir"
|
||||
if [ -n "$dest" ]; then
|
||||
estep "Sélection du profil pff $dest"
|
||||
pff_select_profile "$dest" "$pffdir"
|
||||
fi
|
||||
}
|
||||
|
||||
function build_update_apps() {
|
||||
[ -n "$BUILD_UPDATE_APPS" ] || return 0
|
||||
[ -f update-apps.conf ] || return 0
|
||||
|
@ -493,84 +556,84 @@ function build_update_apps() {
|
|||
esac
|
||||
|
||||
etitle "Mise à jour des dépendances"
|
||||
local app var type url devel_srcdir dest branch after_update after_updates composer_action
|
||||
local app var URL DEVEL_SRCDIR DEST ORIGIN BRANCH TYPE after_update after_updates composer_action
|
||||
for app in "${APPS[@]}"; do
|
||||
etitle "$app"
|
||||
|
||||
var="${app//-/_}"
|
||||
|
||||
url="${var}_URL"; url="${!url}"
|
||||
[ -n "$url" ] || {
|
||||
URL="${var}_URL"; URL="${!URL}"
|
||||
[ -n "$URL" ] || {
|
||||
ewarn "$app: vous devez définir l'url"
|
||||
eend; return 1
|
||||
}
|
||||
|
||||
devel_srcdir="${var}_DEVEL_SRCDIR"; devel_srcdir="${!devel_srcdir}"
|
||||
[ -n "$devel_srcdir" ] || devel_srcdir="$DEFAULT_DEVEL_SRCDIR/${url##*/}"
|
||||
DEVEL_SRCDIR="${var}_DEVEL_SRCDIR"; DEVEL_SRCDIR="${!DEVEL_SRCDIR}"
|
||||
[ -n "$DEVEL_SRCDIR" ] || DEVEL_SRCDIR="$DEFAULT_DEVEL_SRCDIR/${URL##*/}"
|
||||
|
||||
dest="${var}_DEST"; dest="${!dest}"
|
||||
[ -n "$dest" ] || dest="$app/b"
|
||||
mkdir -p "$dest" || { eend; return 1; }
|
||||
DEST="${var}_DEST"; DEST="${!DEST}"
|
||||
[ -n "$DEST" ] || DEST="$app/b"
|
||||
mkdir -p "$DEST" || { eend; return 1; }
|
||||
|
||||
origin="${var}_${PROFILE}_ORIGIN"; origin="${!origin}"
|
||||
[ -n "$origin" ] || { origin="${var}_ORIGIN"; origin="${!origin}"; }
|
||||
[ -n "$origin" ] || origin="$DEFAULT_ORIGIN"
|
||||
ORIGIN="${var}_${PROFILE}_ORIGIN"; ORIGIN="${!ORIGIN}"
|
||||
[ -n "$ORIGIN" ] || { ORIGIN="${var}_ORIGIN"; ORIGIN="${!ORIGIN}"; }
|
||||
[ -n "$ORIGIN" ] || ORIGIN="$DEFAULT_ORIGIN"
|
||||
|
||||
branch="${var}_${PROFILE}_BRANCH"; branch="${!branch}"
|
||||
[ -n "$branch" ] || { branch="${var}_BRANCH"; branch="${!branch}"; }
|
||||
[ -n "$branch" ] || branch="$DEFAULT_BRANCH"
|
||||
BRANCH="${var}_${PROFILE}_BRANCH"; BRANCH="${!BRANCH}"
|
||||
[ -n "$BRANCH" ] || { BRANCH="${var}_BRANCH"; BRANCH="${!BRANCH}"; }
|
||||
[ -n "$BRANCH" ] || BRANCH="$DEFAULT_BRANCH"
|
||||
|
||||
# calculer le type maintenant, on en a besoin pour le mode devel
|
||||
type="${var}_TYPE"; type="${!type}"
|
||||
TYPE="${var}_TYPE"; TYPE="${!TYPE}"
|
||||
|
||||
dest="$dest/$app"
|
||||
DEST="$DEST/$app"
|
||||
if [ -n "$BUILD_UPDATE_DEVEL" ]; then
|
||||
# synchronisation en mode devel
|
||||
local -a rsync_opts; rsync_opts=(-a --delete --exclude .git/ --delete-excluded)
|
||||
estep "Synchro $devel_srcdir --> $dest"
|
||||
rsync "${rsync_opts[@]}" "$devel_srcdir/" "$dest" || { eend; return 1; }
|
||||
estep "Synchro $DEVEL_SRCDIR --> $DEST"
|
||||
rsync "${rsync_opts[@]}" "$DEVEL_SRCDIR/" "$DEST" || { eend; return 1; }
|
||||
|
||||
if [ -z "$type" ]; then
|
||||
if [ -z "$TYPE" ]; then
|
||||
# possible de détecter le type quand on a le projet
|
||||
# en cas de maj ici, mettre à jour aussi le code ci-dessous
|
||||
if [ -f "$dest/composer.json" ]; then type=composer
|
||||
else type=inconnu
|
||||
if [ -f "$DEST/composer.json" ]; then TYPE=composer
|
||||
else TYPE=inconnu
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$type" == composer ]; then
|
||||
if [ "$TYPE" == composer ]; then
|
||||
# Synchronisation des dépendances
|
||||
local -a depdirs; local depdir pname
|
||||
setx -a depdirs=ls -d "$dest/vendor/"{lib,ur}/* 2>/dev/null
|
||||
setx -a depdirs=ls -d "$DEST/vendor/"{lib,ur}/* 2>/dev/null
|
||||
for depdir in "${depdirs[@]}"; do
|
||||
[ -L "$depdir" ] && rm "$depdir"
|
||||
pname="${depdir#$dest/vendor/}"; pname="${pname/\//-}"
|
||||
pname="${depdir#$DEST/vendor/}"; pname="${pname/\//-}"
|
||||
estep "Synchro $DEFAULT_DEVEL_SRCDIR/$pname --> $depdir"
|
||||
rsync "${rsync_opts[@]}" --exclude /vendor/ "$DEFAULT_DEVEL_SRCDIR/$pname/" "$depdir"
|
||||
done
|
||||
fi
|
||||
else
|
||||
if [ -d "$dest" -a -d "$dest/.git" ]; then
|
||||
if [ -d "$DEST" -a -d "$DEST/.git" ]; then
|
||||
# mise à jour
|
||||
estep "Maj dépôt $url:$branch --> $dest"
|
||||
estep "Maj dépôt $URL:$BRANCH --> $DEST"
|
||||
setx cwd=pwd
|
||||
cd "$dest"
|
||||
cd "$DEST"
|
||||
git fetch --all -p -f || { eend; return 1; }
|
||||
git reset --hard "$origin/$branch" || { eend; return 1; }
|
||||
git reset --hard "$ORIGIN/$BRANCH" || { eend; return 1; }
|
||||
cd "$cwd"
|
||||
else
|
||||
# reliquat mode devel?
|
||||
[ -d "$dest" ] && rm -rf "$dest"
|
||||
[ -d "$DEST" ] && rm -rf "$DEST"
|
||||
# clonage initial
|
||||
estep "Clonage $url:$branch --> $dest"
|
||||
git clone -o "$origin" -b "$branch" "$url" "$dest" || { eend; return 1; }
|
||||
estep "Clonage $URL:$BRANCH --> $DEST"
|
||||
git clone -o "$ORIGIN" -b "$BRANCH" "$URL" "$DEST" || { eend; return 1; }
|
||||
fi
|
||||
|
||||
if [ -z "$type" ]; then
|
||||
if [ -z "$TYPE" ]; then
|
||||
# possible de détecter le type quand on a le projet
|
||||
# en cas de maj ici, mettre à jour aussi le code ci-dessus
|
||||
if [ -f "$dest/composer.json" ]; then type=composer
|
||||
else type=inconnu
|
||||
if [ -f "$DEST/composer.json" ]; then TYPE=composer
|
||||
else TYPE=inconnu
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -578,20 +641,20 @@ function build_update_apps() {
|
|||
after_updates="${var}_AFTER_UPDATE"
|
||||
if is_defined "$after_updates"; then
|
||||
after_updates="$after_updates[@]"; after_updates=("${!after_updates}")
|
||||
elif [ "$type" == composer ]; then
|
||||
elif [ "$TYPE" == composer ]; then
|
||||
after_updates=(sqlmig)
|
||||
else
|
||||
after_updates=()
|
||||
fi
|
||||
|
||||
estep "Type de dépôt: $type"
|
||||
if [ "$type" == composer ]; then
|
||||
estep "Type de dépôt: $TYPE"
|
||||
if [ "$TYPE" == composer ]; then
|
||||
composer_action="${var}_${PROFILE}_COMPOSER_ACTION"; composer_action="${!composer_action}"
|
||||
[ -n "$composer_action" ] || { composer_action="${var}_COMPOSER_ACTION"; composer_action="${!composer_action}"; }
|
||||
[ -n "$composer_action" ] || composer_action="$DEFAULT_COMPOSER_ACTION"
|
||||
|
||||
composer=/usr/bin/composer
|
||||
[ -x "$dest/composer.phar" ] && composer="$dest/composer.phar"
|
||||
[ -x "$DEST/composer.phar" ] && composer="$DEST/composer.phar"
|
||||
|
||||
if [ -z "$BUILD_UPDATE_DEVEL" ]; then
|
||||
case "${composer_action:-install}" in
|
||||
|
@ -602,7 +665,7 @@ function build_update_apps() {
|
|||
esac
|
||||
if [ -n "$composer_action" ]; then
|
||||
estep "Installation des dépendances composer"
|
||||
"$composer" -d"$dest" "$composer_action" ${PRODUCTION:+--no-dev -o} || { eend; return 1; }
|
||||
"$composer" -d"$DEST" "$composer_action" ${PRODUCTION:+--no-dev -o} || { eend; return 1; }
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -610,16 +673,19 @@ function build_update_apps() {
|
|||
for after_update in "${after_updates[@]}"; do
|
||||
if [ "${after_update#/}" != "$after_update" ]; then
|
||||
# commande absolue, la lancer telle quelle
|
||||
estep "$after_update"
|
||||
eval "$after_update" || { eend; return 1; }
|
||||
etitle "$after_update"
|
||||
eval "$after_update" || { eend; eend; return 1; }
|
||||
eend
|
||||
elif [ "${after_update#./}" != "$after_update" ]; then
|
||||
# commande relative, la lancer telle quelle
|
||||
estep "$after_update"
|
||||
eval "$after_update" || { eend; return 1; }
|
||||
etitle "$after_update"
|
||||
eval "$after_update" || { eend; eend; return 1; }
|
||||
eend
|
||||
else
|
||||
# c'est une fonction update_apps_func_*
|
||||
estep "$after_update"
|
||||
eval "update_apps_func_$after_update" || { eend; return 1; }
|
||||
etitle "$after_update"
|
||||
eval "update_apps_func_$after_update" || { eend; eend; return 1; }
|
||||
eend
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
|
||||
urequire multiconf
|
||||
|
||||
PFF_ORIGEXT=pff
|
||||
PFF_CONF=.pff.conf # ne pas modifier
|
||||
DEFAULT_PFF_ORIGEXTS=(".$ORIGEXT" .origine .default)
|
||||
DEFAULT_PFF_PROTECTS=(/.git/ .svn/ /pff/ "/$PFF_CONF")
|
||||
|
||||
PFF_CONFVARS=(
|
||||
"VERSION//Version actuellement installée"
|
||||
-a
|
||||
"PVERSIONS//Versions en attente d'intégration"
|
||||
"PROFILES//Profils définis"
|
||||
-s
|
||||
"DISTTYPE=auto//Type de distribution upstream: full ou patch"
|
||||
-a
|
||||
"ORIGEXTS=//Extensions origines"
|
||||
"PROTECTS=//Fichiers locaux à protéger lors de l'intégration e.g /dir/, /file, etc."
|
||||
"MKDIRS//Répertoires qui doivent toujours exister"
|
||||
"FILTERS//Filtres appliqués aux fichiers lors de l'intégration"
|
||||
"NOMERGES=//Fichiers qu'il ne faut pas chercher à fusionner"
|
||||
)
|
||||
|
||||
# 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 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 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/$PFF_CONF" -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 "${PFF_CONFVARS[@]}"
|
||||
source "$pffdir/$PFF_CONF"
|
||||
local "$destvar"; upvar "$destvar" "$pffdir"
|
||||
return
|
||||
fi
|
||||
local msg="Projet pff introuvable (utiliser --init ?)"
|
||||
[ -n "$2" ] && die "$2: $msg" || die "$msg"
|
||||
}
|
||||
|
||||
function pff_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 pff_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 pff_get_user_profiles() {
|
||||
# afficher tous les profils modifiables du projet pff $1 (c'est à dire tous
|
||||
# les profils valides excepté Base)
|
||||
pff_get_profiles "$@" | grep -vxF Base
|
||||
}
|
||||
|
||||
function pff_get_first_profile() {
|
||||
# afficher le premier profil autre que Base du projet pff $1
|
||||
local profile
|
||||
profile="${PROFILES[0]}"
|
||||
if [ -z "$profile" -o "$profile" == Base ]; then
|
||||
pff_get_user_profiles "$@" | head -n1
|
||||
else
|
||||
echo "$profile"
|
||||
fi
|
||||
}
|
||||
|
||||
function pff_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 pff_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 pff_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 pff_get_bfile() { pff_get_pfile "$1" Base "$2"; }
|
||||
function pff_get_Cfile() { pff_get_pfile "$1" Common "$2"; }
|
||||
function pff_get_cfile() { pff_get_pfile "$1" Current "$2"; }
|
||||
|
||||
function pff_get_vlfiles_nostrip() {
|
||||
# afficher tous les fichiers de version
|
||||
local pffdir="$1" rfile="$2" profile="${3:-Base}" version="$4"
|
||||
[ -d "$pffdir/pff/$profile" ] || return
|
||||
if [ -n "$version" ]; then
|
||||
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}__"
|
||||
else
|
||||
find "$pffdir/pff/$profile" \
|
||||
-type f -name "*__pv-${version}__" -o \
|
||||
-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-*__"
|
||||
else
|
||||
find "$pffdir/pff/$profile" \
|
||||
-type f -name "*__pv-*__" -o \
|
||||
-type l -name "*__pv-*__"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
function pff_get_vlfiles() {
|
||||
local pffdir="$1" rfile="$2" profile="${3:-Base}" version="$4"
|
||||
pff_get_vlfiles_nostrip "$@" | sed "s|^$pffdir/pff/$profile/||"
|
||||
}
|
||||
|
||||
function pff_is_nomerge() {
|
||||
local file="$1" pffdir="$2"
|
||||
local nomerge rfile
|
||||
setx rfile=pff_get_rfile "$file" "$pffdir"
|
||||
setx file=basename -- "$rfile" # utilisé pour le match sur le nom du fichier
|
||||
for nomerge in "${NOMERGES[@]}"; do
|
||||
if [[ "$nomerge" == */* ]]; then
|
||||
# matcher sur le chemin relatif
|
||||
if eval "[[ $(qval "$rfile") == $(qwc "$nomerge") ]]"; then
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
# matcher uniquement sur le nom du fichier
|
||||
if eval "[[ $(qval "$file") == $(qwc "$nomerge") ]]"; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function pff_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 "$(pff_get_user_profiles "$pffdir")"
|
||||
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 pff_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=pff_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 pff_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 mkdir
|
||||
[ -d "$pffdir/pff/Current" ] || mkdir -p "$pffdir/pff/Current"
|
||||
[ -d "$pffdir/pff/Base" ] || mkdir -p "$pffdir/pff/Base"
|
||||
# tous les fichiers du profil Base doivent être en lecture seule
|
||||
find "$pffdir/pff/Base" -type f -perm /222 -exec chmod a-w '{}' +
|
||||
# Créer les répertoires de MKDIRS
|
||||
for mkdir in "${MKDIRS[@]}"; do
|
||||
mkdir -p "$pffdir/$mkdir"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
function pff_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=pff_get_first_profile "$pffdir"
|
||||
[ -n "$profile" ] || profile=Base
|
||||
enote "Autosélection du profil $profile"
|
||||
pff_select_profile "$profile" "$pffdir"
|
||||
fi
|
||||
}
|
||||
|
||||
function pff_autofix() {
|
||||
pff_autoinit "$1"
|
||||
pff_autoselect "$1"
|
||||
}
|
Loading…
Reference in New Issue