1804 lines
		
	
	
		
			61 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1804 lines
		
	
	
		
			61 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/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/ulib" || exit 1
 | 
						|
urequire DEFAULTS conf install
 | 
						|
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"
 | 
						|
 | 
						|
    set_var_cmd "${2}VERSION" "$VERSION"
 | 
						|
    set_array_cmd "${2}VERSIONS" VERSIONS
 | 
						|
    set_array_cmd "${2}TAGS" TAGS
 | 
						|
    set_var_cmd "${2}ORIGIN" "$ORIGIN"
 | 
						|
    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 "$(set_var_cmd VERSION "${!__su_varname}")";;
 | 
						|
        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 "$(set_var_cmd ORIGIN "${!__su_varname}")";;
 | 
						|
        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() {
 | 
						|
    uecho "$scriptname template: 
 | 
						|
 | 
						|
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
 | 
						|
        Intégrer tel quel le contenu de l'archive. 
 | 
						|
    --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
 | 
						|
    
 | 
						|
    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() {
 | 
						|
    uecho "$scriptname upstream-clear: 
 | 
						|
 | 
						|
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
 | 
						|
                
 | 
						|
                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
 | 
						|
            
 | 
						|
        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$(quoted_args chown "$owner" "$destdir/$localfile")"
 | 
						|
            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
 | 
						|
            
 | 
						|
            echo "$line"
 | 
						|
        done
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
################################################################################
 | 
						|
 | 
						|
function upstream_diff_help() {
 | 
						|
    uecho "$scriptname upstream-diff: 
 | 
						|
 | 
						|
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() {
 | 
						|
    uecho "$scriptname local-diff: 
 | 
						|
 | 
						|
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() {
 | 
						|
    uecho "$scriptname local-patch: 
 | 
						|
 | 
						|
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() {
 | 
						|
    uecho "$scriptname local-forget: 
 | 
						|
 | 
						|
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
 |