#!/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