nutools/ulib

378 lines
12 KiB
Bash
Executable File

#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname -- "$0")/lib/ulib/auto" || exit 1
function display_help() {
uecho "$scriptname: Gestion des librairies ulib et pyulib
USAGE
$scriptname [options] --destdir DESTDIR [options]
$scriptname [options] --version [options]
$scriptname [options] --shell [options]
SYNCHRONISER ULIB/PYULIB
-S, --sync
Synchroniser ulib, pyulib et les scripts de support
-d, --destdir DESTDIR
Synchroniser ulib et/ou pyulib dans le répertoire destdir.
Les options -u et -p permettent de choisir ce qui est synchronisé
-u, --ulib
Copier/mettre à jour ulib (par défaut)
-p, --pyulib
Copier/mettre à jour pyulib
-s, --support
Copier/mettre à jour les scripts de support
GERER LA VERSION DE ULIB
-v, --version
Gérer la version de ulib
-l, --show
Afficher la version de la librairie (par défaut)
-s, --system
Afficher aussi la version de la librairie système
-c, --check MIN_VERSION
Vérifier que la version de la librairie est au minimum MIN_VERSION, et
afficher un message d'information. Utiliser l'option -q si l'on veut
juste tester la version et ne pas afficher le message d'information.
-V, --set-version VERSION
Forcer la version de ulib
-u, --update
Incrémenter la version de ulib. Les options -x, -z, -p permettent de
choisir le numéro qui est incrémenté.
-x, --major
Augmenter le numéro de version majeure
-z, --minor
Augmenter le numéro de version mineure. C'est l'option par défaut
-p, --patchlevel
Augementer le numéro de patch
LANCER UN SHELL (par défaut)
-s, --shell
Lancer un shell dans lequel les modules de ulib spécifiés sont chargés.
De plus, PATH est modifié pour que $scriptdir soit ajouté en premier.
Les arguments restants sont passés inchangés au shell.
-r, --require module
Spécifier un module à charger avec urequire. Plusieurs modules peuvent
être spécifiés en les séparant par ':'
Par défaut, seul le module DEFAULTS est chargé.
--force-reload
Forcer le (re)chargement des modules avec urequire. Cette option est
utile pour le développement. En effet, dans le shell, la commande
'urequire module' (re)charge toujours le module, même s'il avait déjà
été chargé."
}
function formatversion() {
local major="${1:-${major:-0}}" minor="${2:-${minor:-0}}" patch="${3:-${patch:-0}}"
while [ ${#major} -lt 3 ]; do major="0$major"; done
while [ ${#minor} -lt 3 ]; do minor="0$minor"; done
while [ ${#patch} -lt 3 ]; do patch="0$patch"; done
echo "$major$minor$patch"
}
function parsepversion() {
local v M m p
if [[ "$1" == *.* ]]; then
local v="$1"; shift
local M=0 m=0 p=0
if [[ "$v" == *.* ]]; then
p="${v##*.}"; v="${v%.*}"
if [[ "$v" == *.* ]]; then
m="${v##*.}"; v="${v%.*}"
if [[ "$v" == *.* ]]; then
M="${v##*.}"; v="${v%.*}"
else
M="$v"
fi
else
m="$v"
fi
else
p="$v"
fi
parseversion "$(formatversion "$M" "$m" "$p")" "$@"
else
parseversion "$@"
fi
}
function parseversion() {
if [ -n "$2" ]; then
local version="${1:-${version:-000000000}}"
local major minor patch pversion
else
version="${1:-${version:-000000000}}"
fi
while [ ${#version} -lt 9 ]; do version="0$version"; done
major="${version:0:3}"; while [ ${#major} -gt 1 -a "${major#0}" != "$major" ]; do major="${major#0}"; done
minor="${version:3:3}"; while [ ${#minor} -gt 1 -a "${minor#0}" != "$minor" ]; do minor="${minor#0}"; done
patch="${version:6:3}"; while [ ${#patch} -gt 1 -a "${patch#0}" != "$patch" ]; do patch="${patch#0}"; done
pversion="$major.$minor.$patch"
[ -n "$2" ] && eval "${2}version=\$version; ${2}major=\$major; ${2}minor=\$minor; ${2}patch=\$patch; ${2}pversion=\$pversion"
}
# mode de fonctionnement
case "$scriptname" in
ulibsync) mode=sync;;
ulibversion) mode=version;;
ulibshell) mode=shell;;
*) mode=auto;;
esac
# mode sync
destdir=
syncwhat=auto
synculib=
syncpyulib=
syncsupport=
# mode version
action=show
system=
min_version=
set_version=
inc_version=minor
# mode shell
modules=()
# options courtes partagées
u_opt=; p_opt=; s_opt=
parse_opts + "${PRETTYOPTS[@]}" \
--help '$exit_with display_help' \
-S,--sync mode=sync \
-d:,--destdir: '$mode=sync; set@ destdir' \
--ulib '$mode=sync; syncwhat=; synculib=1' \
--pyulib '$mode=sync; syncwhat=; syncpyulib=1' \
--support '$mode=sync; syncwhat=; syncsupport=1' \
-v,--version mode=version \
-l,--show '$mode=version; action=show' \
--system '$mode=version; action=show; system=1' \
-c:,--check: '$mode=version; action=check; set@ min_version' \
-V:,--set-version: '$mode=version; action=set; set@ set_version' \
--update '$mode=version; action=inc' \
-x,--major '$mode=version; action=inc; inc_version=major' \
-z,--minor '$mode=version; action=inc; inc_version=minor' \
--patchlevel '$mode=version; action=inc; inc_version=patch' \
--shell mode=shell \
-r:,--require: '$mode=shell; add@ modules' \
--force-reload '$mode=shell; __ULIB_FORCE_RELOAD=1' \
-u u_opt=1 \
-p p_opt=1 \
-s s_opt=1 \
@ args -- "$@" && set -- "${args[@]}" || die "$args"
case "$mode" in
auto)
mode=
if [ -n "$u_opt" ]; then
mode=version; action=inc
fi
if [ -n "$p_opt" -a -n "$u_opt" ]; then
# support de -up
mode=version; action=inc; inc_version=patch
elif [ -n "$p_opt" ]; then
die "getopt: invalid option 'p'"
fi
if [ -n "$s_opt" ]; then
mode=shell
fi
;;
esac
[ -n "$mode" ] || mode=shell
case "$mode" in
sync)
[ -n "$u_opt" ] && { syncwhat=; synculib=1; }
[ -n "$p_opt" ] && { syncwhat=; syncpyulib=1; }
[ -n "$s_opt" ] && { syncwhat=; syncsupport=1; }
[ "$syncwhat" == auto ] && {
synculib=1
#syncpyulib=
#syncsupport=
}
[ -n "$destdir" ] || destdir="$1"
[ -z "$destdir" -a -n "$synculib" -a -d lib/ulib ] && destdir=lib
[ -z "$destdir" -a -n "$syncpyulib" -a -d lib/pyulib ] && destdir=lib
[ -n "$destdir" ] || destdir=.
ask_yesno "Voulez-vous copier ${synculib:+
- la librairie ulib}${syncpyulib:+
- la librairie pyulib}${syncsupport:+
- scripts de support}
dans $(ppath "$destdir")?" O || die
urequire install
if [ -n "$synculib" ]; then
__ulib_install_show_args ulib "$destdir" 1
ulibsync "$destdir"
fi
if [ -n "$syncpyulib" ]; then
urequire pyulib/pyulib
__ulib_install_show_args pyulib "$destdir" 1
pyulibsync "$destdir"
fi
if [ -n "$syncsupport" ]; then
adestdir="$(abspath "$destdir")"
for i in .nutools-bootstrap; do
if [ "${adestdir%/lib}" != "$adestdir" ]; then
# cas particulier: synchro vers un répertoire lib/
# dans ce cas, copier le fichier .nutools-bootstrap dans le
# répertoire parent.
copy_update "$scriptdir/$i" "$(dirname -- "$destdir")"
else
copy_update "$scriptdir/$i" "$destdir"
fi
done
# calculer le nom du répertoire de destination, pour nommer les fichiers
# local-uinst
destpfix="${adestdir%/lib}"
destpfix="${destpfix##*/}"
destpfix="${destpfix:-local}"
for i in lib/ulib/support/local-uinst lib/ulib/support/local-uinst.sh; do
destname="$destpfix-${i#lib/ulib/support/local-}"
copy_update "$scriptdir/$i" "$destdir/$destname"
done
fi
exit 0
;;
version)
[ -n "$u_opt" ] && { action=inc; }
[ -n "$p_opt" ] && { action=inc; inc_version=patch; }
[ -n "$s_opt" ] && { action=show; system=1; }
setx version formatversion 0 0 0
versionfile="$scriptdir/lib/ulib/.ulibver"
[ -f "$versionfile" ] || echo "$version" >"$versionfile"
[ -f "$versionfile" ] && version="$(<"$versionfile")"
parseversion "$(<"$versionfile")"
if [ "$action" == set -o "$action" == inc ]; then
[ -f "$scriptdir/.nutools-devel" ] ||
die "Cette installation de ulib est déjà déployé en version $pversion: impossible de la mettre à jour."
fi
if [ "$action" == show ]; then
if [ -n "$system" ]; then
setx sversion formatversion 0 0 0
sversionfile="/etc/.ulibver"
[ -f "$sversionfile" ] && sversion="$(<"$sversionfile")"
parseversion "$(<"$versionfile")" s
fi
if isatty; then
eecho "ulib est en version $pversion"
[ -n "$system" ] && eecho "/etc/ulib est en version $spversion"
else
echo "$pversion"
[ -n "$system" ] && echo "$spversion"
fi
elif [ "$action" == set ]; then
parsepversion "$set_version"
formatversion >"$versionfile"
eecho "ulib est maintenant en version $pversion"
elif [ "$action" == inc ]; then
case "$inc_version" in
major) major=$(($major + 1)); minor=0; patch=0;;
minor) minor=$(($minor + 1)); patch=0;;
patch) patch=$(($patch + 1));;
esac
formatversion >"$versionfile"
parseversion "$(<"$versionfile")"
eecho "ulib est maintenant en version $pversion"
elif [ "$action" == check ]; then
r=1
parsepversion "$min_version" m
[ "$version" -ge "$mversion" ] && r=0
if [ $r -eq 0 ]; then
eecho "ulib est en version $pversion >= $mpversion ${COULEUR_VERTE}[OK]${COULEUR_NORMALE}"
else
eecho "ulib est en version $pversion < $mpversion ${COULEUR_ROUGE}[KO]${COULEUR_NORMALE}"
fi
exit $r
else
die "BUG: action inconnue $action"
fi
;;
shell)
[ -n "$u_opt" ] && die "getopt: invalid option 'u'"
[ -n "$p_opt" ] && die "getopt: invalid option 'p'"
[ -n "$s_opt" ] && { mode=shell; } # FYI, ici $mode vaut déjà shell
ac_set_tmpfile bashrc
echo "\
if ! grep -q '/etc/bash.bashrc' /etc/profile; then
[ -f /etc/bash.bashrc ] && source /etc/bash.bashrc
fi
if ! grep -q '~/.bashrc' ~/.bash_profile; then
[ -f ~/.bashrc ] && source ~/.bashrc
fi
[ -f /etc/profile ] && source /etc/profile
[ -f ~/.bash_profile ] && source ~/.bash_profile
if ! grep -q '$scriptdir/bashrc' ~/.bashrc; then
if [ -f '$scriptdir/bashrc' ]; then
if ! grep -q @@dest@@ '$scriptdir/bashrc'; then
# ne lire que si le répertoire est déployé
source '$scriptdir/bashrc'
fi
fi
function uprovide() { :; }
source '$scriptdir/lib/ulib/uenv'
__uenv_source_dirs '$scriptdir/lib/bashrc.d'
__uenv_cleanup
fi
if ! grep -q '$scriptdir/profile' ~/.bash_profile; then
if [ -f '$scriptdir/profile' ]; then
if grep -q @@dest@@ '$scriptdir/profile'; then
# répertoire non déployé
# la ligne suivante est copiée du fichier profile
[ -z '$USER' -a -n '$LOGNAME' ] && export USER='$LOGNAME'
else
# ne lire que si le répertoire est déployé
source '$scriptdir/profile'
fi
fi
function uprovide() { :; }
source '$scriptdir/lib/ulib/uenv'
__uenv_source_dirs '$scriptdir/lib/profile.d'
__uenv_cleanup
fi
# Modifier le PATH. Ajouter aussi le chemin vers les uapps python
PATH=$(qval "$scriptdir:$scriptdir/lib/pyulib/src/uapps:$PATH")
if [ -n '$DEFAULT_PS1' ]; then
DEFAULT_PS1=$(qval "[ulibshell] $DEFAULT_PS1")
else
if [ -z '$PS1' ]; then
PS1='\\u@\\h \\w \\$ '
fi
PS1=\"[ulibshell] \$PS1\"
fi
$(qvals source "$scriptdir/lib/ulib/ulib")
__ULIB_FORCE_RELOAD=$(qval "$__ULIB_FORCE_RELOAD")
urequire DEFAULTS" >"$bashrc"
array_fix_paths modules
if [ -n "${modules[*]}" ]; then
etitle "Chargement des modules"
for module in "${modules[@]}"; do
estep "$module"
qvals urequire "$module" >>"$bashrc"
done
eend
fi
estep "Lancement du sous-shell"
"$SHELL" --rcfile "$bashrc" -i -- "$@"
# note: ne pas faire exec "$SHELL", parce que sinon le fichier temporaire bashrc
# n'est pas supprimé
ac_clean "$bashrc"
;;
esac