#!/bin/bash # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 source "$(dirname "$0")/lib/ulib/ulib" || exit 1 urequire DEFAULTS 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é." } 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' \ -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 echo "ulib est en version $pversion" if [ -n "$system" ]; then setx sversion formatversion 0 0 0 sversionfile="/etc/.ulibver" [ -f "$sversionfile" ] && sversion="$(<"$sversionfile")" parseversion "$(<"$versionfile")" s echo "/etc/ulib est en version $spversion" fi elif [ "$action" == set ]; then parsepversion "$set_version" formatversion >"$versionfile" echo "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")" echo "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=$(quoted_args "$scriptdir:$scriptdir/lib/pyulib/src/uapps:$PATH") if [ -n '$DEFAULT_PS1' ]; then DEFAULT_PS1=$(quoted_args "[ulibshell] $DEFAULT_PS1") else if [ -z '$PS1' ]; then PS1='\\u@\\h \\w \\$ ' fi PS1=\"[ulibshell] \$PS1\" fi $(quoted_args source "$scriptdir/lib/ulib/auto")" >"$bashrc" array_fix_paths modules if [ -n "${modules[*]}" ]; then etitle "Chargement des modules" for module in "${modules[@]}"; do estep "$module" quoted_args 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