nutools/udist

1804 lines
61 KiB
Plaintext
Raw Normal View History

2013-08-27 15:14:44 +04:00
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
function display_help() {
uecho "$scriptname: gestion d'une distribution upstream
Des fichiers de configuration (par exemple) sont distribués par un partenaire,
et il faut maintenir des modifications locales, tout en acceptant les mises à
jour provenant 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' ou 'file.default'
La liste des extensions reconnues est spécifiée avec l'option -s. Lors de leur
intégration dans le répertoire local, ces fichiers sont copiés sans cette
extension.
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'.
USAGE
$scriptname cmd [options]
OPTIONS COMMUNES
-s .EXT
Ajouter une extension à la liste des extensions reconnues comme contenu
original modifiable dans la distribution upstream. Par défaut, les
extensions suivantes sont reconnues:
${DEFAULT_ORIGEXTS[*]}
Cette option peut être utilisée autant de fois que nécessaire.
--clear-origexts
Supprimer la liste par défaut des extensions origines. Cette option doit
être spécifiée avant l'option -s 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)
-d WORKDIR
Spécifier le répertoire de travail. Par défaut, la racine du répertoire
de travail est cherchée à partir du répertoire courant.
--help
Afficher l'aide détaillée de la commande spécifiée
COMMANDES
init [WORKDIR [ARCHIVE]]
Initialiser un répertoire de travail pour contenir une distribution
upstream
upstream-new, new SRCDIR|ARCHIVE [WORKDIR]
Intégrer une nouvelle distribution upstream.
Les nouveaux fichiers sont copiés tout de suite dans le répertoire de
travail. Par contre, les modifications ne sont intégrées qu'avec la
commande patch
upstream-clear, clear [WORKDIR]
Supprimer tous les fichiers non modifiés de l'upstream.
local-create, create FILE
Créer et/ou identifier FILE comme une modification locale par rapport à
l'upstream.
local-edit, edit FILE
S'assurer que local-create a été exécuté si nécessaire pour FILE, puis
l'éditer avec $EDITOR
local-copy, cp SRCFILE DESTFILE
local-move, mv SRCFILE DESTFILE
local-remove, rm FILE
Frontend pour respectivement cp, mv et rm. Ces commandes agissent aussi
sur les fichiers orig et de tag.
local-tag, tag FILE TAG
Faire une copie du fichier local avec le tag spécifié. Si le fichier de
tag existe déjà, il est écrasé.
local-switch, switch TAG FILE
Sélectionner la copie avec le tag spécifié.
local-put, put [WORKDIR] DESTDIR
Copier tous les fichiers locaux dans DESTDIR, par exemple pour faire une
sauvegarde. Si DESTDIR n'est pas spécifié, prendre la valeur de
l'origine, affichée par local-list
local-get, get [-l|-s] SRCDIR [WORKDIR]
Opération inverse de local-put: intégrer tous les fichiers de SRCDIR
comme fichiers locaux. Si SRCDIR n'est pas spécifié, prendre la valeur
de l'origine, affichée par local-list
local-list, list [WORKDIR]
Lister tous les fichiers locaux. Les fichiers pour lesquels il faut
intégrer une modification de l'upstream avec la commande local-patch
sont identifiés visuellement.
upstream-diff, udiff [FILE]
Après intégration d'une nouvelle distribution upstream, afficher les
modifications entre la nouvelle distribution upstream et l'ancienne pour
tous les fichiers modifiables
local-diff, ldiff [FILE]
Afficher les modifications locales par rapport à l'upstream pour le(s)
fichier(s) spécifié(s).
local-patch, lpatch [FILE]
Après intégration d'une nouvelle distribution upstream, appliquer au(x)
le(s) fichier(s) spécifié(s) les modifications disponibles affichées par
upstream-diff.
local-forget, lforget [FILE]
Après intégration d'une nouvelle distribution upstream, oublier les
modifications disponibles pour le(s) fichier(s) spécifié(s)."
}
SCRIPT_ALIASES=(#alias:command
udn:upstream-new
udc:local-create
ude:local-edit
uds:local-switch
udl:local-list
udd:local-diff
udp:local-patch
)
CMD_ALIASES=(
unew:upstream-new new:upstream-new
uclear:upstream-clear clear:upstream-clear
udiff:upstream-diff
lc:local-create lcreate:local-create c:local-create create:local-create
le:local-edit ledit:local-edit e:local-edit edit:local-edit
cp:local-copy copy:local-copy
mv:local-move move:local-move
rm:local-remove remove:local-remove delete:local-remove del:local-remove
lt:local-tag ltag:local-tag t:local-tag tag:local-tag
lswitch:local-switch s:local-switch sw:local-switch switch:local-switch
lput:local-put put:local-put push:local-put
lget:local-get get:local-get pull:local-get
link:"local-get -l" ln:"local-get -l"
ll:local-list llist:local-list list:local-list ls:local-list l:local-list
ldiff:local-diff diff:local-diff
lpatch:local-patch patch:local-patch
lforget:local-forget forget:local-forget
)
DEFAULT_CMD=local-list
ORIGEXT=udist
DEFAULT_ORIGEXTS=(".$ORIGEXT" .origine .default)
ORIGEXTS=("${DEFAULT_ORIGEXTS[@]}")
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
fi
source "$(dirname -- "$0")/lib/ulib/auto" || exit 1
urequire conf install
2013-08-27 15:14:44 +04:00
INSTALL_VERBOSE=
INSTALL_USES_PPATH=1
# Traduire le nom du script
for script_alias in "${SCRIPT_ALIASES[@]}"; do
splitpair "$script_alias" src dest
if [ "$scriptname" == "$src" ]; then
eval "set -- $dest \"\$@\""
scriptname=udist
break
fi
done
[ -n "$EDITOR" ] || EDITOR=vi
UDISTOPTS=(
-s:,--ext:,--origext: '$add@ ORIGEXTS'
--clear-origexts '$ORIGEXTS=()'
-d:,--workdir: workdir=
)
# Terminologie utilisée dans le code:
# - un fichier default est un fichier de la distribution upstream ayant une des
# extensions du tableau ORIGEXTS, ce qui en fait un candidat automatique pour
# avoir une copie locale. Les fichiers default sont de la forme 'NAME.origext'
# - un fichier local est un fichier auquel est associé un fichier orig. Les
# fichier locaux sont de la forme 'NAME'. En général, un fichier local a un
# fichier default correspondant dans la distribution upstream.
# - un fichier orig est la copie originale d'un fichier de la distribution
# upstream. Ce fichier est associé à un fichier local qui contient ses
# modifications locales. Les fichiers orig sont versionnés tant qu'ils ne sont
# pas intégrés et sont de la forme '.--NAME--[version].udist'
# - un fichier de tag est un fichier associé à un fichier local et qui a un tag
# associé. Ceci permet de maintenir plusieurs "versions" d'un même fichier
# local, e.g. "dev", "prod", etc.
function udist_local() {
utools_local
echo "local workdir"
}
function __check_workdir() {
[ -f "$1/.udist" ]
}
function find_workdir() {
local workdir="$(abspath "${1:-.}")"
while [ "$workdir" != "/" ]; do
if __check_workdir "$workdir"; then
echo "$workdir"
return 0
fi
workdir="$(dirname "$workdir")"
done
return 1
}
function __after_parse() {
array_fix_paths ORIGEXTS
[ -n "${ORIGEXTS[*]}" ] || ORIGEXTS=(".$ORIGEXT")
if [ "$1" != "initial" ]; then
[ -z "$workdir" -o -d "$workdir" ] || die "$workdir: répertoire introuvable"
workdir="$(find_workdir "$workdir")" || die "Impossible de trouver le répertoire de travail. Faut-il faire '$scriptname init'?"
workdir="$(abspath "$workdir")"
fi
}
function __udist_initial() {
echo "# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
VERSION=
VERSIONS=()
TAGS=()
ORIGIN=
LOCALS=()"
}
function __udist_locals() {
# afficher les variables définies dans le fichier .udist
echo "local VERSION ORIGIN; local -a VERSIONS TAGS LOCALS"
}
function __load_udist_nolocal() { (
# charger le fichier .udist ($1) et affiche les commandes pour définir les
# variables PVERSION, PVERSIONS, PTAGS, PORIGIN, PLOCALS.
# P ($2) est un préfixe éventuel pour le nom des variables
VERSION=; VERSIONS=(); TAGS=(); ORIGIN=; LOCALS=()
local udistf="${1:-$workdir}"
[ -d "$udistf" ] && udistf="$udistf/.udist"
source "$udistf"
echo_setv "${2}VERSION" "$VERSION"
2013-08-27 15:14:44 +04:00
set_array_cmd "${2}VERSIONS" VERSIONS
set_array_cmd "${2}TAGS" TAGS
echo_setv "${2}ORIGIN" "$ORIGIN"
2013-08-27 15:14:44 +04:00
set_array_cmd "${2}LOCALS" LOCALS
); }
function __load_udist() {
__udist_locals
__load_udist_nolocal "$@"
}
function __save_udist() {
# écrire dans le fichier .udist ($1) les variables spécifiées, parmi
# VERSION, VERSIONS, TAGS, ORIGIN, LOCALS. Les arguments sont de la forme
# DEST[:varname], e.g.
# __save_udist .udist VERSION:value ORIGIN
# qui met à jour VERSION avec $value et ORIGIN avec $ORIGIN
local __su_udistf="${1:-$workdir}"; shift
[ -d "$__su_udistf" ] && __su_udistf="$__su_udistf/.udist"
local __su_part __su_dest __su_varname
local -a __su_cmd
__su_cmd=(conf_enable "$__su_udistf")
for __su_dest in "$@"; do
splitpair "$__su_dest" __su_dest __su_varname
[ -n "$__su_varname" ] || __su_varname="$__su_dest"
case "$__su_dest" in
VERSION) array_add __su_cmd "$(echo_setv VERSION "${!__su_varname}")";;
2013-08-27 15:14:44 +04:00
VERSIONS) array_add __su_cmd "$(set_array_cmd VERSIONS "${__su_varname}")";;
TAGS) array_add __su_cmd "$(set_array_cmd TAGS "${__su_varname}")";;
ORIGIN) array_add __su_cmd "$(echo_setv ORIGIN "${!__su_varname}")";;
2013-08-27 15:14:44 +04:00
LOCALS) array_add __su_cmd "$(set_array_cmd LOCALS "${__su_varname}")";;
esac
done
"${__su_cmd[@]}"
}
function __is_default() {
# tester si $1 est un fichier de la forme name.origext
local origext ufile lfile
for origext in "${ORIGEXTS[@]}"; do
ufile="$1"
lfile="${ufile%$origext}"
[ "$ufile" != "$lfile" ] && return 0
done
return 1
}
function __get_local() {
# tester si $1 est un fichier de la form 'NAME.origext'. Dans ce cas,
# afficher 'NAME'. Sinon, afficher la valeur inchangée.
# note: cette fonction fait la même chose que __is_default, sauf qu'elle
# affiche le nom local correspondant au nom upstream
local origext ufile lfile
for origext in "${ORIGEXTS[@]}"; do
ufile="$1"
lfile="${ufile%$origext}"
[ "$ufile" != "$lfile" ] && {
echo "$lfile"
return 0
}
done
echo "$1"
return 1
}
function __get_orig() {
# obtenir le fichier orig correspondant à $1, i.e. afficher .--NAME--.udist
# pour $1==NAME
local dir="$(dirname "$1")" name="$(basename "$1")"
echo "$dir/.--$name--.$ORIGEXT"
}
function __list_localfiles() {
# lister les fichiers origs du répertoire $1 et en dériver une liste triée
# de *noms* de fichiers locaux
cd "$1"; find -name ".--*--*.$ORIGEXT" | filter_vcspath | while read path; do
dir="$(dirname "$path")"
file="$(basename "$path")"
file="${file#.--}"
file="${file%--*.$ORIGEXT}"
path="$dir/$file"
path="${path#./}"
echo "$path"
done | csort -u
}
function __list_tagfiles() {
# lister les *noms* des fichiers de tag correspondant au fichier local $1
local dir="$(dirname "$1")" name="$(basename "$1")"
list_all "$dir" "$name.%*"
}
function __list_origfiles() {
# afficher les *noms* des fichiers origs correspondant au fichier local $1
local dir="$(dirname "$1")" name="$(basename "$1")"
list_all "$dir" ".--$name--*.$ORIGEXT"
}
function __get_version() {
# afficher la version correspondant au fichier orig $1
local version="$(basename "$1")"
version="${version##*--}"
version="${version%.$ORIGEXT}"
echo "$version"
}
function __norm_ctag() {
# normaliser le tag composite $1: les doublons sont supprimés, et les tags
# sont triés
local -a tags
array_split tags "$1" %
array_from_lines tags "$(array_to_lines tags | csort -u)"
array_join tags %
}
function __get_ctag() {
# afficher le tag composite normalisé du fichier de tag $1. chaque tag est
# séparé par %
local tags="$(basename "$1")"
tags="${tags##*.%}"
tags="${tags%\%}"
__norm_ctag "$tags"
}
function __init_tags() {
# initialiser le tableau $1(=tags) avec la liste des tags du fichier de tag $2
array_split "${1:-tags}" "$(__get_ctag "$2")" %
}
function __get_tagfile() {
# afficher le nom du fichier de tag correspondant au fichier local $1 et au
# tag $2 (qui doit avoir été normalisé). $3(=tagfiles) est le cas échéant le
# nom du tableau contenant la liste des fichiers de tags.
local localfile="$1" ctag="$2"
local localdir="$(dirname "$localfile")"
if [ -n "$3" -a "$3" != "tagfiles" ]; then
local -a tagfiles
array_copy tagfiles "$3"
fi
for tagfile in "${tagfiles[@]}"; do
curtag="$(__get_ctag "$tagfile")"
if [ "$curtag" == "$ctag" ]; then
echo "$tagfile"
return 0
fi
done
return 1
}
function __get_curtagfile() {
# afficher le nom du fichier de tag *courant* correspondant au fichier local
# $1. $2(=tagfiles) est le cas échéant le nom du tableau contenant la liste
# des fichiers de tags
local localfile="$1"
local localdir="$(dirname "$localfile")"
if [ -n "$3" -a "$3" != "tagfiles" ]; then
local -a tagfiles
array_copy tagfiles "$3"
fi
for tagfile in "${tagfiles[@]}"; do
if testsame "$localfile" "$localdir/$tagfile"; then
echo "$tagfile"
return 0
fi
done
return 1
}
function is_local() {
# tester si $1 est un fichier modifiable ayant une version originale dans
# l'upstream
local origext ufile lfile
# tester d'abord si c'est un fichier de l'upstream de la forme
# 'name.origext'
for origext in "${ORIGEXTS[@]}"; do
ufile="$1"
lfile="${ufile%$origext}"
if [ "$ufile" != "$lfile" -a -e "$lfile" ]; then
return 0
fi
done
# ensuite tester si c'est un fichier local de la forme 'name' tel que
# 'name.origext' existe
for origext in "${ORIGEXTS[@]}"; do
lfile="$1"
ufile="$lfile$origext"
if [ -e "$lfile" -a -e "$ufile" ]; then
return 0
fi
done
return 1
}
function get_upstream() {
# obtenir le fichier de l'upstream correspondant à $1
local origext ufile lfile
# tester d'abord si c'est un fichier de l'upstream de la forme
# 'name.origext'. Afficher alors 'name.origext'
for origext in "${ORIGEXTS[@]}"; do
ufile="$1"
lfile="${ufile%$origext}"
if [ "$ufile" != "$lfile" -a -e "$lfile" ]; then
echo "$ufile"
return 0
fi
done
# ensuite tester si c'est un fichier local de la forme 'name' tel que
# 'name.origext' existe. Afficher alors 'name.origext'
for origext in "${ORIGEXTS[@]}"; do
lfile="$1"
ufile="$lfile$origext"
if [ -e "$lfile" -a -e "$ufile" ]; then
echo "$ufile"
return 0
fi
done
# sinon afficher $1.origext
echo "$1${ORIGEXTS[0]}"
return 1
}
function get_local() {
# obtenir le fichier local modifiable correspondant à $1
local origext ufile lfile
# tester d'abord si c'est un fichier de l'upstream de la forme
# 'name.origext'. Afficher alors 'name'
for origext in "${ORIGEXTS[@]}"; do
ufile="$1"
lfile="${ufile%$origext}"
if [ "$ufile" != "$lfile" -a -e "$lfile" ]; then
echo "$lfile"
return 0
fi
done
# ensuite tester si c'est un fichier local de la forme 'name' tel que
# 'name.origext' existe. Afficher alors 'name'
for origext in "${ORIGEXTS[@]}"; do
lfile="$1"
ufile="$lfile$origext"
if [ -e "$lfile" -a -e "$ufile" ]; then
echo "$lfile"
return 0
fi
done
# sinon afficher $1 inchangé
echo "$1"
return 1
}
function page_maybe() {
if isatty; then
less -XF
else
cat
fi
}
################################################################################
# template à recopier et adapter pour chaque nouvelle opération
function template_help() {
2015-08-20 07:58:17 +04:00
uecho "$scriptname template:
2013-08-27 15:14:44 +04:00
USAGE
$scriptname template [options]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant."
}
function template_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with template_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
#[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
__after_parse
}
################################################################################
function init_help() {
uecho "$scriptname init: initialiser un répertoire de travail
USAGE
$scriptname init [WORKDIR [ARCHIVE|SRCDIR]]
$scriptname init -d WORKDIR [ARCHIVE|SRCDIR]"
}
function init_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with init_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
array_fix_paths ORIGEXTS
[ -n "$workdir" ] || { workdir="${1:-.}"; shift; }
workdir="$(abspath "$workdir")"
if [ ! -d "$workdir" ]; then
ewarn "$(ppath "$workdir"): ce répertoire n'existe pas"
ask_yesno "Voulez-vous le créer?" O || die
mkdir -p "$workdir" || die
fi
if [ -f "$workdir/.udist" ]; then
estepi "$(ppath "$workdir"): Ce répertoire est déjà initialisé pour udist"
else
touch "$workdir/.udist" || die
__udist_initial >"$workdir/.udist"
estepn "$(ppath "$workdir"): répertoire de travail initialisé avec succès"
fi
local archive="$1"; shift
if [ -n "$archive" ]; then
upstream_new_cmd -d "$workdir" "$archive"
fi
}
################################################################################
function __unew_copy() {
# copier les fichiers et répertoire de $1 dans $2 en identifiant les
# fichiers originaux modifiés avec la version $3
local srcdir="$1" destdir="$2" newversion="$3" osrcdir="$4" odestdir="$5"
local -a srcs; local srcname src destname desto destl
local s
array_lsall srcs "$srcdir" "*" ".*"
for src in "${srcs[@]}"; do
srcname="$(basename "$src")"
desto= # fichier orig
destl= # fichier local
if [ -f "$src" ]; then
####################################################################
# copie d'un fichier
if destname="$(__get_local "$srcname")"; then
# c'est un fichier default. stratégie: ne jamais écraser le
# fichier local & copier le fichier orig la première fois, ou
# s'il est différent
desto="$destdir/.--$destname--.$ORIGEXT"
destl="$destdir/$destname"
if [ ! -f "$desto" ]; then
mkdirof "$desto"
if [ -f "$desto" ]; then
if testdiff "$src" "$desto"; then
cat "$src" >"$desto"; edot $? "REPL ${src#$osrcdir/} --> ${desto#$odestdir/}"
fi
else
cp_a "$src" "$desto"; edot $? "NEW ${src#$osrcdir/} --> ${desto#$odestdir/}"
fi
[ -f "$destl" ] || {
cp_a "$src" "$destl"; edot $? "NEW ${src#$osrcdir/} --> ${destl#$odestdir/}"
}
continue
fi
# si on arrive ici, c'est qu'il y a déjà un fichier orig.
else
# ce n'est pas un fichier default. stratégie: n'écraser le
# fichier local que s'il n'existe pas de fichier orig
desto="$destdir/.--$destname--.$ORIGEXT"
destl="$destdir/$destname"
if [ ! -f "$desto" ]; then
mkdirof "$destl"
if [ -f "$destl" ]; then
if testdiff "$src" "$destl"; then
cat "$src" >"$destl"; edot $? "REPL ${src#$osrcdir/} --> ${destl#$odestdir/}"
fi
else
cp_a "$src" "$destl"; edot $? "NEW ${src#$osrcdir/} --> ${destl#$odestdir/}"
fi
continue
fi
# si on arrive ici, c'est qu'il y a maintenant un fichier
# upstream pour un fichier local créé manuellement avec
# local-create. Il faudra donc potentiellement intégrer des
# modifications.
fi
# ici, le fichier upstream est potentiellement différent du fichier
# orig déjà existant. il nous faut donc vérifier s'il y a eu
# modification avant de copier cette nouvelle version.
local -a versions; local destonv same version destov
array_copy versions VERSIONS
array_reverse versions
destonv="$destdir/.--$destname--$newversion.$ORIGEXT"
same=
for version in "${versions[@]}"; do
destov="$destdir/.--$destname--$version.$ORIGEXT"
[ -f "$destov" ] || continue
if testsame "$src" "$destov"; then
same=1
break
fi
done
[ -n "$same" ] && continue
testsame "$src" "$desto" && continue
# nouveau fichier différent. il faut le versionner
mkdirof "$destonv"
if [ -f "$destonv" ]; then
if testdiff "$src" "$destonv"; then
cat "$src" >"$destonv"; edot $? "REPL ${src#$osrcdir/} --> ${destonv#$odestdir/}"
fi
else
cp_a "$src" "$destonv"; edot $? "NEW ${src#$osrcdir/} --> ${destonv#$odestdir/}"
fi
elif [ -d "$src" ]; then
####################################################################
# copie d'un répertoire
destname="$(__get_local "$srcname")"
destl="$destdir/$destname"
if [ ! -d "$destl" ]; then
mkdir -p "$destl"; s=$?
edot $s "DIR ${destl#$odestdir/}"
[ $s == 0 ] || return 1
fi
__unew_copy "$src" "$destl" "$newversion" "$osrcdir" "$odestdir" || return 1
else
edotw 1 "$src: fichier ignoré"
fi
done
return 0
}
function upstream_new_help() {
uecho "$scriptname upstream-new: intégrer une nouvelle distribution upstream
USAGE
$scriptname upstream-new <SRCDIR|ARCHIVE> [WORKDIR]
Les nouveaux fichiers sont copiés tout de suite dans le répertoire de travail.
Par contre, les modifications ne sont intégrées qu'avec la commande local-patch.
Pour chacun des fichiers orig, si le fichier correspondant de la distribution
upstream n'a pas été modifié, alors ce fichier n'est pas intégré.
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
-V, --version VERSION
Spécifier la version de l'archive qui est intégrée. 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.
-O, --origin ORIGIN
Spécifier un répertoire origine qui contient soit la distribution non
modifiée, soit une autre environnement udist pour la même distribution.
Si la source est un répertoire et que l'origine n'est pas déjà spécifiée
dans la configuration, cette option est automatiquement activée.
--no-origin
Ne pas mettre à jour la valeur de l'origine
--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
2015-08-20 07:58:17 +04:00
Intégrer tel quel le contenu de l'archive.
2013-08-27 15:14:44 +04:00
--force
Forcer l'intégration de la nouvelle version, même si elle a déjà été
intégrée.
-n
Ne pas appeler '$scriptname local-patch' après l'intégration de la
nouvelle version"
}
function upstream_new_cmd() {
eval "$(udist_local)"
local version=
local origin=
local noorigin= unwrap=auto force= nopatch=
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with upstream_new_help' \
"${UDISTOPTS[@]}" \
-V:,--version: version= \
-O:,--origin: origin= \
--no-origin noorigin=1 \
--auto-unwrap unwrap=auto \
--no-unwrap unwrap= \
-e,--unwrap unwrap=1 \
-k skiploneroot= \
--force force=1 \
-n nopatch=1 \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -d "$2" ] && workdir="$(find_workdir "$2")"
__after_parse
eval "$(__load_udist)"
local srcdir archive
archive="$1"; shift
if [ -f "$archive" ]; then
is_archive "$archive" || die "$archive: doit être un fichier archive"
[ -n "$version" ] || version="$(get_archive_version "$archive")"
elif [ -d "$archive" ]; then
srcdir="$(abspath "$archive")"
archive=
if [ -z "$noorigin" -a -z "$ORIGIN" -a -z "$origin" ]; then
# exprimer l'origine relativement à workdir
origin="$(relpath "$srcdir" "$workdir")"
fi
else
die "$archive: fichier introuvable"
fi
2015-08-20 07:58:17 +04:00
2013-08-27 15:14:44 +04:00
read_value "Entrez un identifiant pour cette version" version "$version" || die
if [ -z "$force" ] && array_contains VERSIONS "$version"; then
die "Vous avez déjà intégré la version $version"
fi
if [ -n "$archive" ]; then
ac_set_tmpdir tmpd
ebegin "Extraction de $(ppath "$archive")"
extract_archive "$archive" "$tmpd" &
ewait $!
eend
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_version "$archive")}"
local filename="$(basename "$file")"
[ "$filename" == "$banv" -o "$filename" == "$ban" ] || unwrap=
fi
[ -n "$unwrap" -a -d "$file" ] && srcdir="$file"
fi
fi
fi
ebegin "Copie des fichiers"
__unew_copy "$srcdir" "$workdir" "$version" "$srcdir" "$workdir"
eend
estep "Maj de la configuration"
array_addu VERSIONS "$version"
__save_udist "" VERSION:version VERSIONS ${origin:+ORIGIN:origin}
local_list_cmd -d "$workdir" --no-list
[ -z "$nopatch" ] && local_patch_cmd -d "$workdir"
ac_cleanall
}
################################################################################
function upstream_clear_help() {
2015-08-20 07:58:17 +04:00
uecho "$scriptname upstream-clear:
2013-08-27 15:14:44 +04:00
USAGE
$scriptname upstream-clear [options] [WORKDIR]"
}
function upstream_clear_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with upstream_clear_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -d "$1" ] && workdir="$(find_workdir "$1")"
__after_parse
ewarn "upstream-clear: non implémenté"
}
################################################################################
function local_create_help() {
uecho "$scriptname local-create: créer un fichier local
USAGE
$scriptname local-create [options] [WORKDIR] <FILEs...>
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant.
-u, --update
Mettre à jour la liste des fichiers locaux après l'ajout. C'est l'option
par défaut.
-n, --no-update
Ne pas mettre à jour la liste des fichiers avec locaux après
l'ajout. Cette option ne devrait pas être utilisée sauf dans des cas
très spécifiques."
}
function local_create_cmd() {
eval "$(udist_local)"
local update=1
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_create_help' \
"${UDISTOPTS[@]}" \
-u,--update update=1 \
-n,--no-update update= \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$workdir" -a -d "$1" ]; then
workdir="$(find_workdir "$1")" && shift
[ -n "$workdir" ] && estepn "Sélection du répertoire de travail $(ppath "$workdir")"
else
[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
[ -z "$workdir" -a ! -e "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
fi
__after_parse
[ -n "$*" ] || die "Vous devez spécifier les fichiers locaux à créer"
if [ -n "$update" ]; then
eval "$(__load_udist)"
else
local -a LOCALS
fi
local file relfile
for file in "$@"; do
if withinpath "$workdir" "$file"; then
if [ ! -f "$file" ]; then
ask_yesno "$file: fichier introuvable. Voulez-vous le créer?" O || continue
touch "$file" || continue
fi
file="$(abspath "$file")"
relfile="$(relpath "$file" "$workdir")"
if [ -n "$(__list_origfiles "$file")" ]; then
estep "$relfile: nop"
else
array_addu LOCALS "$relfile"
ebegin "$relfile"
cp "$file" "$(__get_orig "$file")"
eend $?
fi
else
eerror "$file: ne se trouve pas dans $workdir"
fi
done
if [ -n "$update" ]; then
estep "Maj de la configuration"
__save_udist "" LOCALS
fi
}
################################################################################
function local_edit_help() {
uecho "$scriptname local-edit: editer un fichier local
USAGE
$scriptname local-edit [options] <FILEs...>
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_edit_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_edit_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
__after_parse
local_create_cmd -d "$workdir" -qy "$@"
"$EDITOR" "$@"
}
################################################################################
function local_copy_help() {
uecho "$scriptname local-copy: copier un fichier
USAGE
$scriptname local-copy [options] SRCFILE DESTFILE
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier SRCFILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_copy_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_copy_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
__after_parse
ewarn "local-copy: non implémenté"
}
################################################################################
function local_move_help() {
uecho "$scriptname local-move: déplacer un fichier
USAGE
$scriptname local-move [options] SRCFILE DESTFILE
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier SRCFILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_move_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_move_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
__after_parse
ewarn "local-move: non implémenté"
}
################################################################################
function local_remove_help() {
uecho "$scriptname local-remove: supprimer un fichier
USAGE
$scriptname local-remove [options] FILE
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_remove_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_remove_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
__after_parse
ewarn "local-remove: non implémenté"
}
################################################################################
function local_tag_help() {
uecho "$scriptname local-tag: gérer les fichiers de tag
USAGE
$scriptname local-tag [options] <FILE> <TAG[%TAG...]>
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_tag_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_tag_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -f "$1" ] && workdir="$(find_workdir "$(dirname "$1")")"
__after_parse
ewarn "local-tag: non implémenté"
}
################################################################################
function local_switch_help() {
uecho "$scriptname local_switch: changer le tag courant
USAGE
$scriptname local_switch [options] TOTAG [FILE]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant.
--from FROMTAG
Ne faire le changement que si le tag courant est FROMTAG. Si le tag est
composite, les tags doivent être séparés par %, e.g. tag1%tag2"
}
function local_switch_cmd() {
eval "$(udist_local)"
local fromctag
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_switch_help' \
"${UDISTOPTS[@]}" \
--from: fromctag= \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -d "$2" ] && workdir="$(find_workdir "$2")"
[ -z "$workdir" -a -f "$2" ] && workdir="$(find_workdir "$(dirname "$2")")"
__after_parse
local toctag="$1"; shift
[ -n "$toctag" ] || die "Vous devez spécifier le tag de destination"
fromctag="$(__norm_ctag "$fromctag")"
toctag="$(__norm_ctag "$toctag")"
[ -n "$*" ] || set -- "$workdir"
local -a localfiles tagfiles
local localfile localdir doswitch tagfile ctag oldtagfile oldctag
for localfile in "$@"; do
etitle "$localfile"
if ! withinpath "$workdir" "$localfile"; then
eerror "$localfile: ne se trouve pas dans $workdir"
continue
fi
if [ -d "$localfile" ]; then
# cas particulier, c'est un répertoire, il faut lister tous les
# fichiers locaux
local basedir="$localfile"
array_from_lines localfiles "$(__list_localfiles "$basedir")"
for localfile in "${localfiles[@]}"; do
localfile="$basedir/$localfile"
localdir="$(dirname "$localfile")"
doswitch=1
array_from_lines tagfiles "$(__list_tagfiles "$localfile")"
oldtagfile="$(__get_curtagfile "$localfile")"
oldctag=$(__get_ctag "$oldtagfile")
if [ -z "$oldtagfile" ]; then
doswitch=
if [ -n "${tagfiles[*]}" ]; then
eerror "$(ppath "$localfile"): Modifications locales sur le fichier. Veuillez utiliser local-tag pour corriger ce problème."
fi
elif [ "$oldctag" == "$toctag" ]; then
# le fichier a déjà le bon tag
doswitch=
elif [ -z "${tagfiles[*]}" ]; then
doswitch=
elif [ -n "$fromctag" ]; then
tagfile="$(__get_tagfile "$localfile" "$fromctag" tagfiles)"
if [ -z "$tagfile" ]; then
doswitch=
elif ! testsame "$localfile" "$localdir/$tagfile"; then
ctag="$(__get_ctag "$tagfile")"
ewarn "$(ppath "$localfile"): Fichier ignoré (tag courant $oldctag, attendu $fromctag)"
doswitch=
fi
fi
2015-08-20 07:58:17 +04:00
2013-08-27 15:14:44 +04:00
if [ -n "$doswitch" ]; then
tagfile="$(__get_tagfile "$localfile" "$toctag" tagfiles)"
if [ -n "$tagfile" ]; then
copy_update "$localdir/$tagfile" "$localfile" &&
estepn "$(ppath "$localfile"): $oldctag --> $toctag"
fi
fi
done
elif [ -f "$localfile" ]; then
# c'est un fichier
localdir="$(dirname "$localfile")"
doswitch=1
array_from_lines tagfiles "$(__list_tagfiles "$localfile")"
oldtagfile="$(__get_curtagfile "$localfile")"
oldctag=$(__get_ctag "$oldtagfile")
if [ -z "$oldtagfile" ]; then
doswitch=
if [ -n "${tagfiles[*]}" ]; then
eerror "Modifications locales sur le fichier. Veuillez utiliser local-tag pour corriger ce problème."
fi
elif [ "$oldctag" == "$toctag" ]; then
# le fichier a déjà le bon tag
doswitch=
elif [ -z "${tagfiles[*]}" ]; then
ewarn "Fichier ignoré (pas de tags)"
doswitch=
elif [ -n "$fromctag" ]; then
tagfile="$(__get_tagfile "$localfile" "$fromctag" tagfiles)"
if [ -z "$tagfile" ]; then
ewarn "Fichier ignoré (pas de tag $fromctag)"
doswitch=
elif ! testsame "$localfile" "$localdir/$tagfile"; then
ctag="$(__get_ctag "$tagfile")"
ewarn "Fichier ignoré (tag courant $oldctag, attendu $fromctag)"
doswitch=
fi
fi
if [ -n "$doswitch" ]; then
tagfile="$(__get_tagfile "$localfile" "$toctag" tagfiles)"
if [ -z "$tagfile" ]; then
ewarn "Fichier ignoré (pas de tag $toctag)"
else
copy_update "$localdir/$tagfile" "$localfile" &&
estepn "$oldctag --> $toctag"
fi
fi
2015-08-20 07:58:17 +04:00
2013-08-27 15:14:44 +04:00
else
eerror "$localfile: fichier introuvable"
fi
eend
done
}
################################################################################
function __lput_copyto() {
local destdir="$1"
for localfile in "${localfiles[@]}"; do
copy_update "$workdir/$localfile" "$destdir/$localfile" &&
edot 0 "$(ppath "$destdir/$localfile")"
done
}
function local_put_help() {
uecho "$scriptname local-put: copier les fichiers locaux dans un répertoire distant
USAGE
$scriptname local-put [options] [WORKDIR] <[user@host:]destdir>
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
-u, --update
Mettre à jour d'abord la liste des fichiers locaux avec local-list.
-n, --no-update
Ne pas mettre à jour la liste des fichiers avec local-list. Utiliser
simplement le cache. C'est l'option par défaut
--copy-origs
Copier les fichiers orig en plus des fichiers locaux
--copy-tags
Copier les fichiers de tag en plus des fichiers locaux
-a, --all
Copier le fichier .udist et les fichiers orig et de tag en plus des
fichiers locaux
-S, --ssh SSH
Spécifier la commande ssh à utiliser pour la copie avec rsync.
-R, --rsync RSYNC
Spécifier la commande rsync à utiliser pour la copie.
-O, --owner OWNER
Spécifier le propriétaire des fichiers à l'arrivée. La modification se
fait en se connectant avec ssh."
}
function local_put_cmd() {
eval "$(udist_local)"
local update= copyorigs= copytags= copyall=
local ssh= rsync= owner=
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_put_help' \
"${UDISTOPTS[@]}" \
-u,--update update=1 \
-n,--no-update update= \
--copy-origs copyorigs=1 \
--copy-tags copytags=1 \
-a,--all,--copy-all copyall=1 \
-S:,--ssh: ssh= \
-R:,--rsync: rsync= \
-O:,--owner: owner= \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$workdir" -a $# -ge 2 -a -d "$1" ]; then
workdir="$(find_workdir "$1")" && shift
[ -n "$workdir" ] && estepn "Sélection du répertoire de travail $(ppath "$workdir")"
fi
__after_parse
local remote="$1"
if [ -z "$remote" ]; then
# Si la destination n'est pas spécifiée, prendre la valeur de ORIGIN
eval "$(__load_udist)"
remote="$ORIGIN"
[ -n "$remote" ] && enote "Sélection automatique de la destination $remote"
fi
[ -n "$remote" ] || die "Vous devez spécifier la destination"
local userhost destdir
if [[ "$remote" == *:* ]]; then
# remote est de la forme userhost:destdir
splitfsep "$remote" : userhost destdir
else
# remote est de la forme destdir
userhost=
destdir="$remote"
[ -d "$destdir" ] || die "$destdir: répertoire introuvable"
fi
[ -n "$update" ] && local_list_cmd -d "$workdir" --no-list
eval "$(__load_udist)"
local -a localfiles; array_copy localfiles LOCALS
if [ -n "$copyorigs" -o -n "$copytags" -o -n "$copyall" ]; then
local -a origlocalfiles
local local localdir origfile tagfile
array_copy origlocalfiles localfiles
localfiles=()
[ -n "$copyall" ] && array_add localfiles .udist
for localfile in "${origlocalfiles[@]}"; do
array_add localfiles "$localfile"
localdir="$(dirname "$localfile")"
if [ -n "$copyorigs" -o -n "$copyall" ]; then
array_from_lines origfiles "$(__list_origfiles "$workdir/$localfile")"
for origfile in "${origfiles[@]}"; do
array_add localfiles "$localdir/$origfile"
done
fi
if [ -n "$copytags" -o -n "$copyall" ]; then
array_from_lines tagfiles "$(__list_tagfiles "$workdir/$localfile")"
for tagfile in "${tagfiles[@]}"; do
array_add localfiles "$localdir/$tagfile"
done
fi
done
fi
if [ -n "$userhost" ]; then
# copie distante
ac_set_tmpdir tmpdir
ebegin "Préparation de la copie"
__lput_copyto "$tmpdir"
eend
estep "Copie distante vers $userhost:$destdir"
local -a cmd
cmd=("${rsync:-rsync}")
[ -n "$ssh" ] && cmd=("${cmd[@]}" -e "$ssh")
"${cmd[@]}" -rv "$tmpdir/" "$userhost:$destdir"
if [ -n "$owner" ]; then
estep "Modification du propriétaire à $owner"
local script=
for localfile in "${localfiles[@]}"; do
[ -n "$script" ] && script="$script; "
script="$script$(qvals chown "$owner" "$destdir/$localfile")"
2013-08-27 15:14:44 +04:00
done
"${ssh:-ssh}" -qt "$userhost:$destdir" "$script"
fi
else
# copie locale
withinpath "$workdir" "$destdir" && die "Impossible de copier dans $(ppath "$destdir")"
ebegin "Copie des fichiers"
__lput_copyto "$destdir"
eend
if [ -n "$owner" ]; then
ebegin "Modification du propriétaire à $owner"
for localfile in "${localfiles[@]}"; do
chown "$owner" "$destdir/$localfile"; edot $? "$(ppath "$destdir/$localfile")"
done
eend
fi
fi
}
################################################################################
function local_get_help() {
uecho "$scriptname local-get: intégrer des fichiers d'un répertoire distant et en faire des fichiers locaux
USAGE
$scriptname local-get [options] <[user@host:]destdir> [WORKDIR]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
-l
Faire des liens physiques au lieu de simplement copier les fichiers
-s
Faire des liens symboliques au lieu de liens physiques
-S, --ssh SSH
Spécifier la commande ssh à utiliser pour la copie avec rsync.
-R, --rsync RSYNC
Spécifier la commande rsync à utiliser pour la copie."
}
function local_get_cmd() {
eval "$(udist_local)"
local link= symbolic=
local ssh= rsync=
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_get_help' \
"${UDISTOPTS[@]}" \
-l,--link link=1 \
-s,--symbolic '$link=1; symbolic=1' \
-S:,--ssh: ssh= \
-R:,--rsync: rsync= \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -d "$2" ] && workdir="$(find_workdir "$2")"
__after_parse
local remote="$1"
if [ -z "$remote" ]; then
# Si la destination n'est pas spécifiée, prendre la valeur de ORIGIN
eval "$(__load_udist)"
remote="$ORIGIN"
[ -n "$remote" ] && enote "Sélection automatique de la source $remote"
fi
[ -n "$remote" ] || die "Vous devez spécifier la source"
local userhost srcdir
if [[ "$remote" == *:* ]]; then
# remote est de la forme userhost:srcdir
splitfsep "$remote" : userhost srcdir
else
# remote est de la forme srcdir
userhost=
srcdir="$remote"
[ -d "$srcdir" ] || die "$srcdir: répertoire introuvable"
withinpath "$workdir" "$srcdir" && die "Impossible de copier depuis $(ppath "$srcdir")"
fi
if [ -n "$userhost" ]; then
if [ -n "$link" ]; then
ewarn "Impossible de faire des liens pour des fichiers distants"
link=
fi
# copie distante
etitle "Copie distante depuis $userhost:$srcdir"
ac_set_tmpdir tmpdir
local -a cmd
cmd=("${rsync:-rsync}")
[ -n "$ssh" ] && cmd=("${cmd[@]}" -e "$ssh")
"${cmd[@]}" -rv "$userhost:$srcdir/" "$tmpdir"
eend
srcdir="$tmpdir"
fi
etitle "Intégration des fichiers"
array_from_lines srcs "$(cd "$srcdir"; find -type f | filter_vcspath | sed 's/^.\///')"
for src in "${srcs[@]}"; do
mkdirof "$workdir/$src" || die
local_create_cmd -d "$workdir" -qy "$src"
if [ -n "$link" ]; then
[ -e "$workdir/$src" ] && rm "$workdir/$src"
ln ${symbolic:+-s} "$srcdir/$src" "$workdir/$src"
else
[ -L "$workdir/$src" ] && rm "$workdir/$src"
copy_update "$srcdir/$src" "$workdir/$src" &&
estep "$(ppath "$workdir/$src")"
fi
done
eend
}
################################################################################
function local_list_help() {
uecho "$scriptname local-list: lister les fichiers locaux
USAGE
$scriptname local-list [options] [WORKDIR]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
-n, --no-update
Ne pas mettre à jour la liste des fichiers. Utiliser simplement le
cache. Implique l'option --no-cache
--no-list
Ne pas lister les fichiers. Faire simplement la mise à jour du cache.
--no-cache
Ne pas mettre à jour le cache des fichiers locaux. Normalement, toutes
les autres commandes utilisent les informations du cache."
}
function local_list_cmd() {
eval "$(udist_local)"
local update=1
local list=1
local cache=1
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_list_help' \
"${UDISTOPTS[@]}" \
-u,--update update=1 \
-n,--no-update '$update=; cache=' \
-l,--list list=1 \
--no-list list= \
-c,--cache cache=1 \
--no-cache cache= \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
[ -z "$workdir" -a -d "$1" ] && workdir="$(find_workdir "$1")"
__after_parse
eval "$(__load_udist)"
local -a localfiles tags tagfiles localtags
local tagfile localtag
if [ -n "$update" ]; then
array_from_lines localfiles "$(__list_localfiles "$workdir")"
for localfile in "${localfiles[@]}"; do
array_from_lines tagfiles "$(__list_tagfiles "$workdir/$localfile")"
for tagfile in "${tagfiles[@]}"; do
__init_tags localtags "$tagfile"
array_extendu tags localtags
done
done
array_from_lines tags "$(array_to_lines tags | csort -u)"
else
array_copy localfiles LOCALS
array_copy tags TAGS
fi
if [ -n "$cache" ]; then
__save_udist "" LOCALS:localfiles TAGS:tags
fi
if [ -n "$list" ]; then
[ -n "$ORIGIN" ] && echo "# origin: $(relpath "$ORIGIN" "" "$workdir")"
echo "# version: $VERSION"
local -a versions tagfiles; local localdir
for localfile in "${localfiles[@]}"; do
localfile="$workdir/$localfile"
localdir="$(dirname "$localfile")"
line="$(relpath "$localfile")"
if [ ! -f "$localfile" ]; then
line="$line ${COULEUR_ROUGE}!${COULEUR_NORMALE}"
fi
array_from_lines versions "$(__list_origfiles "$localfile")"
array_map versions __get_version
array_del versions "$version"
if [ -n "${versions[*]}" ]; then
line="$line ${COULEUR_JAUNE}pending${COULEUR_NORMALE}($(array_join versions ", "))"
fi
array_from_lines tagfiles "$(__list_tagfiles "$localfile")"
if [ -n "${tagfiles[*]}" ]; then
local tmpline= first=1 foundcur=
for tagfile in "${tagfiles[@]}"; do
if [ -n "$first" ]; then first=; else tmpline="$tmpline, "; fi
if testsame "$localfile" "$localdir/$tagfile"; then
tmpline="$tmpline${COULEUR_BLEUE}$(__get_ctag "$tagfile")${COULEUR_NORMALE}"
foundcur=1
else
tmpline="$tmpline$(__get_ctag "$tagfile")"
fi
done
if [ -n "$foundcur" ]; then
line="$line tags($tmpline)"
else
line="$line ${COULEUR_ROUGE}tags${COULEUR_NORMALE}($tmpline)"
fi
fi
2015-08-20 07:58:17 +04:00
2013-08-27 15:14:44 +04:00
echo "$line"
done
fi
}
################################################################################
function upstream_diff_help() {
2015-08-20 07:58:17 +04:00
uecho "$scriptname upstream-diff:
2013-08-27 15:14:44 +04:00
USAGE
$scriptname upstream-diff [options] WORKDIR
$scriptname upstream-diff [options] [FILEs...]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function upstream_diff_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with upstream_diff_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$workdir" -a -d "$1" ]; then
workdir="$(find_workdir "$1")" && shift
elif [ -z "$workdir" -a -f "$1" ]; then
workdir="$(find_workdir "$(dirname "$1")")"
fi
__after_parse
ewarn "upstream-diff: non implémenté"
}
################################################################################
function local_diff_help() {
2015-08-20 07:58:17 +04:00
uecho "$scriptname local-diff:
2013-08-27 15:14:44 +04:00
USAGE
$scriptname local-diff [options] WORKDIR
$scriptname local-diff [options] [FILEs...]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_diff_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_diff_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$workdir" -a -d "$1" ]; then
workdir="$(find_workdir "$1")" && shift
elif [ -z "$workdir" -a -f "$1" ]; then
workdir="$(find_workdir "$(dirname "$1")")"
fi
__after_parse
ewarn "local-diff: non implémenté"
}
################################################################################
function local_patch_help() {
2015-08-20 07:58:17 +04:00
uecho "$scriptname local-patch:
2013-08-27 15:14:44 +04:00
USAGE
$scriptname local-patch [options] WORKDIR
$scriptname local-patch [options] [FILEs...]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_patch_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_patch_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$workdir" -a -d "$1" ]; then
workdir="$(find_workdir "$1")" && shift
elif [ -z "$workdir" -a -f "$1" ]; then
workdir="$(find_workdir "$(dirname "$1")")"
fi
__after_parse
ewarn "local-patch: non implémenté"
}
################################################################################
function local_forget_help() {
2015-08-20 07:58:17 +04:00
uecho "$scriptname local-forget:
2013-08-27 15:14:44 +04:00
USAGE
$scriptname local-forget [options] WORKDIR
$scriptname local-forget [options] [FILEs...]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
Si cette option n'est pas spécifiée et que le fichier FILE existe, le
calcul est effectué à partir de son répertoire au lieu du répertoire
courant."
}
function local_forget_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with local_forget_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -z "$workdir" -a -d "$1" ]; then
workdir="$(find_workdir "$1")" && shift
elif [ -z "$workdir" -a -f "$1" ]; then
workdir="$(find_workdir "$(dirname "$1")")"
fi
__after_parse
ewarn "local-forget: non implémenté"
}
################################################################################
# XXX à migrer puis supprimer
function diff_help() {
uecho "$scriptname diff: afficher les différences entre les versions
USAGE
$scriptname diff [options]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant.
-o
Afficher les différences entre la version originale actuelle et la
version précédente (par défaut). Ces différences peuvent être intégrées
dans le répertoire de travail avec la commande '$scriptname patch'
-c
Afficher les différences entre la copie de travail et la version
originale."
}
function diff_cmd() {
eval "$(udist_local)"
local mode=orig
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with diff_help' \
"${UDISTOPTS[@]}" \
-o,--orig mode=orig \
-c,--work mode=work \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
__after_parse
local cwd="$(pwd)"
cd "$workdir"
if [ "$mode" == "orig" ]; then
if [ -d ".__prev" -a -d ".__orig" ]; then
cdiff -urN .__prev .__orig | page_maybe
else
einfo "Pas de version précédente à comparer"
fi
elif [ "$mode" == "work" ]; then
if [ -d ".__orig" ]; then
cdiff -urN -x .svn -x .git -x .__prev -x .__orig -x .udist .__orig . | page_maybe
else
einfo "Pas de version originale à comparer"
fi
fi
cd "$cwd"
}
################################################################################
# XXX à migrer puis supprimer
function patch_help() {
uecho "$scriptname patch: intégrer les modifications dans le répertoire de travail
USAGE
$scriptname patch [options]
OPTIONS
-d WORKDIR
Spécifier le répertoire de travail au lieu du répertoire courant."
}
function patch_cmd() {
eval "$(udist_local)"
parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with patch_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
__after_parse
local patch
ac_set_tmpfile patch
diff_cmd -qo >"$patch"
if [ -s "$patch" ]; then
page_maybe <"$patch"
ask_yesno "Voulez-vous appliquer ces modifications à la copie de travail?" X || die
local cwd="$(pwd)"
cd "$workdir"
patch -p1 <"$patch" || die
rm -rf ".__prev" || die
cd "$cwd"
else
einfo "Pas de modifications à intégrer"
fi
}
################################################################################
workdir=
parse_opts + "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \
"${UDISTOPTS[@]}" \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
__after_parse initial
# Traduire la commande
[ -n "$*" ] || set -- "$DEFAULT_CMD"
cmd=
found_cmd=
while [ -z "$found_cmd" ]; do
cmd="$1"; shift; found_cmd=1
[ -n "$cmd" ] || break
for cmd_alias in "${CMD_ALIASES[@]}"; do
splitpair "$cmd_alias" src dest
if [ "$cmd" == "$src" ]; then
eval "set -- $dest \"\$@\""
found_cmd=
break
fi
done
done
case "$cmd" in
"") exit_with display_help;;
init) init_cmd "$@";;
upstream-new) upstream_new_cmd "$@";;
upstream-clear) upstream_clear_cmd "$@";;
local-create) local_create_cmd "$@";;
local-edit) local_edit_cmd "$@";;
local-copy) local_copy_cmd "$@";;
local-move) local_move_cmd "$@";;
local-remove) local_remove_cmd "$@";;
local-tag) local_tag_cmd "$@";;
local-switch) local_switch_cmd "$@";;
local-put) local_put_cmd "$@";;
local-get) local_get_cmd "$@";;
local-list) local_list_cmd "$@";;
upstream-diff) upstream_diff_cmd "$@";;
local-diff) local_diff_cmd "$@";;
local-patch) local_patch_cmd "$@";;
local-forget) local_forget_cmd "$@";;
*) die "$cmd: commande incorrecte";;
esac