Merge branch '41-cleanup' into 'master'

Resolve "cleanup"

Closes #41

See merge request Pmodules/src!12
This commit is contained in:
2019-05-24 16:56:36 +02:00
+329 -268
View File
@@ -22,6 +22,8 @@ declare -r getopt="${sbindir}/getopt"
source "${libdir}/libstd.bash"
source "${libdir}/libpmodules.bash"
: ${PMODULES_DEFINED_RELEASES:=':unstable:stable:deprecated:'}
declare -r version='@PMODULES_VERSION@'
if [[ ${PMODULES_PURETCL} == yes ]]; then
@@ -31,17 +33,12 @@ else
declare -r modulecmd="${libexecdir}/modulecmd.bin"
fi
# required for pre 0.99.3 modulefiles
declare -rx PSI_LIBMODULES="${TCLLIBPATH}/libmodules.tcl"
declare verbosity_lvl=${PMODULES_VERBOSITY:-'verbose'}
shopt -s nullglob
declare -A GroupDepths='()'
declare current_modulefile=''
declare g_shell=''
declare Shell=''
declare -A Subcommands
declare -A Options
declare -A Help
@@ -57,9 +54,7 @@ print_help() {
}
export_env() {
local -r shell="$1"
shift
case "${shell}" in
case "${Shell}" in
bash | zsh )
local -r fmt="export %s=\"%s\"; "
;;
@@ -67,7 +62,7 @@ export_env() {
local -r fmt="setenv %s \"%s\"; "
;;
* )
std::die 1 "Unsupported shell -- ${shell}\n"
std::die 1 "Unsupported shell -- ${Shell}\n"
;;
esac
@@ -77,24 +72,27 @@ export_env() {
done
}
#
# Save/cache some variables.
# This function is called on exit via a trap handler.
#
# Args;
# none
#
declare g_env_must_be_saved='no'
save_env() {
[[ ${g_env_must_be_saved} == 'no' ]] && return 0
local -r shell="$1"
shift
local s=''
local tmp
while (( $# > 0 )); do
tmp="$( typeset -p $1 2> /dev/null)"
[[ -n "${tmp}" ]] && s+="${tmp};"
shift
done
local vars=( GroupDepths UsedReleases UseFlags UsedGroups )
vars+=( PMODULES_DEFAULT_GROUPS PMODULES_DEFINED_RELEASES )
vars+=( PMODULES_DEFAULT_RELEASES )
local s=$(typeset -p ${vars[@]})
declare -g PMODULES_ENV=$( "${base64}" --wrap=0 <<< "$s" )
export_env ${shell} PMODULES_ENV
export_env 'PMODULES_ENV'
}
trap 'save_env ${g_shell} GroupDepths UsedReleases UseFlags UsedGroups PMODULES_DEFAULT_GROUPS PMODULES_DEFINED_RELEASES PMODULES_DEFAULT_RELEASES' EXIT
trap 'save_env ' EXIT
#
# get release of module
@@ -128,31 +126,23 @@ get_release() {
return 0
}
: ${PMODULES_DEFINED_RELEASES:=':unstable:stable:deprecated:'}
is_release() {
[[ ${PMODULES_DEFINED_RELEASES} =~ :$1: ]]
}
is_used_release() {
[[ ":${UsedReleases}:" =~ :$1: ]]
}
#
# Check whether argument is a group
#
# Args:
# $1: string
#
is_group () {
local -r group="$1"
# arg isn't emtpy and group already in cache
[[ -n ${group} ]] && [[ -n ${GroupDepths[${group}]} ]] && return 0
# not yet cached or not a group
get_group_depths "${PMODULES_ROOT}" "${group}"
}
is_used_group() {
[[ :${UsedGroups}: =~ :$1: ]]
}
module_is_loaded() {
[[ :${LOADEDMODULES}: =~ :$1: ]]
local moduledir="${PMODULES_ROOT}/${group}/${PMODULES_MODULEFILES_DIR}"
[[ -d "${moduledir}" ]] || return 1
compute_group_depth "${moduledir}"
}
#
@@ -184,10 +174,11 @@ subcommand_generic0() {
esac
done
if (( ${#args[@]} > 0 )); then
std::die 3 "%s %s: no arguments allowed\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"no arguments allowed"
fi
"${modulecmd}" "${g_shell}" "${subcommand}"
"${modulecmd}" "${Shell}" "${subcommand}"
}
subcommand_generic1() {
@@ -209,13 +200,15 @@ subcommand_generic1() {
shift
done
if (( ${#args[@]} == 0 )); then
std::die 3 "%s %s: missing argument\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"missing argument"
elif (( ${#args[@]} > 1 )); then
std::die 3 "%s %s: only one argument allowed\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"only one argument allowed"
fi
"${modulecmd}" "${g_shell}" "${subcommand}" "${args[@]}"
"${modulecmd}" "${Shell}" "${subcommand}" "${args[@]}"
}
subcommand_generic1plus() {
@@ -237,10 +230,11 @@ subcommand_generic1plus() {
shift
done
if (( ${#args[@]} == 0 )); then
std::die 3 "%s %s: missing argument\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"missing argument"
fi
"${modulecmd}" "${g_shell}" "${subcommand}" "${args[@]}"
"${modulecmd}" "${Shell}" "${subcommand}" "${args[@]}"
}
##############################################################################
@@ -290,7 +284,8 @@ subcommand_load() {
# - specified with name only (without version, like gcc).
# The module can be either in- or outside our hierarchy.
#
# - directory in- or outsite our hierarchy (not supported by modulecmd.tcl!)
# - directory in- or outsite our hierarchy (not supported by
# modulecmd.tcl!)
#
# arguments:
# $1: module name or file
@@ -316,7 +311,7 @@ subcommand_load() {
# setenv FOO_PREFIX bar
# can be used.
#
mapfile -t array < <("${modulecmd}" "${shell}" show "$m" 2>&1 | \
mapfile -t array < <("${modulecmd}" 'bash' show "$m" 2>&1 | \
awk 'NR == 2 {print substr($0, 1, length($0)-1)}; /_PREFIX |_HOME / {print $3; exit}')
current_modulefile="${array[0]}"
prefix="${array[1]}"
@@ -349,21 +344,28 @@ subcommand_load() {
fi
}
module_is_loaded() {
[[ :${LOADEDMODULES}: =~ :$1: ]]
}
load_dependencies() {
local -r fname="$1"
while read dep; do
[[ -z ${dep} ]] && continue
[[ ${dep:0:1} == \# ]] && continue
module_is_loaded "${dep}" && continue
local output=$( subcommand_load --internal "${dep}")
echo ${output}
local output=$( subcommand_load 'bash' "${dep}")
eval ${output}
if [[ "${Shell}" == "bash" ]]; then
echo ${output}
else
subcommand_load "${Shell}" "${dep}"
fi
done < "${fname}"
}
local args=()
opts=()
local shell="${g_shell}"
while (($# > 0)); do
case $1 in
-H | --help )
@@ -381,9 +383,6 @@ subcommand_load() {
-w | --warn )
verbosity_lvl='warn'
;;
-i | --internal )
shell='bash'
;;
-- )
;;
* )
@@ -393,7 +392,9 @@ subcommand_load() {
shift
done
if (( ${#args[@]} == 0 )); then
std::die 2 "${CMD} load: No module specified\n"
std::die 2 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"No module specified"
fi
for m in "${args[@]}"; do
if [[ "$m" =~ ":" ]]; then
@@ -436,19 +437,26 @@ subcommand_load() {
fi
if [[ -n ${group} ]]; then
is_group "${group}" || \
std::die 3 "%s %s: illegal group name -- %s\n" \
"${CMD}" 'load' "${group}"
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal group name" \
"${group}"
local -i depth=${GroupDepths[${group}]}
(( depth != 0 )) && \
std::die 3 "%s %s: illegal group name -- %s\n" \
"${CMD}" 'load' "${group}"
MODULEPATH="${PMODULES_ROOT}/${group}/${PMODULES_MODULEFILES_DIR}"
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal group name" \
"${group}"
MODULEPATH="${PMODULES_ROOT}/${group}/"
MODULEPATH+="${PMODULES_MODULEFILES_DIR}"
modulepath=( ${MODULEPATH} )
fi
if [[ -n ${release} ]]; then
is_release "${release}" || \
std::die 3 "%s %s: illegal release name -- %s\n" \
"${CMD}" 'load' "${release}"
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal release name"
"${release}"
std::append_path UsedReleases "${release}"
g_env_must_be_saved='yes'
fi
@@ -468,8 +476,10 @@ subcommand_load() {
std::die 3 ""
fi
if [[ ":${LOADEDMODULES}:" =~ ":${m}:" ]]; then
std::die 3 "%s %s: module conflicts with already loaded module -- %s\n" \
"${CMD}" 'load' "${m}"
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"module conflicts with already loaded module" \
"${m}"
fi
if [[ ${current_modulefile} =~ ${PMODULES_ROOT} ]]; then
# modulefile is in our hierarchy
@@ -479,15 +489,16 @@ subcommand_load() {
fi
local tmpfile=$( "${mktemp}" /tmp/Pmodules.XXXXXX ) \
|| std::die 1 "Oops: unable to create tmp file!\n"
local output=$("${modulecmd}" "${shell}" ${opts} 'load' "${current_modulefile}" 2> "${tmpfile}")
echo "${output}"
local output=$("${modulecmd}" 'bash' ${opts} 'load' \
"${current_modulefile}" 2> "${tmpfile}")
eval "${output}"
# we do not want to print the error message we got from
# modulecmd, they are a bit ugly
# :FIXME: Not sure whether this is now correct!
# The idea is to supress the error messages from the Tcl modulecmd, but not
# the output to stderr coded in a modulefile.
# The idea is to supress the error messages from the Tcl
# modulecmd, but not the output to stderr coded in a
# modulefile.
local error=$( < "${tmpfile}")
if [[ "${error}" =~ ":ERROR:" ]]; then
@@ -497,13 +508,24 @@ subcommand_load() {
error_txt='conflicts with already loaded modules'
fi
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" 'load' "${error_txt}" "${m}"
elif [[ -n ${error} ]]; then
echo "${error}" 1>&2
fi
if [[ ${verbosity_lvl} != silent ]] && [[ ${release} != stable ]]; then
std::info "%s %s: a %s module has been loaded -- %s\n" \
"${CMD}" 'load' ${release} "${m}"
"${CMD}" "${subcommand}" \
"${error_txt}" \
"${m}"
fi
if [[ "${Shell}" == "bash" ]]; then
echo "${output}"
echo "${error}"
else
"${modulecmd}" "${Shell}" ${opts} 'load' \
"${current_modulefile}"
fi
if [[ ${verbosity_lvl} != silent ]] && \
[[ ${release} != stable ]]; then
std::info "%s %s: %s -- %s\n" \
"${CMD}" 'load' \
"${release} module has been loaded" \
"${m}"
fi
done
# fix LOADEDMODULES
@@ -513,7 +535,7 @@ subcommand_load() {
[[ "${dir: -1}" == "/" ]] || dir+="/"
LOADEDMODULES="${LOADEDMODULES//${dir}}"
done <<< "${MODULEPATH//:/$'\n'}"
export_env "${g_shell}" LOADEDMODULES
export_env 'LOADEDMODULES'
}
##############################################################################
@@ -534,10 +556,10 @@ USAGE:
subcommand_unload() {
local -r subcommand='unload'
# :FIXME: add dependency tests: don't unload if module is required be
# another module.
# For the time being the modules requiring this module will be
# unloaded too.
# :FIXME: add dependency tests: don't unload if module is required
# be another module.
# For the time being the modules requiring this module will
# be unloaded too.
local args=()
while (( $# > 0 )); do
case $1 in
@@ -553,15 +575,20 @@ subcommand_unload() {
shift
done
if (( ${#args[@]} == 0 )); then
std::die 3 "%s %s: missing argument\n" \
"${CMD}" 'unload'
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"missing argument"
fi
local arg
for arg in "${args[@]}"; do
local output=$("${modulecmd}" "${g_shell}" 'unload' "${arg}")
echo "${output}"
local output=$("${modulecmd}" "${Shell}" 'unload' "${arg}")
eval "${output}"
if [[ "${Shell}" == "bash" ]]; then
echo "${output}"
else
"${modulecmd}" "${Shell}" 'unload' "${arg}"
fi
done
}
@@ -598,11 +625,13 @@ subcommand_swap() {
shift
done
if (( ${#args[@]} == 0 )); then
std::die 3 "%s %s: missing argument\n" \
"${CMD}" 'swap'
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"missing argument"
elif (( ${#args[@]} > 2 )); then
std::die 3 "%s %s: too many arguments\n" \
"${CMD}" 'swap'
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"too many arguments"
fi
if (( ${#args[@]} == 1 )); then
local -r module_to_load=${args[0]}
@@ -650,13 +679,14 @@ subcommand_show() {
shift
done
if (( ${#args[@]} == 0 )); then
std::die 3 "%s %s: missing argument\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"missing argument"
fi
local arg
for arg in "${args[@]}"; do
"${modulecmd}" "${g_shell}" "${subcommand}" "${arg}"
"${modulecmd}" "${Shell}" "${subcommand}" "${arg}"
done
}
@@ -868,7 +898,9 @@ subcommand_avail() {
local string
for string in "${pattern[@]}"; do
for dir in "${modulepath[@]}"; do
mods=( $( get_available_modules "${dir}" "${string}" "${opt_use_releases}" ) )
mods=( $( get_available_modules \
"${dir}" "${string}" \
"${opt_use_releases}" ) )
[[ ${#mods[@]} == 0 ]] && continue
${output_function}
done
@@ -876,58 +908,48 @@ subcommand_avail() {
}
#
# compute depths of group passed as argument
# Note: cwd must be Pmodules root directory
# $1: group
# compute depth of modulefile directory.
#
get_group_depth () {
local -r group="$1"
local -r dir="${group}/${PMODULES_MODULEFILES_DIR}"
# Args:
# $1: absolute path of a modulefile directory
#
compute_group_depth () {
local -r dir=$1
test -d "${dir}" || return 1
local tmp=$(find "${dir}" -depth -type f -o -type l 2>/dev/null| head -1)
local -a tmp2=( ${tmp//\// } )
local depth=${#tmp2[@]}
(( depth-=4 ))
# if a group doesn't contain a module yet, depth would be -4
# instead of 0
local group=${dir%/*}
local group=${group##*/}
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 == -4 )) && (( depth = 0 ))
(( depth < 0 )) && (( depth = 0 ))
GroupDepths[$group]=${depth}
g_env_must_be_saved='yes'
}
#
# Compute depth for all known groups
# $1: root of modulefile hierarchy
get_group_depths () {
# (Re-)Scan available groups in given root and compute group depth's
#
# Args:
# $1: root of modulefile hierarchy
#
scan_groups () {
local -r root="$1"
{
cd "${root}"
local group
for group in [ABCDEFGHIJKLMNOPQRSTUVWXYZ]*; do
get_group_depth "${group}"
done
};
local moduledir
for moduledir in ${root}/*/${PMODULES_MODULEFILES_DIR}; do
compute_group_depth "${moduledir}"
done
}
# re-scan available groups.
#
# Note:
# Removing groups is not supported for the time being. Be aware, that
# a user might have a module loaded from this group. This cannot be checked.
#
# $1: root of modulefile hierarchy
rescan_groups() {
local -r root="$1"
{
cd "${root}"
# for some unknown reason [A-Z]* doesn't work with some bash versions
for group in [ABCDEFGHIJKLMNOPQRSTUVWXYZ]*; do
if [[ -z "${GroupDepths[${group}]}" ]]; then
get_group_depth "${group}"
fi
done
};
local moduledir
for moduledir in ${root}/*/${PMODULES_MODULEFILES_DIR}; do
if [[ -z "${GroupDepths[${group}]}" ]]; then
compute_group_depth "${moduledir}"
fi
done
}
##############################################################################
@@ -968,6 +990,14 @@ subcommand_use() {
IFS=${saved_IFS}
local add2path_func='std::append_path'
group_is_used() {
[[ :${UsedGroups}: =~ :$1: ]]
}
release_is_used() {
[[ ":${UsedReleases}:" =~ :$1: ]]
}
print_info() {
local f
local r
@@ -979,7 +1009,7 @@ subcommand_use() {
local _group
for _group in "${!GroupDepths[@]}"; do
local -i depth=${GroupDepths[${_group}]}
if ! is_used_group "${_group}" && (( depth == 0 )); then
if ! group_is_used "${_group}" && (( depth == 0 )); then
std::info "\t${_group}\n"
fi
done
@@ -990,7 +1020,7 @@ subcommand_use() {
done
std::info "\nUnused releases:\n"
for r in ${PMODULES_DEFINED_RELEASES//:/ }; do
if ! is_used_release $r; then
if ! release_is_used $r; then
std::info "\t${r}\n"
fi
done
@@ -1015,56 +1045,56 @@ subcommand_use() {
}
use () {
while (( $# > 0)); do
local arg="$1"
# if is release
# ...
# elif is group
# ...
# elif matches modulepath root
# ...
# elif is directory
# ...
# else
# error
#
local modulefiles_dir="${PMODULES_ROOT}/${arg}/${PMODULES_MODULEFILES_DIR}"
if is_release "${arg}"; then
# releases are always *appended*
std::append_path UsedReleases "${arg}"
local arg=$1
elif [[ "${arg}" =~ "flag=" ]]; then
std::append_path UseFlags "${arg/flag=}"
if is_release "${arg}"; then
# argument is release
std::append_path UsedReleases "${arg}"
return
fi
if [[ "${arg}" =~ "flag=" ]]; then
# argument is flag
std::append_path UseFlags "${arg/flag=}"
return
fi
if [[ -n ${GroupDepths[${arg}]} ]] &&
(( ${GroupDepths[${arg}]} == 0 )); then
# argument is group in our root with depth 0
std::append_path UsedGroups "${arg}"
local dir="${PMODULES_ROOT}/${arg}/"
dir+="${PMODULES_MODULEFILES_DIR}"
${add2path_func} MODULEPATH "${dir}"
return
fi
if [[ -n ${GroupDepths[${arg}]} ]] &&
(( ${GroupDepths[${arg}]} > 0 )); then
# argument is a hierarchical group in our root
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal group" \
"${arg}"
return
fi
# arg must be a directory!
if [[ ! -d ${arg} ]]; then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal argument" \
"${arg}"
return
fi
elif [[ ! ${arg} =~ */* ]] && [[ -d ${modulefiles_dir} ]]; then
if (( ${GroupDepths[$arg]} != 0 )); then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"cannot add group to module path" \
"${arg}"
fi
std::append_path UsedGroups "${arg}"
${add2path_func} MODULEPATH "${modulefiles_dir}"
elif [[ ${arg} =~ ^${PMODULES_ROOT} ]]; then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal directory" \
"${arg}"
elif [[ -d ${arg} ]]; then
${add2path_func} MODULEPATH "$(cd "${arg}" && pwd)"
else
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"neither a directory, release or group" \
"${arg}"
fi
shift
done
g_env_must_be_saved='yes'
export_env ${g_shell} 'MODULEPATH'
dir="$(cd "${arg}" && pwd)"
if [[ ${dir} =~ ^${PMODULES_ROOT} ]]; then
# argument is somehing in our root
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal argument" \
"${arg}"
return
fi
# argument is a modulepath
${add2path_func} MODULEPATH "$(cd "${arg}" && pwd)"
}
local -a args=()
@@ -1090,9 +1120,13 @@ subcommand_use() {
if (( ${#args[@]} == 0 )); then
print_info
else
use "${args[@]}"
fi
return
fi
for arg in "${args[@]}"; do
use "${arg}"
done
g_env_must_be_saved='yes'
export_env 'MODULEPATH'
}
##############################################################################
@@ -1110,59 +1144,64 @@ unuse directory|group|release...
subcommand_unuse() {
local -r subcommand='unuse'
unuse() {
while (( $# > 0 )); do
local arg=$1
local modulefiles_dir="${PMODULES_ROOT}/${arg}/${PMODULES_MODULEFILES_DIR}"
if is_release "${arg}"; then
# argument is release
std::remove_path UsedReleases "${arg}"
local arg=$1
elif [[ "${arg}" =~ "flag=" ]]; then
# argument is flag
std::remove_path UseFlags "${arg/flag=}"
elif [[ ! ${arg} =~ */* ]] && [[ -d ${modulefiles_dir} ]]; then
# argument is group
if (( ${GroupDepths[$arg]} != 0 )); then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"cannot remove group" \
"${arg}"
fi
local var="PMODULES_LOADED_${arg^^}"
if [[ -n "${!var}" ]]; then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"cannot remove group due to loaded modules" \
"${arg}"
fi
std::remove_path UsedGroups "${arg}"
std::remove_path MODULEPATH "${modulefiles_dir}"
elif [[ -d ${arg} ]]; then
# argument is a modulepath
local normalized_dir=$(cd "${arg}" && pwd)
std::remove_path MODULEPATH "${normalized_dir}"
elif [[ ${arg} =~ ^${PMODULES_ROOT} ]]; then
# argument looks like a group in our root
std::die 3 "%s %s: %s -- %s\n." \
if is_release "${arg}"; then
# argument is release
std::remove_path UsedReleases "${arg}"
return
fi
if [[ "${arg}" =~ "flag=" ]]; then
# argument is flag
std::remove_path UseFlags "${arg/flag=}"
return
fi
if [[ -n ${GroupDepths[${arg}]} ]] &&
(( ${GroupDepths[${arg}]} == 0 )); then
# argument is group in our root with depth 0
local var="PMODULES_LOADED_${arg^^}"
if [[ -n "${!var}" ]]; then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal directory" \
"cannot remove group due to loaded modules" \
"${arg}"
fi
std::remove_path UsedGroups "${arg}"
local dir="${PMODULES_ROOT}/${arg}/"
dir+="${PMODULES_MODULEFILES_DIR}"
std::remove_path MODULEPATH "${dir}"
return
fi
if [[ -n ${GroupDepths[${arg}]} ]] &&
(( ${GroupDepths[${arg}]} > 0 )); then
# argument is a hierarchical group in our root
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal group" \
"${arg}"
return
fi
# arg must be a directory!
if [[ ! -d ${arg} ]]; then
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal argument" \
"${arg}"
return
fi
else
# oops
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"not a valid argument" \
"${arg}"
dir="$(cd "${arg}" && pwd)"
if [[ ${dir} =~ ^${PMODULES_ROOT} ]]; then
# argument is somehing in our root
std::die 3 "%s %s: %s -- %s\n" \
"${CMD}" "${subcommand}" \
"illegal argument" \
"${arg}"
return
fi
# argument is a modulepath
std::remove_path MODULEPATH "${dir}"
fi
shift
done
g_env_must_be_saved='yes'
export_env "${g_shell}" 'MODULEPATH'
}
local -a args=()
@@ -1184,14 +1223,20 @@ subcommand_unuse() {
"${CMD}" "${subcommand}" \
'missing argument'
fi
unuse "${args[@]}"
for arg in "${args[@]}"; do
unuse "${args[@]}"
done
g_env_must_be_saved='yes'
export_env 'MODULEPATH'
}
##############################################################################
#
# update
#
# :FIXME: either compile Modules with --enable-beginenv or remove the sub-command
# :FIXME:
# either compile Modules with --enable-beginenv or remove the
# sub-command
#
Subcommands[update]='update'
Options[update]='-o H -l help'
@@ -1288,7 +1333,7 @@ pmodules_init() {
reset_used_releases
init_path
init_manpath
export_env "${g_shell}" \
export_env \
LOADEDMODULES \
_LMFILES_ \
MODULEPATH \
@@ -1325,13 +1370,14 @@ subcommand_purge() {
shift
done
if (( ${#args[@]} > 0 )); then
std::die 3 "%s %s: no arguments allowd\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"no arguments allowd"
fi
"${modulecmd}" "${g_shell}" "${subcommand}"
"${modulecmd}" "${Shell}" "${subcommand}"
reset_modulepath
reset_used_groups
export_env ${g_shell} MODULEPATH
export_env MODULEPATH
}
##############################################################################
@@ -1373,10 +1419,11 @@ subcommand_list() {
shift
done
if (( ${#args[@]} > 0 )); then
std::die 3 "%s %s: no arguments allowd\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"no arguments allowd"
fi
"${modulecmd}" "${g_shell}" list "${opts[@]}"
"${modulecmd}" "${Shell}" list "${opts[@]}"
}
@@ -1411,11 +1458,12 @@ subcommand_clear() {
shift
done
if (( ${#args[@]} > 0 )); then
std::die 3 "%s %s: no arguments allowed\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"no arguments allowed"
fi
pmodules_init
export_env ${g_shell} LOADEDMODULES MODULEPATH _LMFILES_
export_env LOADEDMODULES MODULEPATH _LMFILES_
}
##############################################################################
@@ -1496,13 +1544,16 @@ subcommand_search() {
done
out+="${line[0]}"
std::info "${out}\n"
done < <("${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | awk "${with_modules}")
done < <("${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | \
awk "${with_modules}")
elif [[ "${opt_print_csv}" == "yes" ]]; then
while read -a toks; do
:
done < <("${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | awk "${with_modules}")
done < <("${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | \
awk "${with_modules}")
else
"${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | awk "${with_modules}" 1>&2
"${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | \
awk "${with_modules}" 1>&2
fi
}
#.....................................................................
@@ -1544,7 +1595,8 @@ subcommand_search() {
# get and print all available modules in $mpath
# with respect to the requested releases
# tmpfile: module/version release group group-dependencies...
# tmpfile: module/version release group group-
# dependencies...
local mods=( $( get_available_modules \
"${mpath}" \
"${module}" \
@@ -1584,8 +1636,10 @@ subcommand_search() {
local arg=${1/--release=}
fi
is_release "${arg}" || \
std::die 1 "%s %s: illegal release name -- %s\n" \
"${CMD}" 'search' "${arg}"
std::die 1 "%s %s: %s -- %s\n" \
"${CMD}" 'search' \
"illegal release name" \
"${arg}"
opt_use_releases+="${arg}:"
;;
--with | --with=* )
@@ -1596,8 +1650,10 @@ subcommand_search() {
local arg=${1/--with=}
fi
if [[ -z ${arg} ]] || [[ "${arg}" =~ "-*" ]]; then
std::die 1 "%s %s: illegal value for --with option -- %s\n" \
"${CMD}" 'search' "${arg}"
std::die 1 "%s %s: %s -- %s\n" \
"${CMD}" 'search' \
"illegal value for --with option" \
"${arg}"
fi
arg=${arg//:/ }
arg=${arg//,/ }
@@ -1633,8 +1689,9 @@ subcommand_search() {
modules+=( '' )
fi
if (( ${#GroupDepths[@]} == 0 )) || [[ ${src_prefix} != ${PMODULES_ROOT} ]]; then
get_group_depths "${src_prefix}"
if (( ${#GroupDepths[@]} == 0 )) || \
[[ ${src_prefix} != ${PMODULES_ROOT} ]]; then
scan_groups "${src_prefix}"
fi
local module
@@ -1711,7 +1768,7 @@ subcommand_help() {
else
# :FIXME: print help of newest *available* module
# (respecting UsedReleases)
"${modulecmd}" "${g_shell}" "${subcommand}" "${arg}"
"${modulecmd}" "${Shell}" "${subcommand}" "${arg}"
fi
done
}
@@ -1835,7 +1892,8 @@ Options[initswitch]='-o H -l help'
Help[initswitch]="
USAGE:
module initswitch modulefile1 modulefile2
Switch modulefile1 with modulefile2 in the shell's initialization files.
Switch modulefile1 with modulefile2 in the shell's
initialization files.
"
subcommand_initswitch() {
@@ -1856,10 +1914,11 @@ subcommand_initswitch() {
shift
done
if (( ${#args[@]} != 2 )); then
std::die 3 "%s %s: two arguments required not less not more\n" \
"${CMD}" "${subcommand}"
std::die 3 "%s %s: %s\n" \
"${CMD}" "${subcommand}" \
"two arguments required not less not more"
fi
"${modulecmd}" "${g_shell}" "${subcommand}" "${args[@]}"
"${modulecmd}" "${Shell}" "${subcommand}" "${args[@]}"
}
##############################################################################
@@ -1871,7 +1930,8 @@ Options[initlist]='-o H -l help'
Help[initlist]="
USAGE:
module initlist
List all of the modulefiles loaded from the shell's initialization file.
List all of the modulefiles loaded from the shell's
initialization file.
"
subcommand_initlist() {
@@ -1887,7 +1947,8 @@ Options[initclear]='-o H -l help'
Help[initclear]="
USAGE:
module initclear
Clear all of the modulefiles from the shell's initialization files.
Clear all of the modulefiles from the shell's
initialization files.
"
subcommand_initclear() {
@@ -1900,10 +1961,10 @@ subcommand_initclear() {
#
case "$1" in
bash | zsh )
declare g_shell="$1"
declare Shell="$1"
;;
csh | tcsh )
declare g_shell='csh'
declare Shell='csh'
;;
* )
std::die 1 "${CMD}: unsupported shell -- $1\n"
@@ -1952,7 +2013,7 @@ else
fi
if (( ${#GroupDepths[@]} == 0 )); then
get_group_depths "${PMODULES_ROOT}"
scan_groups "${PMODULES_ROOT}"
fi
declare options