358 lines
11 KiB
Bash
Executable File
358 lines
11 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: Outil pour gérer des projets
|
|
|
|
USAGE
|
|
$scriptname cmd [args]
|
|
|
|
COMMANDS
|
|
getvcs [dir]
|
|
Afficher le type de VCS pour dir.
|
|
getroot [dir]
|
|
Si dir est un répertoire versionné, retourner le répertoire racine du
|
|
projet versionné.
|
|
getrepos [dir]
|
|
Si dir est un répertoire versionné, retourner l'url du repository du
|
|
projet versionné.
|
|
geturl [dir]
|
|
Si dir est un répertoire versionné, retourner son url dans le
|
|
repository.
|
|
fold [dir]
|
|
unfold [dir]
|
|
Utiliser uinc pour défaire (resp. refaire) toutes les inclusions des
|
|
fichiers de dir. Cela nécessite qu'un fichier .udir soit configuré à la
|
|
racine du projet avec uinc=true
|
|
vcs [args]
|
|
Appeler le gestionnaire de gestion approprié avec les arguments donnés.
|
|
add files...
|
|
Ajouter les fichiers files dans le gestionnaire de version.
|
|
remove files...
|
|
Supprimer les fichiers versionnés files.
|
|
copy from to
|
|
Copier le fichier versionné from vers le fichier to.
|
|
move from to
|
|
Renommer le fichier versionné from vers le fichier to.
|
|
mkdir dir
|
|
Créer un nouveau répertoire versionné.
|
|
commit message [files...]
|
|
Enregistrer les modifications (par défaut sur tous les fichiers
|
|
modifiés) avec le commentaire message.
|
|
status
|
|
Afficher l'état des fichiers versionnés et non versionnés.
|
|
update [-x]
|
|
Mettre à jour la copie locale avec la copie sur le serveur.
|
|
-x Ne pas mettre à jour les références externes (si appliquable)
|
|
-n, --no-autoff
|
|
Ne pas faire de fast-forward automatique pour toutes les branches
|
|
traquées. Par défaut, s'il n'y a pas de modifications locales,
|
|
essayer de fast-fowarder toutes les branches locales traquées.
|
|
diff [options]
|
|
Afficher les différences.
|
|
-l Afficher les différences non commitées (par défaut)
|
|
-c Afficher les différences en passe d'être commitées (si appliquable)
|
|
-r REV
|
|
Afficher les différences depuis la révision REV.
|
|
-R Afficher les modifications effectuées depuis la dernière release.
|
|
|
|
clone git@host:path/to/repo [destdir]
|
|
Cloner un dépôt distant. Initialiser git annex si le dépôt contient des
|
|
fichiers annexés. Récupérer aussi ces fichiers avec 'git annex get'
|
|
|
|
crone git@host:path/to/repo [destdir]
|
|
Créer un dépôt distant sur gitolite, puis le cloner
|
|
|
|
develop
|
|
release
|
|
hotfix
|
|
Démarrer le travail sur une branche respectivement de développement, de
|
|
release, ou de correction de bugs. Lancer chaque commande avec --help
|
|
pour les détails. Nécessite git.
|
|
|
|
archive
|
|
Créer une archive du projet courant. Nécessite git.
|
|
|
|
annex [args]
|
|
Lancer git annex avec les arguments spécifiés.
|
|
xadd
|
|
xunlock
|
|
xdrop
|
|
xwhereis
|
|
xwebapp
|
|
Chacune de ces commandes est un raccourci vers la commande
|
|
correspondante de git annex, sans le préfixe 'x'
|
|
xsync
|
|
Sur un dépot où git-annex est activé, lancer 'git annex sync' si on est
|
|
en mode indirect ou 'git annex sync --content' si on est en mode direct.
|
|
Sur un dépôt où git-annex n'est pas activé, faire l'équivalent des
|
|
commandes 'git add -A && git commit && git pull && git push'
|
|
xcopy
|
|
xmove
|
|
xget
|
|
Comme ci-dessus, mais si la commande s'exécute sans erreur, lancer
|
|
aussi 'git annex sync'
|
|
xinitial
|
|
Sur un dépôt fraichement cloné, initialiser le dépôt avec 'annex init'
|
|
s'il contient des fichiers annexés. Récupérer aussi ces fichiers avec
|
|
'annex get'
|
|
xconfig-export [dir]
|
|
Installer des hooks pour qu'un dépôt puisse être utilisé pour servir des
|
|
fichiers, par exemple avec un serveur web. Plus précisément, un hook
|
|
post-receive est créé avec la commande 'git annex merge', et un hook
|
|
post-update est créé avec la commande 'git update-server-info'
|
|
|
|
printml [-t TYPE]
|
|
Afficher le modeline pour un fichier du type spécifié
|
|
addml [-t TYPE] file
|
|
Ajouter un modele pour le fichier spécifié, s'il n'en a pas déjà un.
|
|
Si nécessaire, forcer le type du fichier au lieu de l'autodétecter
|
|
new [options] file [template options]
|
|
Créer un nouveau fichier à partir d'un modèle.
|
|
Avant le nom du fichier, les options suivantes sont valides:
|
|
-t TEMPLATE
|
|
Spécifier le modèle de fichier à utiliser. Par défaut, le modèle
|
|
à utiliser est déduit de l'extension ou du nom du fichier.
|
|
-e Editer le fichier après l'avoir créé.
|
|
Après le nom du fichier, toutes les options sont spécifiques au modèle
|
|
utilisé pour créer le nouveau fichier. Utiliser l'option --help pour
|
|
avoir une description des options disponibles."
|
|
}
|
|
|
|
SCRIPT_ALIASES=(
|
|
pv:vcs
|
|
pa:add prm:remove pcp:copy pmv:move pmd:mkdir
|
|
pci:commit pu:update pp:push pdiff:diff
|
|
pclone:clone
|
|
pcrone:crone
|
|
pxx:annex
|
|
pxa:xadd pxu:xunlock pxc:xcopy pxd:xdrop pxm:xmove
|
|
pxg:xget pxs:xsync pxw:xwhereis pxwa:xwebapp
|
|
pxinitial:xinitial
|
|
pnew:new
|
|
pgr:grep
|
|
paddml:addml
|
|
)
|
|
CMD_ALIASES=(
|
|
getrepo:getrepos repo:getrepos repos:getrepos
|
|
url:geturl
|
|
a:add
|
|
rm:remove del:remove delete:remove
|
|
cp:copy
|
|
mv:move ren:move rename:move
|
|
md:mkdir
|
|
ci:commit
|
|
s:status st:status
|
|
u:update upd:update
|
|
p:push
|
|
version:pver ver:pver
|
|
develop:pdev dev:pdev release:prel rel:prel hotfix:pfix fix:pfix
|
|
archive:pz arch:pz
|
|
xx:annex
|
|
xa:xadd
|
|
xu:xunlock
|
|
xc:xcopy
|
|
xd:xdrop
|
|
xm:xmove
|
|
xg:xget
|
|
xs:xsync
|
|
xw:xwhereis
|
|
xwa:xwebapp
|
|
xce:xconfig-export
|
|
gr:grep
|
|
)
|
|
DEFAULT_CMD=status
|
|
PY_CMDS=(new)
|
|
VCS_CMDS=(getvcs getroot getrepos geturl vcs add remove copy move mkdir commit status update push diff tag)
|
|
SH_CMDS=(pver pdev prel pfix pz)
|
|
GITANNEX_CMDS=(annex xadd xunlock xcopy xdrop xmove xget xsync xwhereis xwebapp xinitial)
|
|
ML_CMDS=(printml addml)
|
|
|
|
if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then
|
|
# créer les liens
|
|
scriptname="$(basename "$0")"
|
|
for alias in p "${SCRIPT_ALIASES[@]}"; do
|
|
alias="${alias%:*}"
|
|
ln -s "$scriptname" "$alias"
|
|
done
|
|
exit 0
|
|
fi
|
|
|
|
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
|
|
urequire DEFAULTS modeline vcs
|
|
|
|
# Traduire le nom du script
|
|
for script_alias in "${SCRIPT_ALIASES[@]}"; do
|
|
splitpair "$script_alias" src dest
|
|
if [ "$scriptname" == "$src" ]; then
|
|
eval "set -- $dest \"\$@\""
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Parser les options de uproject
|
|
parse_opts + "${PRETTYOPTS[@]}" \
|
|
--help '$exit_with display_help' \
|
|
@ args -- "$@" && set -- "${args[@]}" || die "$args"
|
|
|
|
# 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
|
|
|
|
################################################################################
|
|
# Traiter les commandes
|
|
|
|
function use_ssh_wrapper() {
|
|
__UTOOLS_FORCE_PATH="$PATH"
|
|
__UTOOLS_FORCE_SSH="${GIT_SSH:-ssh}"
|
|
export __UTOOLS_FORCE_PATH __UTOOLS_FORCE_SSH
|
|
udelpath "$scriptdir/lib/ssh-wrapper" __UTOOLS_FORCE_PATH
|
|
uinspath "$scriptdir/lib/ssh-wrapper" PATH
|
|
}
|
|
|
|
if [ "$CMD" == "grep" ]; then
|
|
## grep
|
|
if [ $# -eq 1 -a "$1" == "--help" ]; then
|
|
uecho "uproject grep: Lancer une recherche récursive en ignorant les répertoire de controle de version
|
|
|
|
USAGE
|
|
uproject grep [grep options]"
|
|
exit 0
|
|
fi
|
|
EXCLUDES=(--exclude-dir .svn --exclude-dir CVS --exclude-dir .git --exclude "*.pyc")
|
|
exec grep -r "${EXCLUDES[@]}" "$@"
|
|
|
|
elif array_contains SH_CMDS "$CMD"; then
|
|
exec "$scriptdir/$CMD" "$@"
|
|
|
|
elif array_contains ML_CMDS "$CMD"; then
|
|
"$CMD" "$@"
|
|
|
|
elif array_contains VCS_CMDS "$CMD"; then
|
|
"vcs_$CMD" "$@"
|
|
|
|
elif array_contains GITANNEX_CMDS "$CMD"; then
|
|
function xsync() {
|
|
if ! git_have_annex; then
|
|
git_commit -Al "Maj des fichiers" && git pull && git_push
|
|
elif is_yes "$(git config --get annex.direct)"; then
|
|
git annex add &&
|
|
git annex sync &&
|
|
git annex sync --content &&
|
|
git annex sync
|
|
else
|
|
git annex sync
|
|
fi
|
|
}
|
|
use_ssh_wrapper
|
|
case "$CMD" in
|
|
annex) git annex "$@";;
|
|
xsync) xsync;;
|
|
xcopy|xmove|xget) git annex "${CMD#x}" "$@" && git annex sync;;
|
|
xinitial) git_annex_initial "$@";;
|
|
*) git annex "${CMD#x}" "$@";;
|
|
esac
|
|
|
|
elif [ "$CMD" == clone ]; then
|
|
repourl="${1%.git}"
|
|
[ -n "$repourl" ] || die "Vous devez spécifier l'url du dépôt git"
|
|
splitfsep "$repourl" : userhost path
|
|
|
|
destdir="$2"
|
|
if [ -z "$destdir" ]; then
|
|
setx destdir=basename -- "$path"
|
|
destdir="${destdir%.git}"
|
|
fi
|
|
[ -d "$destdir" ] && die "$(ppath "$destdir"): répertoire existant"
|
|
|
|
use_ssh_wrapper
|
|
git clone "$repourl" "$destdir" || die
|
|
git_annex_initial "$destdir" || die
|
|
|
|
elif [ "$CMD" == crone ]; then
|
|
repourl="${1%.git}"
|
|
[ -n "$repourl" ] || die "Vous devez spécifier l'url du dépôt git"
|
|
splitfsep "$repourl" : userhost path
|
|
|
|
destdir="$2"
|
|
if [ -z "$destdir" ]; then
|
|
setx destdir=basename -- "$path"
|
|
destdir="${destdir%.git}"
|
|
fi
|
|
[ -d "$destdir" ] && die "$(ppath "$destdir"): répertoire existant"
|
|
|
|
splituserhost "$userhost" user host
|
|
[ -n "$user" ] || user=git
|
|
[ -n "$host" ] || die "Vous devez spécifier l'hôte"
|
|
userhost="$user@$host"
|
|
[ -n "$path" ] || die "Vous devez spécifier le chemin du dépôt git"
|
|
|
|
use_ssh_wrapper
|
|
ssh "$userhost" create "$path" || die
|
|
git clone "$userhost:$path" "$destdir" || die
|
|
git_annex_initial "$destdir" || die
|
|
|
|
elif [ "$CMD" == xconfig-export ]; then
|
|
unset GIT_DIR; unset GIT_WORK_TREE
|
|
dir="${1:-.}"
|
|
[ -d "$dir" ] || die "$dir: répertoire introuvable"
|
|
setx dir=abspath "$dir"
|
|
setx repodir=ppath "$dir"
|
|
cd "$dir"
|
|
|
|
git rev-parse 2>/dev/null || die "$repodir: n'est pas un dépôt git"
|
|
[ -n "$(git config --get annex.uuid)" ] || die "$repodir: n'est pas un dépôt git-annex"
|
|
cd "$(__vcs_find_root "$dir")"
|
|
[ -d .git ] || die "$repodir: est un dépôt nu"
|
|
|
|
prhook=.git/hooks/post-receive
|
|
prscript='if [ -n "$GIT_DIR" ]; then cd "$GIT_DIR"; cd ..; unset GIT_DIR; fi
|
|
git annex merge'
|
|
puhook=.git/hooks/post-update
|
|
puscript='git update-server-info'
|
|
if [ -f "$prhook" ]; then
|
|
ewarn "Le fichier $prhook existe déjà dans $repodir
|
|
Vérifiez qu'il contient les commandes suivantes:
|
|
--------8<--------
|
|
$prscript
|
|
--------8<--------"
|
|
else
|
|
estep "post-receive"
|
|
echo "#!/bin/bash
|
|
$prscript" >"$prhook"
|
|
chmod +x "$prhook"
|
|
fi
|
|
if [ -f "$puhook" ]; then
|
|
ewarn "Le fichier $puhook existe déjà dans $repodir
|
|
Vérifiez qu'il contient les commandes suivantes:
|
|
--------8<--------
|
|
$puscript
|
|
--------8<--------"
|
|
else
|
|
estep "post-update"
|
|
echo "#!/bin/bash
|
|
$puscript" >"$puhook"
|
|
chmod +x "$puhook"
|
|
fi
|
|
|
|
elif array_contains PY_CMDS "$CMD"; then
|
|
exec "$scriptdir/lib/pywrapper" uproject.py "$CMD" "$@"
|
|
|
|
else
|
|
die "$CMD: commande inconnue"
|
|
fi
|