From bdc9ddf8b5791c5019b7c7bb71188d12c39cb873 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 11:59:21 +0100 Subject: [PATCH 1/9] std:split_fname(): changed arguments and leading slash handling - a leading slash is now removed - the filename is now passed as second argument, the number of parts is returned in an optional third argument --- Pmodules/libstd.bash | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Pmodules/libstd.bash b/Pmodules/libstd.bash index fedd0c4..f7bee90 100644 --- a/Pmodules/libstd.bash +++ b/Pmodules/libstd.bash @@ -135,14 +135,27 @@ std::replace_path () { # # split file name # +# Args: +# $1 upvar +# $2 fname +# $3 opt upvar: number of components +# std::split_fname() { - local -r savedIFS="${IFS}" + local parts="$1" + local -r fname="$2" + if [[ "${fname:0:1}" == '/' ]]; then + local -r std__split_fname_tmp="${fname:1}" + else + local -r std__split_fname_tmp="${fname}" + fi + IFS='/' - local std__split_fname_result__=( $(echo "${@: -1}") ) - IFS=${savedIFS} - eval $1=\(\"\${std__split_fname_result__[@]}\"\) + local std__split_fname_result=( ${std__split_fname_tmp} ) + unset IFS + std::upvar ${parts} "${std__split_fname_result[@]}" if (( $# >= 3 )); then - eval $2=${#std__split_fname_result__[@]} + # return number of parts + std::upvar "$3" ${#std__split_fname_result[@]} fi } From 8112e8b6d4fd730e372eb371317c4b91f70514b1 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 12:20:17 +0100 Subject: [PATCH 2/9] std::split_fname(): reviewed and renamed to std::split_abs_path() --- Pmodules/libstd.bash | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Pmodules/libstd.bash b/Pmodules/libstd.bash index f7bee90..6314872 100644 --- a/Pmodules/libstd.bash +++ b/Pmodules/libstd.bash @@ -133,29 +133,29 @@ std::replace_path () { } # -# split file name +# split an absolute path # # Args: # $1 upvar -# $2 fname +# $2 absolute path # $3 opt upvar: number of components # -std::split_fname() { +std::split_abs_path() { local parts="$1" - local -r fname="$2" - if [[ "${fname:0:1}" == '/' ]]; then - local -r std__split_fname_tmp="${fname:1}" + local -r path="$2" + if [[ "${path:0:1}" == '/' ]]; then + local -r std__split_path_tmp="${path:1}" else - local -r std__split_fname_tmp="${fname}" + std::die 255 "Oops: Internal error in '${FUNCNAME[0]}' called by '${FUNCNAME[1]}' }" fi IFS='/' - local std__split_fname_result=( ${std__split_fname_tmp} ) + local std__split_path_result=( ${std__split_path_tmp} ) unset IFS - std::upvar ${parts} "${std__split_fname_result[@]}" + std::upvar ${parts} "${std__split_path_result[@]}" if (( $# >= 3 )); then # return number of parts - std::upvar "$3" ${#std__split_fname_result[@]} + std::upvar "$3" ${#std__split_path_result[@]} fi } From 6d53069bedb6978a504cf078ed55b68bc92a43be Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 12:25:25 +0100 Subject: [PATCH 3/9] std::split_abs_path() renamed to std::split_abspath() --- Pmodules/libstd.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pmodules/libstd.bash b/Pmodules/libstd.bash index 6314872..f56ae57 100644 --- a/Pmodules/libstd.bash +++ b/Pmodules/libstd.bash @@ -140,7 +140,7 @@ std::replace_path () { # $2 absolute path # $3 opt upvar: number of components # -std::split_abs_path() { +std::split_abspath() { local parts="$1" local -r path="$2" if [[ "${path:0:1}" == '/' ]]; then From a67b3cdf5f1069fe39bdb27be2191dc3eadd2531 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 13:44:54 +0100 Subject: [PATCH 4/9] better solution to define used commands implemented --- Pmodules/libstd.bash | 11 +++++++++++ Pmodules/modulecmd.bash.in | 30 +++++++----------------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Pmodules/libstd.bash b/Pmodules/libstd.bash index f56ae57..5161915 100644 --- a/Pmodules/libstd.bash +++ b/Pmodules/libstd.bash @@ -35,6 +35,17 @@ std::die() { exit $ec } +std::def_cmds(){ + local path="$1" + shift + for cmd in "$@"; do + eval declare -g ${cmd}=$(PATH="${path}" which $cmd 2>/dev/null) + if [[ -z "${!cmd}" ]]; then + std::die 255 "${cmd} not found" + fi + done +} + # # get answer to yes/no question # diff --git a/Pmodules/modulecmd.bash.in b/Pmodules/modulecmd.bash.in index 1644675..ccde9f6 100644 --- a/Pmodules/modulecmd.bash.in +++ b/Pmodules/modulecmd.bash.in @@ -13,30 +13,14 @@ declare prefix=$(dirname "${mydir}") declare -r libdir="${prefix}/lib" declare -r libexecdir="${prefix}/libexec" -base64=$(PATH=/bin:/usr/bin /usr/bin/which base64) -declare -r base64 -mktemp=$(PATH=/bin:/usr/bin /usr/bin/which mktemp) -declare -r mktemp -sort=$(PATH=/bin:/usr/bin /usr/bin/which sort) -declare -r sort -awk=$(PATH=/bin:/usr/bin /usr/bin/which awk) -declare -r awk -rm=$(PATH=/bin:/usr/bin /usr/bin/which rm) -declare -r rm -logger=$(PATH=/bin:/usr/bin /usr/bin/which logger) -declare -r logger - -if [[ $(uname -s) == 'Darwin' ]]; then - declare -r getopt="${libexecdir}/getopt" - declare -r find="${libexecdir}/find" -else - getopt=$(PATH=/bin:/usr/bin /usr/bin/which getopt) - declare -r getopt - find=$(PATH=/bin:/usr/bin /usr/bin/which find) - declare -r find -fi - source "${libdir}/libstd.bash" +source "${libdir}/libpmodules.bash" + +path="/bin:/usr/bin" +[[ $(uname -s) == 'Darwin' ]] && path+=":${libexecdir}" +std::def_cmds "${path}" \ + 'awk' 'base64' 'find' 'getopt' 'logger' 'mktemp' \ + 'rm' 'sort' 'find' if [[ ${PMODULES_PURETCL} == yes ]]; then declare -r modulecmd="${libexecdir}/modulecmd.tcl" From d1a66d5e6f838bb5591c3d9a43c531cc309cae23 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 14:05:05 +0100 Subject: [PATCH 5/9] libpmodules.bash reviewed - cleanup code in lib - function we need in modmanage moved to lib - some cleanup in modulecmd --- .../{libpmodules.bash => libpmodules.bash.in} | 0 Pmodules/modulecmd.bash.in | 72 ++----------------- 2 files changed, 7 insertions(+), 65 deletions(-) rename Pmodules/{libpmodules.bash => libpmodules.bash.in} (100%) diff --git a/Pmodules/libpmodules.bash b/Pmodules/libpmodules.bash.in similarity index 100% rename from Pmodules/libpmodules.bash rename to Pmodules/libpmodules.bash.in diff --git a/Pmodules/modulecmd.bash.in b/Pmodules/modulecmd.bash.in index ccde9f6..5afa784 100644 --- a/Pmodules/modulecmd.bash.in +++ b/Pmodules/modulecmd.bash.in @@ -1,9 +1,12 @@ #!@BASH@ --noprofile # -#set -o nounset -# we have to unset CDPATH, otherwise 'cd' prints the directoy! -unset CDPATH +PATH='/bin:/usr/bin' +case +unset CDPATH # unset CDPATH, otherwise 'cd' prints the directoy! +unset IFS # use default IFS + +shopt -s nullglob # used for some output only declare -r CMD='module' @@ -31,20 +34,11 @@ fi declare verbosity_lvl=${PMODULES_VERBOSITY:-'verbose'} -# use default IFS -unset IFS - -shopt -s nullglob - -declare -A GroupDepths='()' declare Shell='' -declare -A Subcommands -declare -A Options -declare -A Help declare -r pmodules_config_file="${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/Pmodules.conf" -# the following settings are used if the Pmodules.conf is not available +# the following settings are used if the Pmodules.conf doesn't exist # set groups which should be available after initialization declare -- DefaultGroups='Tools Programming' @@ -55,22 +49,6 @@ declare -- ReleaseStages=':unstable:stable:deprecated:' # set releases which should be available after initialization declare -- DefaultReleaseStages='stable' -# In the dictionary Help we store the help text of each single command -# and for displaying the version. - -# initialize help text of 'module --version' -Help['version']=" -Pmodules @PMODULES_VERSION@ using Tcl Environment Modules @MODULES_VERSION@ -Copyright GNU GPL v2 -" - -# -# display help text for command given in $1 -# -print_help() { - echo -e "${Help[$1]}" 1>&2 - std::die 1 -} export_env() { case "${Shell}" in @@ -170,42 +148,6 @@ is_release_stage() { [[ ${ReleaseStages} =~ :$1: ]] } -# -# compute depth of modulefile directory. -# -# Args: -# $1: absolute path of a modulefile directory -# -compute_group_depth () { - local -r dir=$1 - test -d "${dir}" || return 1 - local group=${dir%/*} - local group=${group##*/} - [[ -n "${GroupDepths[${group}]}" ]] && return 0 - local -i depth=$(${find} "${dir}" -depth \( -type f -o -type l \) \ - -printf "%d" -quit 2>/dev/null) - (( depth-=2 )) - # if a group doesn't contain a modulefile, depth is negativ - # :FIXME: better solution? - (( depth < 0 )) && (( depth = 0 )) - GroupDepths[$group]=${depth} - g_env_must_be_saved='yes' -} - -# -# (Re-)Scan available groups in given root and compute group depth's -# -# Args: -# $1: root of modulefile hierarchy -# -scan_groups () { - local -r root="$1" - local moduledir - for moduledir in ${root}/*/${PMODULES_MODULEFILES_DIR}; do - compute_group_depth "${moduledir}" - done -} - # # Check whether argument is a group # From 98ce3112eed6aacecf1df1054f6250514542d285 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 14:13:55 +0100 Subject: [PATCH 6/9] review libpmodules.bash, new functions added, cleanup --- Pmodules/libpmodules.bash.in | 74 +++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/Pmodules/libpmodules.bash.in b/Pmodules/libpmodules.bash.in index cba80a7..7ad1140 100644 --- a/Pmodules/libpmodules.bash.in +++ b/Pmodules/libpmodules.bash.in @@ -1,38 +1,60 @@ #!/bin/bash -if [[ -z ${sbindir} ]]; then - local sbindir=$(dirname "${BASH_SOURCE}") - sbindir=$(cd "${sbindir}"/.. && pwd)"/sbin" -fi +declare PMODULES_MODULEFILES_DIR='modulefiles' +declare -A GroupDepths=() +declare -A Subcommands=() +declare -A Options=() +declare -A Help=() -pmodules::get_options() { - local "$1" - std::upvar $1 $("${sbindir}/getopt" "${@:2}") +# initialize help text of 'module --version' +Help['version']=" +Pmodules @PMODULES_VERSION@ using Tcl Environment Modules @MODULES_VERSION@ +Copyright GNU GPL v2 +" + +# +# display help text for command given in $1 +# +print_help() { + echo -e "${Help[$1]}" 1>&2 + std::die 1 } -pmodules::check_env_vars() { - [[ -n "${PMODULES_ROOT}" ]] && - [[ -n "${PMODULES_HOME}" ]] && - [[ -n "${PMODULES_VERSION}" ]] || std::die 1 " -Error: the module environment you are going to use as source has not been -initialized properly!" +# +# compute depth of modulefile directory. +# +# Args: +# $1: absolute path of a modulefile directory +# +compute_group_depth () { + local -r dir=$1 + test -d "${dir}" || return 1 + local group=${dir%/*} + local group=${group##*/} + [[ -n "${GroupDepths[${group}]}" ]] && return 0 + local -i depth=$(${find} "${dir}" -depth \( -type f -o -type l \) \ + -printf "%d" -quit 2>/dev/null) + (( depth-=2 )) + # if a group doesn't contain a modulefile, depth is negativ + # :FIXME: better solution? + (( depth < 0 )) && (( depth = 0 )) + GroupDepths[$group]=${depth} } -pmodules::check_directories() { - local -r src_prefix="$1" - - [[ -d "${src_prefix}" ]] && - [[ -d "${src_prefix}/${PMODULES_CONFIG_DIR}" ]] && - [[ -d "${src_prefix}/Tools/Pmodules/${PMODULES_VERSION}" ]] || std::die 1 " -Error: the module environment '${src_prefix}' has not been initialized properly!" +# +# (Re-)Scan available groups in given root and compute group depth's +# +# Args: +# $1: root of modulefile hierarchy +# +scan_groups () { + local -r root="$1" + local moduledir + for moduledir in ${root}/*/${PMODULES_MODULEFILES_DIR}; do + compute_group_depth "${moduledir}" + done } -pmodules::check_env() { - pmodules::check_env_vars - pmodules::check_directories "${PMODULES_ROOT}" -} - - # Local Variables: # mode: sh # sh-basic-offset: 8 From 1204517a99be8702c7b30e527d7026ccb31f76f1 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 14:27:12 +0100 Subject: [PATCH 7/9] modulecmd: cmd-line arguments and handling reviewed --- Pmodules/modulecmd.bash.in | 97 ++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 46 deletions(-) diff --git a/Pmodules/modulecmd.bash.in b/Pmodules/modulecmd.bash.in index 1644675..c53db32 100644 --- a/Pmodules/modulecmd.bash.in +++ b/Pmodules/modulecmd.bash.in @@ -254,7 +254,7 @@ subcommand_generic0() { local -a args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -282,7 +282,7 @@ subcommand_generic1() { local -a args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -314,7 +314,7 @@ subcommand_generic1plus() { local args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -344,7 +344,7 @@ subcommand_generic1plus() { # Subcommands[add]='load' Subcommands[load]='load' -Options['load']='-l help -o Hfsvwi -l force -l silent -l verbose -l warn -l internal' +Options[load]='-l help -o \?Hfsvw -l force -l silent -l verbose -l warn' Help[load]=' USAGE: module add modulefile... @@ -467,7 +467,7 @@ subcommand_load() { opts=() while (($# > 0)); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -f | --force ) @@ -664,7 +664,7 @@ subcommand_load() { # Subcommands[rm]='unload' Subcommands[unload]='unload' -Options[unload]='-o H -l help' +Options[unload]='-o \?H -l help' Help[unload]=" USAGE: module rm modulefile... @@ -683,7 +683,7 @@ subcommand_unload() { local args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -737,7 +737,7 @@ subcommand_unload() { # Subcommands[switch]='swap' Subcommands[swap]='swap' -Options[swap]='-o H -l help' +Options[swap]='-o \?H -l help' Help[swap]=" USAGE: module switch [modulefile1] modulefile2 @@ -752,7 +752,7 @@ subcommand_swap() { local args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -792,7 +792,7 @@ subcommand_swap() { # Subcommands[display]='show' Subcommands[show]='show' -Options[show]='-o H -l help' +Options[show]='-o \?H -l help' Help[show]=' USAGE: module display modulefile... @@ -809,7 +809,7 @@ subcommand_show() { local args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -874,7 +874,8 @@ get_available_modules() { # avail [-hlt] [...] # Subcommands[avail]='avail' -Options[avail]='-l help -o Hahlmt -l all -l all-release-stages -l human -l long -l machine -l terse' +Options[avail]='-l help -o \?Hahlmtg: -l all -l all-release-stages -l group: ' +Options[avail]+='-l human -l long -l machine -l terse' Help[avail]=" USAGE: module avail [switches] string @@ -897,8 +898,12 @@ SWITCHES: -l|--long Output in long format. + -g|--group= + Output modules available in + -h|--human Output in human readable format. + -m|--machine Output in machine readable format " @@ -1018,7 +1023,7 @@ subcommand_avail() { local val='' while (($# > 0)); do case $1 in - -H | --help | -\? ) + -\? | -H | --help ) print_help "${subcommand}" ;; -a | --all | --all-release-stages ) @@ -1038,15 +1043,13 @@ subcommand_avail() { ;; -g | --group | --group=* ) if [[ $1 == --group=* ]]; then - val="${1/--group=}" + val="${1#--*=}" else val="$2" shift fi opt_groups[${val}]=1 ;; - '' ) - ;; -- ) shift 1 pattern+=( "$@" ) @@ -1092,7 +1095,7 @@ subcommand_avail() { # use [-a|--append|-p|--prepend] [directory|group|release_stage...] # Subcommands[use]='use' -Options[use]='-l help -o Hap -l append -l prepend' +Options[use]='-l help -o \?Hap -l append -l prepend' Help[use]=" USAGE: module use [-a|--append|-p|--prepend] [directory|group|release_stage|...] @@ -1232,7 +1235,7 @@ subcommand_use() { local -a args=() while (( $# > 0)); do case "$1" in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -a | --append ) @@ -1269,7 +1272,7 @@ subcommand_use() { # unuse directory|group|release_stage|... # Subcommands[unuse]='unuse' -Options[unuse]='-o H -l help' +Options[unuse]='-o \?H -l help' Help[unuse]=' unuse directory|group|release... Remove the given modulefiles directory, group, release stage, @@ -1346,7 +1349,7 @@ subcommand_unuse() { local -a args=() while (( $# > 0)); do case "$1" in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -1381,7 +1384,7 @@ subcommand_unuse() { # sub-command # Subcommands[update]='update' -Options[update]='-o H -l help' +Options[update]='-o \?H -l help' Help[update]=' USAGE: module update @@ -1397,7 +1400,7 @@ subcommand_update() { # refresh # Subcommands[refresh]='refresh' -Options[refresh]='-o H -l help' +Options[refresh]='-o \?H -l help' Help[refresh]=' USAGE: module refresh @@ -1488,7 +1491,7 @@ pmodules_init() { # purge # Subcommands[purge]='purge' -Options[purge]='-o H -l help' +Options[purge]='-o \?H -l help' Help[purge]=' USAGE: module purge @@ -1507,7 +1510,7 @@ subcommand_purge() { local -a args=() while (( $# > 0)); do case "$1" in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -1583,7 +1586,7 @@ subcommand_purge() { # list [-hlt] # Subcommands[list]='list' -Options[list]='-l help -o Hhlt -l human -l long -l terse' +Options[list]='-l help -o \?Hhlt -l human -l long -l terse' Help[list]=' USAGE: module list @@ -1596,7 +1599,7 @@ subcommand_list() { local args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -h | --human ) @@ -1633,7 +1636,7 @@ subcommand_list() { # clear # Subcommands[clear]='clear' -Options[clear]='-o H -l help' +Options[clear]='-o \?H -l help' Help[clear]=' USAGE: module clear @@ -1646,7 +1649,7 @@ subcommand_clear() { local -a args=() while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; -- ) @@ -1674,13 +1677,13 @@ subcommand_clear() { # search [switches] [STRING...] # Subcommands[search]='search' -Options[search]='-o aH -l help -l no-header -l print-modulefiles ' +Options[search]='-o a\?H -l help -l no-header -l print-modulefiles ' Options[search]+='-l release-stage: -l with: -l all-release-stages -l src: -l print-csv ' Options[search]+='-l verbose ' -Options[search]+='-l all-deps -l wrap' +Options[search]+='-l all-deps -l wrap ' Help[search]=' USAGE: - module search [switches] string... + module search [switches] STRING... Search installed modules. If an argument is given, search for modules whose name match the argument. @@ -2057,6 +2060,7 @@ USAGE: SWITCHES: -h|-H|-?|--help this usage info -V|--version modules version & configuration options + --debug enable debug output SUBCOMMANDS: + add|load [switches] modulefile [modulefile ...] @@ -2087,7 +2091,7 @@ subcommand_help() { local -a args=() while (( $# > 0 )); do case $1 in - -[hH] | --help ) + -\? | -h | -H | --help ) print_help "${subcommand}" ;; -V | --version ) @@ -2124,7 +2128,7 @@ subcommand_help() { # whatis # Subcommands[whatis]='whatis' -Options[whatis]='-o H -l help' +Options[whatis]='-o \?H -l help' Help[whatis]=' USAGE: module whatis [modulefile...] @@ -2147,7 +2151,7 @@ subcommand_whatis() { # Subcommands[apropos]='apropos' Subcommands[keyword]='apropos' -Options[apropos]='-o H -l help' +Options[apropos]='-o \?H -l help' Help[apropos]=' USAGE: module apropos string @@ -2165,7 +2169,7 @@ subcommand_apropos() { # initadd module... # Subcommands[initadd]='initadd' -Options[initadd]='-o H -l help' +Options[initadd]='-o \?H -l help' Help[initadd]=" USAGE: module initadd modulefile... @@ -2201,7 +2205,7 @@ subcommand_initadd() { # initprepend module... # Subcommands[initprepend]='initprepend' -Options[initprepend]='-o H -l help' +Options[initprepend]='-o \?H -l help' Help[initprepend]=" USAGE: module initprepend modulefile... @@ -2218,7 +2222,7 @@ subcommand_initprepend() { # initrm module... # Subcommands[initrm]='initrm' -Options[initrm]='-o H -l help' +Options[initrm]='-o \?H -l help' Help[initrm]=" USAGE: module initrm modulefile... @@ -2234,7 +2238,7 @@ subcommand_initrm() { # initswitch module1 module2 # Subcommands[initswitch]='initswitch' -Options[initswitch]='-o H -l help' +Options[initswitch]='-o \?H -l help' Help[initswitch]=" USAGE: module initswitch modulefile1 modulefile2 @@ -2247,7 +2251,7 @@ subcommand_initswitch() { local args=() while (( $# > 0 )); do case $1 in - -h | --help ) + -\? | --help ) print_help "${subcommand}" ;; -- ) @@ -2274,7 +2278,7 @@ subcommand_initswitch() { # initlist # Subcommands[initlist]='initlist' -Options[initlist]='-o H -l help' +Options[initlist]='-o \?H -l help' Help[initlist]=" USAGE: module initlist @@ -2291,7 +2295,7 @@ subcommand_initlist() { # initclear # Subcommands[initclear]='initclear' -Options[initclear]='-o H -l help' +Options[initclear]='-o \?H -l help' Help[initclear]=" USAGE: module initclear @@ -2323,7 +2327,7 @@ shift declare -a opts=() while (( $# > 0 )); do case $1 in - -H | -\? | --help | -help ) + -\? | -H | --help | -help ) print_help 'help' ;; -V | --version ) @@ -2422,11 +2426,12 @@ case ${subcommand} in ;; esac -declare options -options=$( "${getopt}" ${Options[${subcommand}]} -- "${opts[@]}" "$@" ) \ + +tmp=$("${getopt}" --name="${CMD}" ${Options[${subcommand}]} -- "${opts[@]}" "$@" ) \ || print_help "${subcommand}" -eval set -- ${options} -subcommand_${Subcommands[$subcommand]} "$@" +eval args=( "$tmp" ) +unset tmp +subcommand_${Subcommands[$subcommand]} "${args[@]}" # Local Variables: # mode: sh From 5f81fe32e93a56b496f87cd9774ef257a7f58746 Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 14:40:35 +0100 Subject: [PATCH 8/9] modulecmd: bugfix in saving state to PMODULES_ENV --- Pmodules/modulecmd.bash.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Pmodules/modulecmd.bash.in b/Pmodules/modulecmd.bash.in index 2bac638..b90b4a1 100644 --- a/Pmodules/modulecmd.bash.in +++ b/Pmodules/modulecmd.bash.in @@ -161,6 +161,7 @@ is_group () { local moduledir="${PMODULES_ROOT}/${group}/${PMODULES_MODULEFILES_DIR}" [[ -d "${moduledir}" ]] || return 1 compute_group_depth "${moduledir}" + g_env_must_be_saved='yes' } # @@ -1116,6 +1117,7 @@ subcommand_use() { fi if [[ -z ${GroupDepths[${arg}]} ]] && [[ -d "${PMODULES_ROOT}/${arg}" ]]; then scan_groups "${PMODULES_ROOT}" + g_env_must_be_saved='yes' fi if [[ -n ${GroupDepths[${arg}]} ]] && @@ -1965,6 +1967,7 @@ subcommand_search() { if (( ${#GroupDepths[@]} == 0 )) || \ [[ ${src_prefix} != ${PMODULES_ROOT} ]]; then scan_groups "${src_prefix}" + g_env_must_be_saved='yes' fi local module @@ -2340,6 +2343,7 @@ fi if (( ${#GroupDepths[@]} == 0 )); then scan_groups "${PMODULES_ROOT}" + g_env_must_be_saved='yes' fi case ${subcommand} in From 5815bc52017f8e330b8912534adef60fad37a83f Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 8 Nov 2021 14:43:46 +0100 Subject: [PATCH 9/9] modulecmd: shell glob pattern search implemented --- Pmodules/modulecmd.bash.in | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Pmodules/modulecmd.bash.in b/Pmodules/modulecmd.bash.in index b90b4a1..dc20928 100644 --- a/Pmodules/modulecmd.bash.in +++ b/Pmodules/modulecmd.bash.in @@ -789,7 +789,7 @@ get_available_modules() { fi done < <(${find} -L * \ \( -type f -o -type l \) -not -name ".*" \ - -ipath "${module}*" \ + -ipath "${module}" \ | ${sort} --version-sort) } done @@ -1008,7 +1008,7 @@ subcommand_avail() { fi get_available_modules \ mods \ - "${string}" \ + "${string}*" \ "${opt_use_rel_stages}" \ "${dir}" [[ ${#mods[@]} == 0 ]] && continue @@ -1609,6 +1609,7 @@ Options[search]='-o a\?H -l help -l no-header -l print-modulefiles ' Options[search]+='-l release-stage: -l with: -l all-release-stages -l src: -l print-csv ' Options[search]+='-l verbose ' Options[search]+='-l all-deps -l wrap ' +Options[search]+='-l glob' Help[search]=' USAGE: module search [switches] STRING... @@ -1622,6 +1623,9 @@ SWITCHES: --all-deps Show all dependecies + --glob + Interpret STRING as shell pattern. + --no-header Suppress output of a header. @@ -1659,6 +1663,7 @@ subcommand_search() { local opt_use_releases=':' local opt_all_deps='no' local opt_wrap='no' + local opt_glob='no' #..................................................................... # @@ -1797,7 +1802,12 @@ subcommand_search() { # :FIXME: # search () { - local -r module=$1 + if [[ ${opt_glob} == 'yes' ]]; then + local -r module="$1" + else + local -r module="${1}*" + fi + # write results to a temporary file for later processing local group # loop over all groups @@ -1860,7 +1870,7 @@ subcommand_search() { while (( $# > 0 )); do case $1 in - -H | --help ) + -\? | -H | --help ) print_help "${subcommand}" ;; --all-deps ) @@ -1940,6 +1950,9 @@ subcommand_search() { --wrap ) opt_wrap='yes' ;; + --glob ) + opt_glob='yes' + ;; -- ) shift 1 modules+=( "$@" )