1805 lines
		
	
	
		
			61 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1805 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")/ulib/ulib &&
 | |
| urequire DEFAULTS conf install ||
 | |
| exit 1
 | |
| 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
 |