diff --git a/Pmodules/modulecmd.bash.in.overlays b/Pmodules/modulecmd.bash.in.overlays deleted file mode 100644 index e2c0132..0000000 --- a/Pmodules/modulecmd.bash.in.overlays +++ /dev/null @@ -1,2087 +0,0 @@ -#!@PMODULES_HOME@/sbin/bash --noprofile -# - -#set -o nounset -# we have to unset CDPATH, otherwise 'cd' prints the directoy! -unset CDPATH - -# used for some output only -declare -r CMD='module' - -declare -r mydir=$(cd $(dirname "$0") && pwd) -declare prefix=$(dirname "${mydir}") -declare -r sbindir="${prefix}/sbin" -declare -r libdir="${prefix}/lib" -declare -r libexecdir="${prefix}/libexec" - -declare -r base64="${sbindir}/base64" -declare -r mktemp="${sbindir}/mktemp" -declare -r sort="${sbindir}/sort" -declare -r getopt="${sbindir}/getopt" - -source "${libdir}/libstd.bash" -source "${libdir}/libpmodules.bash" - -declare -r version='@PMODULES_VERSION@' - -if [[ ${PMODULES_PURETCL} == yes ]]; then - declare -r modulecmd="${libexecdir}/modulecmd.tcl" -else - declare -rx TCLLIBPATH="${PMODULES_HOME}/lib/Pmodules" - 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 -A Subcommands -declare -A Options -declare -A Help - -Help['version']=" -Pmodules ${version} using Tcl Environment Modules @MODULES_VERSION@ -Copyright GNU GPL v2 -" - -print_help() { - echo -e "${Help[$1]}" 1>&2 - std::die 1 -} - -export_env() { - local -r shell="$1" - shift - case "${shell}" in - bash | zsh ) - local -r fmt="export %s=\"%s\"; " - ;; - csh | tcsh ) - local -r fmt="setenv %s \"%s\"; " - ;; - * ) - std::die 1 "Unsupported shell -- ${shell}\n" - ;; - esac - - while (( $# > 0 )); do - printf "${fmt}" "$1" "${!1}" - shift - done -} - -save_env() { - 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 - declare -g PMODULES_ENV=$( "${base64}" --wrap=0 <<< "$s" ) - export_env ${shell} PMODULES_ENV -} - -trap 'save_env ${g_shell} GroupDepths UsedReleases UseFlags UsedGroups PMODULES_DEFAULT_GROUPS PMODULES_DEFINED_RELEASES PMODULES_DEFAULT_RELEASES' EXIT - -# -# get release of module -# Note: -# - the release of a module outside ${Overlays[@]} is always 'stable' -# - the release of a module inside ${Overlays[@]} without a -# coresponding release file is always 'unstable' -# -# Args: -# $1 upvar for returned release -# $2 absolute modulefile name -# $3 colon seperated list of accepted releases -# -get_release() { - local "$1" - local -r modulefile=$2 - local -r releases=$3 - - # is modulefile in a used overlay? - for root in "${!Overlays[@]}" 'ZZZZZZZ'; do - [[ ${modulefile} =~ ${root} ]] && break - done - if [[ "${root}" == 'ZZZZZZZ' ]]; then - std::upvar $1 'stable' - return 0 - fi - - # we are inside the used overlays - local -r releasefile="${modulefile%/*}/.release-${modulefile##*/}" - if [[ -r ${releasefile} ]]; then - # read releasefile, remove empty lines, spaces etc - local -r data=$( < "${releasefile}" ) - std::upvar $1 "${data}" - else - std::upvar $1 'unstable' - fi - [[ :${releases}: =~ ${release} ]] -} - -: ${PMODULES_DEFINED_RELEASES:=':unstable:stable:deprecated:'} - -is_release() { - [[ ${PMODULES_DEFINED_RELEASES} =~ :$1: ]] -} - -is_used_release() { - [[ ":${UsedReleases}:" =~ :$1: ]] -} - -get_overlay_of_group () { - local "$1" - local -r group="$2" - for overlay in "${!Overlays[@]}"; do - if [[ -d "${overlay}/${group}/${PMODULES_MODULEFILES_DIR}" ]]; then - std::upvar $1 "${overlay}" - return 0 - fi - done - return 1 -} - -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 - local overlay='' - get_overlay_of_group overlay "${group}" || return 1 - get_group_depths "${overlay}" "${group}" -} - -# -# Check whether a given path is in an overlay. -# If yes, return 0 and the overlay with upvar of first argument -# otherwise return 1 -# -# $1 upvar to return overlay -# $2 upvar to return group -# $3 path to check -# -find_overlay () { - local "$1" - local "$2" - local -r path=$3 - for overlay in "${!Overlays[@]}"; do - if [[ "${path}" =~ "${overlay}" ]]; then - std::upvar $1 "${overlay}" - local group="${path#${overlay}/}" - group=${group%%/*} - std::upvar $2 "${group}" - return 0 - fi - done - return 1 -} - -is_used_group() { - [[ :${UsedGroups}: =~ :$1: ]] -} - -module_is_loaded() { - [[ :${LOADEDMODULES}: =~ :$1: ]] -} - -# -# check shebang -# $1: file name to test -is_modulefile() { - local -r fname="$1" - local shebang - [[ -r ${fname} ]] || return 1 - read -n 11 shebang < "${fname}" - [[ "${shebang:0:8}" == '#%Module' ]] || [[ "${shebang:0:9}" == '#%Pmodule' ]] -} - -subcommand_generic0() { - local -r subcommand="$1" - shift - local -a args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - : - ;; - * ) - args+=( "$1" ) - ;; - esac - done - if (( ${#args[@]} > 0 )); then - std::die 3 "%s %s: no arguments allowed\n" \ - "${CMD}" "${subcommand}" - fi - "${modulecmd}" "${g_shell}" "${subcommand}" -} - -subcommand_generic1() { - local -r subcommand="$1" - shift - local -a args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - : - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 3 "%s %s: missing argument\n" \ - "${CMD}" "${subcommand}" - elif (( ${#args[@]} > 1 )); then - std::die 3 "%s %s: only one argument allowed\n" \ - "${CMD}" "${subcommand}" - fi - "${modulecmd}" "${g_shell}" "${subcommand}" "${args[@]}" -} - -subcommand_generic1plus() { - local -r subcommand="$1" - shift - local args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - : - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 3 "%s %s: missing argument\n" \ - "${CMD}" "${subcommand}" - fi - "${modulecmd}" "${g_shell}" "${subcommand}" "${args[@]}" -} - -############################################################################## -# -# load [-fsvw] -# -# $1: module to load -# -Subcommands[add]='load' -Subcommands[load]='load' -Options['load']='-l help -o Hfsvwi -l force -l silent -l verbose -l warn -l internal' -Help[load]=' -USAGE: - module add modulefile... - module load modulefile... - Load modulefile(s) into the shell environment. Loading a - 'group-head' will extend the MODULEPATH. E.g.: loading a - compiler makes additional modules like openmpi and libraries - compiled with this compiler available. -' - -subcommand_load() { - local -r subcommand='load' - local release='undef' - local current_modulefile='' - local prefix='' - local m='' - - local saved_IFS="${IFS}"; - IFS=':' - local -a modulepath=(${MODULEPATH}) - IFS=${saved_IFS} - - # - # Test whether a given module is available. - # The passed module-name can be - # - # - an absolute file- or link-name. - # The module can be either in- or outside our hierarchy. - # - # - a relative file- or link-name. - # The module can be either in- or outside out hierarchy. - # - # - specified with name and version (like gcc/5.2.0). - # The module can be either in- or outside our hierarchy. - # - # - 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!) - # - # arguments: - # $1: module name or file - # - # possible return values: - # 0: module is loadable - # 1: either not a modulefile or unsused release - # - # Notes: - # The variable 'release' in function 'subcommand_load()' will be set. - # - is_available() { - local m=$1 - local -a array - # - # the next command assigns the absolute modulefile path - # to ${arry[0]} and - if the module is in our root - the - # prefix of the module to ${array[1]}. - # - # The trick with the first line matching "_PREFIX" is not - # 100% reliable: One of the Pmodules extensions must be - # called before something like - # setenv FOO_PREFIX bar - # can be used. - # - mapfile -t array < <("${modulecmd}" "${shell}" 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]}" - test -n "${current_modulefile}" || return 1 - get_release release "${current_modulefile}" "${UsedReleases}" - } - - # - # output load 'hints' - # - # Note: - # The variable 'm' from the parent function will be used - # but not changed. - # - # Args: - # none - output_load_hints() { - local output='' - local release='' - while read -a line; do - release=${line[1]} - if [[ ! ":${UsedReleases}:" =~ "${release}" ]]; then - output+="module use ${release}; " - fi - output+="module load ${line[@]:3} ${line[0]}\n" - done < <(subcommand_search "${m}" -a --no-header 2>&1) - if [[ -n "${output}" ]]; then - std::info "\nTry with one of the following command(s):\n" - std::die 3 "${output}\n" - fi - } - - 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} - eval ${output} - done < "${fname}" - } - - local args=() - opts=() - local shell="${g_shell}" - while (($# > 0)); do - case $1 in - -H | --help ) - print_help "${subcommand_load}" - ;; - -f | --force ) - opts+=(' -f') - ;; - -s | --silent ) - verbosity_lvl='silent' - ;; - -v | --verbose ) - verbosity_lvl='verbose' - ;; - -w | --warn ) - verbosity_lvl='warn' - ;; - -i | --internal ) - shell='bash' - ;; - -- ) - ;; - * ) - args+=( $1 ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 2 "${CMD} load: No module specified\n" - fi - for m in "${args[@]}"; do - if [[ "$m" =~ ":" ]]; then - - # $m is an extendet module - # the format is one of - # - group:name - # - group:name:release - # - release:name - # - release:group:name - # - name:release - - local save_ifs=${IFS} - IFS=':' - local -a toks=($m) - IFS=${save_ifs} - local group='' - local release='' - if is_group "${toks[0]}"; then - group=${toks[0]} - m=${toks[1]} - release=${toks[2]} - elif is_release "${toks[0]}"; then - release=${toks[0]} - if is_group "${toks[1]}"; then - group=${toks[1]} - m=${toks[2]} - else - m=${toks[1]} - group=${toks[2]} - fi - else - m=${toks[0]} - if is_group "${toks[1]}"; then - group=${toks[1]} - release=${toks[2]} - else - release=${toks[1]} - group=${toks[2]} - fi - fi - if [[ -n ${group} ]]; then - is_group "${group}" || \ - std::die 3 "%s %s: illegal group name -- %s\n" \ - "${CMD}" 'load' "${group}" - local -i depth=${GroupDepths[${group}]} - (( depth != 0 )) && \ - std::die 3 "%s %s: illegal group name -- %s\n" \ - "${CMD}" 'load' "${group}" - MODULEPATH="" - modulepath=() - for root in "${!Overlays[@]}"; do - MODULEPATH+="${root}/${group}/${PMODULES_MODULEFILES_DIR}:" - modulepath+=( ${MODULEPATH} ) - done - fi - if [[ -n ${release} ]]; then - is_release "${release}" || \ - std::die 3 "%s %s: illegal release name -- %s\n" \ - "${CMD}" 'load' "${release}" - std::append_path UsedReleases "${release}" - fi - fi - local found='' - for flag in "${UseFlags[@]/#/_}" ""; do - if is_available "${m}${flag}"; then - m+="${flag}" - found=':' - break - fi - done - if [[ ! "${found}" ]]; then - std::info "%s %s: module unavailable -- %s\n" \ - "${CMD}" 'load' "${m}" - [[ ${verbosity_lvl} == 'verbose' ]] && output_load_hints - std::die 3 "" - fi - if [[ ":${LOADEDMODULES}:" =~ ":${m}:" ]]; then - std::die 3 "%s %s: module already loaded -- %s\n" \ - "${CMD}" 'load' "${m}" - fi - for root in "${!Overlays[@]}"; do - if [[ ${current_modulefile} =~ ${root} ]]; then - # modulefile is in our hierarchy - # ${prefix} was set in is_available()! - test -r "${prefix}/.info" && cat "$_" 1>&2 - test -r "${prefix}/.dependencies" && load_dependencies "$_" - break - fi - done - 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}" - 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. - - local error=$( < "${tmpfile}") - if [[ "${error}" =~ ":ERROR:" ]]; then - local s=${error%%$'\n'*} - local error_txt='failed' - if [[ "$s" =~ ' conflicts ' ]]; then - 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}" - fi - done - # fix LOADEDMODULES - LOADEDMODULES="${_LMFILES_}" - local dir - while read dir; do - [[ "${dir: -1}" == "/" ]] || dir+="/" - LOADEDMODULES="${LOADEDMODULES//${dir}}" - done <<< "${MODULEPATH//:/$'\n'}" - export_env "${g_shell}" LOADEDMODULES -} - -############################################################################## -# -# unload -# -Subcommands[rm]='unload' -Subcommands[unload]='unload' -Options[unload]='-o H -l help' -Help[unload]=" -USAGE: - module rm modulefile... - module unload modulefile... - Remove modulefile(s) from the shell environment. Removing - a 'group-head' will also unload all modules belonging to - this group. -" - -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. - local args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 3 "%s %s: missing argument\n" \ - "${CMD}" 'unload' - fi - - local arg - for arg in "${args[@]}"; do - local output=$("${modulecmd}" "${g_shell}" 'unload' "${arg}") - echo "${output}" - eval "${output}" - done -} - -############################################################################## -# -# swap [] -# -Subcommands[switch]='swap' -Subcommands[swap]='swap' -Options[swap]='-o H -l help' -Help[swap]=" -USAGE: - module switch [modulefile1] modulefile2 - module swap [modulefile1] modulefile2 - Switch loaded modulefile1 with modulefile2. If modulefile1 - is not specified, then it is assumed to be the currently - loaded module with the same root name as modulefile2. -" - -subcommand_swap() { - local -r subcommand='swap' - local args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 3 "%s %s: missing argument\n" \ - "${CMD}" 'swap' - elif (( ${#args[@]} > 2 )); then - std::die 3 "%s %s: too many arguments\n" \ - "${CMD}" 'swap' - fi - if (( ${#args[@]} == 1 )); then - local -r module_to_load=${args[0]} - local -r module_to_unload=${module_to_load%/*} - else - local -r module_to_unload=${args[0]} - local -r module_to_load=${args[1]} - fi - subcommand_unload "${module_to_unload}" - subcommand_load "${module_to_load}" -} - -############################################################################## -# -# show -# -Subcommands[display]='show' -Subcommands[show]='show' -Options[show]='-o H -l help' -Help[show]=' -USAGE: - module display modulefile... - module show modulefile... - Display information about one or more modulefiles. The - display sub-command will list the full path of the - modulefile(s) and all (or most) of the environment changes - the modulefile(s) will make if loaded. It will not display - any environment changes found within conditional statements. -' - -subcommand_show() { - local -r subcommand='show' - local args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 3 "%s %s: missing argument\n" \ - "${CMD}" "${subcommand}" - fi - - local arg - for arg in "${args[@]}"; do - "${modulecmd}" "${g_shell}" "${subcommand}" "${arg}" - done -} - -# -# Get all available modules in given modulepath. Whereby modulepath is -# a colon separated list. -# return list like -# modulename1 release1 modulename2 release2 ... -# -get_available_modules() { - local saved_IFS=${IFS}; - IFS=':' - local -a dirs=($1) - IFS=${saved_IFS} - local -r module="$2" - local -r releases="${3:-${UsedReleases}}" - local -a mods=() - local release - - local -A dict - for dir in "${dirs[@]}"; do - test -d "${dir}" || continue - { - cd "${dir}" - while read mod; do - get_release release "${dir}/${mod}" "${releases}" || continue - if [[ -z ${dict[${mod}]} ]]; then - mods+=( "${mod}" ${release} ) - dict[${mod}]=1 - fi - done < <(find * \( -type f -o -type l \) -not -name ".*" -ipath "${module}*") - } - done - echo "${mods[@]}" -} - -############################################################################## -# -# avail [-hlt] [...] -# -Subcommands[avail]='avail' -Options[avail]='-l help -o Hahlmt -l all -l all-releases -l human -l long -l machine -l terse' -Help[avail]=" -USAGE: - module avail [switches] string - List all available modulefiles in the current MODULEPATH. If - an argument is given, then each directory in the MODULEPATH - is searched for modulefiles whose pathname match the argument. - - This command does *not* display all installed modules on the - system. Only *loadable* modules are listed. The list of - available modules may change either by loading other modules, - e.g. a compiler, or with the sub-command 'use'. - -SWITCHES: - -a|--all||--all-releases - List all available modules independend of the release. - - -t|--terse - Output in short format. - - -l|--long - Output in long format. - - -h|--human - Output in human readable format. - -m|--machine - Output in machine readable format -" - -subcommand_avail() { - local -r subcommand='avail' - # use this variable in the output functions - local -a mods=() - local dir='' - - # get number of columns of terminal - cols=$(tput cols) - - output_header() { - local caption=$1 - let i=($cols-${#caption})/2-2 - printf -- "%0.s-" $(seq 1 $i) 1>&2 - printf -- " %s " "${caption}" 1>&2 - printf -- "%0.s-" $(seq 1 $i) 1>&2 - printf -- "\n" 1>&2 - } - - terse_output() { - output_header "$1" - for (( i=0; i<${#mods[@]}; i+=2 )); do - local mod=${mods[i]} - local release=${mods[i+1]} - case $release in - stable ) - out='' - ;; - * ) - out="${release}" - ;; - esac - printf "%-20s\t%s\n" "${mod}" "${out}" 1>&2 - done - std::info "\n" - } - - machine_output() { - for (( i=0; i<${#mods[@]}; i+=2 )); do - printf "%-20s\t%s\n" "${mods[i]}" "${mods[i+1]}" 1>&2 - done - } - - # - # :FIXME: for the time being, this is the same as terse_output! - long_output() { - output_header "$1" - for (( i=0; i<${#mods[@]}; i+=2 )); do - local mod=${mods[i]} - local release=${mods[i+1]} - case $release in - stable ) - out='' - ;; - * ) - out=${release} - ;; - esac - printf "%-20s\t%s\n" "${mod}" "${out}" 1>&2 - done - std::info "\n" - } - - human_readable_output() { - output_header "$1" - - local -i column=$cols - local -i colsize=16 - for ((i=0; i<${#mods[@]}; i+=2)); do - if [[ ${verbosity_lvl} == 'verbose' ]]; then - local release=${mods[i+1]} - case ${mods[i+1]} in - stable ) - mod=${mods[i]} - ;; - * ) - mod="${mods[i]}(${release:0:1})" - ;; - esac - else - mod=${mods[i]} - fi - local -i len=${#mod} - local -i span=$(( len / 16 + 1 )) - local -i colsize=$(( span * 16 )) - if (( column+len >= cols )); then - printf -- "\n" 1>&2 - column=0 - fi - if (( column+colsize < cols )); then - fmt="%-${colsize}s" - else - fmt="%-s" - fi - printf "${fmt}" "${mod}" 1>&2 - column+=colsize - done - printf -- "\n\n" 1>&2 - } - local pattern=() - local output_function='human_readable_output' - local opt_all_groups='no' - local opt_use_releases="${UsedReleases}" - while (($# > 0)); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -a | --all ) - opt_all_groups='yes' - opt_use_releases="${PMODULES_DEFINED_RELEASES}" - ;; - --all-releases ) - opt_use_releases="${PMODULES_DEFINED_RELEASES}" - ;; - -h | --human ) - output_function='human_readable_output' - ;; - -l | --long ) - output_function='long_output' - ;; - -t | --terse ) - output_function='terse_output' - ;; - -m | --machine ) - output_function='machine_output' - ;; - -- | '' ) - ;; - * ) - pattern+=( "$1" ) - ;; - esac - shift - done - if [[ "${opt_all_groups}" = 'yes' ]]; then - rescan_groups "${!Overlays[@]}" - fi - if (( ${#pattern[@]} == 0 )); then - pattern+=( '' ) - fi - local -a modulepath - local saved_IFS=${IFS} - IFS=':' - modulepath=(${MODULEPATH}) - IFS=${saved_IFS} - - local overlay='' - local group='' - local -A modulepath_of_group - local -a groups=() - for dir in "${modulepath[@]}"; do - group='other' - find_overlay overlay group "${dir}" - if [[ ${modulepath_of_group[${group}]} ]]; then - modulepath_of_group[${group}]+=:${dir} - else - modulepath_of_group[${group}]=${dir} - groups+=( "${group}" ) - fi - done - local string - for string in "${pattern[@]}"; do - for group in "${groups[@]}"; do - mods=( $( get_available_modules \ - "${modulepath_of_group[${group}]}" \ - "${string}" \ - "${opt_use_releases}" ) ) - [[ ${#mods[@]} == 0 ]] && continue - - ${output_function} "${group}" - done - done -} - -# compute depths or passed group -# Note: cwd must be Pmodules root directory -# $1: group -# -get_group_depth () { - local -r group="$1" - local -r dir="${group}/${PMODULES_MODULEFILES_DIR}" - 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, the above computed depth is < 0. - # We set it to 0 (even this might be wrong). - # :FIXME: better solution? - (( depth < 0 )) && (( depth = 0 )) - GroupDepths[$group]=${depth} -} - -# -# Compute depth for all known groups -# $1: root of modulefile hierarchy -get_group_depths () { - local -r roots=( "$@" ) - local root - for root in "${roots[@]}"; do - { - cd "${root}" - local group - # for some unknown reason [A-Z]* doesn't work - # on (some?) SL6 systems - for group in [ABCDEFGHIJKLMNOPQRSTUVWXYZ]*; do - get_group_depth "${group}" - done - }; - 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 roots="$@" - local root - for root in "${roots[@]}"; do - { - 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 - }; - done -} - -############################################################################## -# -# use [-a|--append|-p|--prepend] [directory|group|release...] -# -Subcommands[use]='use' -Options[use]='-l help -o Hap -l append -l prepend' -Help[use]=" -USAGE: - module use [-a|--append|-p|--prepend] [directory|group|release...] - Without arguments this sub-command displays information about - the module search path, used families and releases. You can - use this sub-command to get a list of available families and - releases. - - With a directory as argument, this directory will either be - prepended or appended to the module search path. The default - is to prepend the directory. - - With a group as argument, the modules in this group will - be made available. - - With a release as argument, this modules with this release - will be made available. - -SWITCHES: - -a | --append -p | --prepend ) - Append/prepend agrument to module search path or list of to be - searched releases. -" - -subcommand_use() { - local -r subcommand='use' - local saved_IFS=${IFS}; - IFS=':' - local -a modulepath=(${MODULEPATH}) - IFS=${saved_IFS} - local add2path_func='std::append_path' - - print_info() { - local f - local r - std::info "Used groups:\n" - for f in ${UsedGroups//:/ }; do - std::info "\t${f}\n" - done - std::info "\nUnused groups:\n" - local _group - for _group in "${!GroupDepths[@]}"; do - local -i depth=${GroupDepths[${_group}]} - if ! is_used_group "${_group}" && (( depth == 0 )); then - std::info "\t${_group}\n" - fi - done - - std::info "\nUsed releases:\n" - for r in ${UsedReleases//:/ }; do - std::info "\t${r}\n" - done - std::info "\nUnused releases:\n" - for r in ${PMODULES_DEFINED_RELEASES//:/ }; do - if ! is_used_release $r; then - std::info "\t${r}\n" - fi - done - - std::info "\nUsed flags:\n" - for flag in "${UseFlags//:/ }"; do - std::info "\t${flag}\n" - done - - local overlay - std::info "\nUsed overlays:\n" - for overlay in "${!Overlays[@]}"; do - std::info "\t${overlay}\n" - done - - std::info "\nAdditonal directories in MODULEPATH:\n" - let n=0 - local group - for (( i=0; i<${#modulepath[@]}; i++)); do - if ! find_overlay overlay group "${modulepath[i]}"; then - std::info "\t${modulepath[i]}\n" - let n+=1 - fi - done - if (( n == 0 )); then - std::info "\tnone\n" - fi - std::info "\n" - } - - use () { - declare -g UsedGroups - declare -g MODULEPATH - - local dirs_to_add=() - while (( $# > 0)); do - arg="$1" - # if is release - # ... - # elif is group - # ... - # elif matches modulepath root - # ... - # elif is directory - # ... - # else - # error - # - if is_release "${arg}"; then - # releases are always *appended* - std::append_path UsedReleases "${arg}" - elif [[ "${arg}" =~ "flag=" ]]; then - std::append_path UseFlags "${arg/flag=}" - elif [[ "${arg}" =~ "overlay=" ]]; then - local overlay="${arg/overlay=}" - [[ -d "${overlay}" ]] || \ - std:die 3 "%s %s: is not a directory -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${overlay}" - if [[ ! ${Overlays[${overlay}]} ]]; then - Overlays[${overlay}]=1 - PMODULES_OVERLAYS+=:${overlay} - get_group_depths "${!Overlays[@]}" - for group in ${UsedGroups//:/ }; do - local dir="${overlay}/${group}/${PMODULES_MODULEFILES_DIR}" - if [[ -d "${dir}" ]]; then - std::prepend_path MODULEPATH "${dir}" - fi - done - fi - - elif [[ ! ${arg} =~ */* ]] && is_group "${arg}"; then - if (( ${GroupDepths[$arg]} != 0 )); then - std::die 3 "%s %s: cannot add group to module path -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${arg}" - fi - std::append_path UsedGroups "${arg}" - for overlay in "${!Overlays[@]}"; do - for group in ${UsedGroups//:/ }; do - local dir="${overlay}/" - dir+="${group}/${PMODULES_MODULEFILES_DIR}" - if [[ -d "${dir}" ]]; then - std::prepend_path MODULEPATH "${dir}" - fi - done - done - elif [[ ${arg} =~ ^${PMODULES_ROOT} ]]; then - std::die 3 "%s %s: illegal directory -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${arg}" - elif [[ -d ${arg} ]]; then - ${add2path_func} MODULEPATH "$(cd "${arg}" && pwd)" - else - std::die 3 "%s %s: neither a directory, release or group -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${arg}" - fi - shift - done - - export_env ${g_shell} MODULEPATH UsedGroups - } - - local -a args=() - while (( $# > 0)); do - case "$1" in - -H | --help ) - print_help "${subcommand}" - ;; - -a | --append ) - add2path_func='std::append_path' - ;; - -p | --prepend ) - add2path_func='std::prepend_path' - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - - if (( ${#args[@]} == 0 )); then - print_info - else - use "${args[@]}" - fi -} - -############################################################################## -# -# unuse directory|group|release... -# -Subcommands[unuse]='unuse' -Options[unuse]='-o H -l help' -Help[unuse]=' -unuse directory|group|release... - Remove the given directory, group or release from the search - path. -' - -subcommand_unuse() { - local -r subcommand='unuse' - local dirs_to_remove=() - local -a args=() - while (( $# > 0)); do - case "$1" in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - std::die 3 "%s %s: missing argument\n" \ - "${CMD}" "${subcommand}" - fi - - local arg - for arg in "${args[@]}"; do - # if is release - # ... - # elif is group - # ... - # elif matches modulepath root - # ... - # elif is directory - # ... - local modulefiles_dir="${PMODULES_ROOT}/${arg}/${PMODULES_MODULEFILES_DIR}" - if is_release "${arg}"; then - std::remove_path UsedReleases "${arg}" - - elif [[ "${arg}" =~ "flag=" ]]; then - std::remove_path UseFlags "${arg/flag=}" - - elif [[ "${arg}" =~ "overlay=" ]]; then - local overlay="${arg/overlay=}" - [[ -d "${overlay}" ]] || \ - std::die 3 "%s %s: is not a directory -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${overlay}" - [[ "${overlay}" == "${PMODULES_ROOT}" ]] && \ - std::die 3 "%s %s: cannot remove root overlay -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${overlay}" - if [[ ${Overlays[${overlay}]} ]]; then - [[ "${_LMFILES_}" =~ "${overlay}" ]] && \ - std::die 3 "%s %s: cannot remove overlay -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${overlay}" - unset Overlays[${overlay}] - std::remove_path PMODULES_OVERLAYS "${overlay}" - for dir in "${modulepath[@]}"; do - if [[ "${dir}" =~ "${overlay}" ]]; then - std::remove_path MODULEPATH "${dir}" - fi - done - fi - - elif [[ ! ${arg} =~ */* ]] && [[ -d ${modulefiles_dir} ]]; then - if (( ${GroupDepths[$arg]} != 0 )); then - std::die 3 "%s %s: %s" \ - "${CMD}" "${FUNCNAME[0]##*_}" \ - "cannot remove group from module path -- %s\n" \ - "${arg}" - fi - std::remove_path UsedGroups "${arg}" - dirs_to_remove+=( ${modulefiles_dir} ) - - elif [[ -d ${arg} ]]; then - local normalized_dir=$(cd "${arg}" && pwd) - dirs_to_remove+=( ${normalized_dir} ) - elif [[ ${arg} =~ ^${PMODULES_ROOT} ]]; then - std::die 3 "%s %s: illegal directory -- %s\n." \ - "${CMD}" "${FUNCNAME[0]##*_}" "${arg}" - else - std::die 3 "%s %s: not a directory -- %s\n" \ - "${CMD}" "${FUNCNAME[0]##*_}" "${arg}" - fi - shift - done - - declare -g UsedGroups - export_env ${g_shell} UsedGroups - [[ ${#dirs_to_remove[@]} == 0 ]] && return - for dir in "${dirs_to_remove[@]}"; do - "${modulecmd}" "${g_shell}" "${subcommand}" "${dir}" - done -} - -############################################################################## -# -# update -# -# :FIXME: either compile Modules with --enable-beginenv or remove the sub-command -# -Subcommands[update]='update' -Options[update]='-o H -l help' -Help[update]=' -USAGE: - module update - Attempt to reload all loaded modulefiles. -' - -subcommand_update() { - subcommand_generic0 'update' "$@" -} - -############################################################################## -# -# refresh -# -Subcommands[refresh]='refresh' -Options[refresh]='-o H -l help' -Help[refresh]=' -USAGE: - module refresh - Force a refresh of all non-persistent components of currently - loaded modules. This should be used on derived shells where - aliases need to be reinitialized but the environment variables - have already been set by the currently loaded modules. -' - -subcommand_refresh() { - subcommand_generic0 'refresh' "$@" -} - -reset_modulepath() { - MODULEPATH='' - local group - local root - for root in "${!Overlays[@]}"; do - for group in ${PMODULES_DEFAULT_GROUPS}; do - local dir="${root}/${group}/${PMODULES_MODULEFILES_DIR}" - [[ -d "${dir}" ]] && std::prepend_path MODULEPATH "${dir}" - done - done -} - -reset_used_groups() { - UsedGroups='' - local group - for group in ${PMODULES_DEFAULT_GROUPS}; do - std::append_path UsedGroups "${group}" - done -} - -reset_used_releases() { - declare -g UsedReleases='' - for r in ${PMODULES_DEFAULT_RELEASES//:/ }; do - std::append_path UsedReleases "${r}" - done -} - -init_path() { - std::replace_path PATH "${PMODULES_HOME%/*}/.*" - std::prepend_path PATH "${PMODULES_HOME}/bin" -} - -init_manpath() { - std::replace_path MANPATH "${PMODULES_HOME%/*}/.*" - - if [[ -r /etc/man.config ]]; then - declare _manconf='/etc/man.config' - elif [[ -r /etc/man.conf ]]; then - declare _manconf='/etc/man.conf' - fi - if [[ -n ${_manconf} ]]; then - while read name value rest; do - std::append_path MANPATH "${value}" - done < <(grep "^MANPATH\s" "${_manconf}") - unset _manconf - else - std::append_path MANPATH "${PMODULES_HOME}/share/man" - std::append_path MANPATH "/usr/share/man" - fi -} - -pmodules_init() { - declare -gx LOADEDMODULES='' - declare -gx _LMFILES_='' - - declare -Ag Overlays=([${PMODULES_ROOT}]="1") - declare -gx PMODULES_OVERLAYS="${PMODULES_ROOT}" - declare -g UsedGroups='' - declare -gx MODULEPATH='' - declare -Ag GroupDepths='()' - declare -g UseFlags=() - reset_modulepath - reset_used_groups - reset_used_releases - init_path - init_manpath - export_env "${g_shell}" \ - LOADEDMODULES \ - _LMFILES_ \ - MODULEPATH \ - PATH \ - MANPATH -} - -############################################################################## -# -# purge -# -Subcommands[purge]='purge' -Options[purge]='-o H -l help' -Help[purge]=' -USAGE: - module purge - Unload all loaded modulefiles. -' - -subcommand_purge() { - local -r subcommand='purge' - local -a args=() - while (( $# > 0)); do - case "$1" in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} > 0 )); then - std::die 3 "%s %s: no arguments allowd\n" \ - "${CMD}" "${subcommand}" - fi - "${modulecmd}" "${g_shell}" "${subcommand}" - reset_modulepath - reset_used_groups - export_env ${g_shell} MODULEPATH UsedGroups -} - -############################################################################## -# -# list [-hlt] -# -Subcommands[list]='list' -Options[list]='-l help -o Hhlt -l human -l long -l terse' -Help[list]=' -USAGE: - module list - List loaded modules. -' - -subcommand_list() { - local -r subcommand='list' - local opts=() - local args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -h | --human ) - opts+=( '-h' ) - ;; - -l | --long ) - opts+=( '-l' ) - ;; - -t | --terse ) - opts+=( '-t' ) - ;; - -- ) - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} > 0 )); then - std::die 3 "%s %s: no arguments allowd\n" \ - "${CMD}" "${subcommand}" - fi - "${modulecmd}" "${g_shell}" list "${opts[@]}" -} - - -############################################################################## -# -# clear -# -Subcommands[clear]='clear' -Options[clear]='-o H -l help' -Help[clear]=' -USAGE: - module clear - Force the Modules package to believe that no modules are - currently loaded. -' - -subcommand_clear() { - local -r subcommand='clear' - local -a args=() - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - -- ) - : - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} > 0 )); then - std::die 3 "%s %s: no arguments allowed\n" \ - "${CMD}" "${subcommand}" - fi - pmodules_init - export_env ${g_shell} LOADEDMODULES MODULEPATH _LMFILES_ -} - -############################################################################## -# -# search [switches] [STRING...] -# -Subcommands[search]='search' -Options[search]='-o aH -l help -l no-header -l print-modulefiles ' -Options[search]+='-l release: -l with: -l all-releases -l src: -l print-csv' -Help[search]=' -USAGE: - module search [switches] string... - Search installed modules. If an argument is given, search - for modules whose name match the argument. - -SWITCHES: - --no-header - Suppress output of a header. - - --release=RELEASE - Search for modules within this release. You can specify this - switch multiple times. Without this switch, the used releases - will be searched. - - -a|--all-releases - Search within all releases. - - --with=STRING - Search for modules compiled with modules matching string. The - command - - module search --with=gcc/4.8.3 - - lists all modules in the hierarchy compiled with gcc 4.8.3. -' - -subcommand_search() { - local -r subcommand='search' - local modules=() - local with_modules='//' - local src_prefix=() - local opt_print_header='yes' - local opt_print_modulefiles='no' - local opt_print_csv='no' - local opt_use_releases=':' - local -r fmt="%-20s %-10s %-12s %-s\n" - - # no args - print_header() { - printf '\n' 1>&1 - printf "${fmt}" "Module" "Release" "Group" "Requires" 1>&2 - printf -- '-%.0s' {1..60} 1>&2 - printf '\n' 1>&2 - } - - #..................................................................... - # - # output result of search - # Args: - # $1: tmp file - # - # variables used from enclosing function: - # opt_print_header - # opt_print_modulefiles - # with_modules - # - print_result() { - local -r tmpfile=$1 - [[ "${opt_print_header}" == "yes" ]] && print_header - if [[ "${opt_print_modulefiles}" == "yes" ]]; then - while read -a line; do - # group first - local out="${line[2]}/" - # add directory of modulefiles - out+="${PMODULES_MODULEFILES_DIR}/" - for d in "${line[@]:3}"; do - out+="$d/" - done - out+="${line[0]}" - std::info "${out}\n" - 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}") - else - "${sort}" -k 1,1 -k 4,4 -k 5,5 "${tmpfile}" | awk "${with_modules}" 1>&2 - fi - } - - #..................................................................... - # - # search modules - # Args: - # $1: module name pattern - # - # Variables used from enclosing function - # :FIXME: - # - search () { - local -r module=$1 - # write results to a temporary file for later processing - local -r tmpfile=$( "${mktemp}" /tmp/Pmodules.XXXXXX ) \ - || std::die 1 "Oops: unable to create tmp file!\n" - local group - # loop over all groups - for group in "${!GroupDepths[@]}"; do - # loop over all directories which can be added to - # MODULEPATH inside current group - local depth=${GroupDepths[${group}]} - local mpaths=( $(find \ - "${src_prefix[@]/%//${group}/modulefiles}" \ - -type d \ - -mindepth ${depth} -maxdepth ${depth} \ - 2>/dev/null)) - local mpath - local overlay - local unused - for mpath in "${mpaths[@]}"; do - # get dependencies encoded in directory name - find_overlay overlay unused "${mpath}" - local p="${mpath/${overlay}}" - p=( ${p//\// } ) - local deps=() - local -i i - for ((i=2; i < ${#p[@]}; i+=2)); do - deps+=( ${p[i]}/${p[i+1]} ) - done - local requires=${deps[@]} - - # get and print all available modules in $mpath - # with respect to the requested releases - # tmpfile: module/version release group group-dependencies... - local mods=( $( get_available_modules \ - "${mpath}" \ - "${module}" \ - "${opt_use_releases}" ) ) - [[ ${#mods[@]} == 0 ]] && continue - for (( i=0; i<${#mods[@]}; i+=2 )); do - printf "${fmt}" ${mods[i]} "${mods[i+1]}" \ - ${group} "${requires}" >> "${tmpfile}" - done - done - done - print_result "${tmpfile}" - rm -f "${tmpfile}" - } - - while (( $# > 0 )); do - case $1 in - -H | --help ) - print_help "${subcommand}" - ;; - --no-header ) - opt_print_header='no' - ;; - --print-modulefiles ) - opt_print_modulefiles='yes' - opt_print_header='no' - ;; - --print-csv ) - opt_print_csv='yes' - opt_print_header='no' - ;; - --release | --release=* ) - if [[ "$1" == "--release" ]]; then - local arg=$2 - shift - else - local arg=${1/--release=} - fi - is_release "${arg}" || \ - std::die 1 "%s %s: illegal release name -- %s\n" \ - "${CMD}" 'search' "${arg}" - opt_use_releases+="${arg}:" - ;; - --with | --with=* ) - if [[ "$1" == --with ]]; then - local arg=$2 - shift - else - 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}" - fi - with_modules+=" && / ${arg//\//\\/}/" - ;; - -a | --all-releases ) - opt_use_releases="${PMODULES_DEFINED_RELEASES}" - ;; - --src ) - src_prefix=$2 - pmodules::check_directories "${src_prefix}" - shift - ;; - -- ) - ;; - * ) - modules+=( "$1" ) - ;; - esac - shift - done - if [[ -z "${src_prefix}" ]]; then - src_prefix=( "${!Overlays[@]}" ) - fi - - if [[ "${opt_use_releases}" == ":" ]]; then - opt_use_releases=":${UsedReleases}:" - fi - - if [[ ${#modules[@]} == 0 ]]; then - modules+=( '' ) - fi - - if (( ${#GroupDepths[@]} == 0 )) || [[ ${src_prefix} != ${PMODULES_ROOT} ]]; then - get_group_depths "${src_prefix}" - fi - - local module - for module in "${modules[@]}"; do - search "${module}" - done -} - -############################################################################## -# -# help [module|sub-command] -# -Subcommands[help]='help' -Options[help]='-o hHV? -l version -l help' -Help[help]=' -USAGE: - module [ switches ] [ subcommand ] [subcommand-args ] - -SWITCHES: - -h|-H|-?|--help this usage info - -V|--version modules version & configuration options - -SUBCOMMANDS: - + add|load [switches] modulefile [modulefile ...] - + rm|unload modulefile [modulefile ...] - + switch|swap [modulefile1] modulefile2 - + display|show modulefile [modulefile ...] - + avail [switches] [modulefile [modulefile ...]] - + search [switches] [args] - + use [switches] [dir|group|release ...] - + unuse dir|group|release [dir|group|release ...] - + refresh - + purge - + list [switches] - + clear - + help [modulefile|subcommand] - + whatis [modulefile [modulefile ...]] - + apropos|keyword string - + initadd modulefile [modulefile ...] - + initprepend modulefile [modulefile ...] - + initrm modulefile [modulefile ...] - + initswitch modulefile1 modulefile2 - + initlist - + initclear -' - -subcommand_help() { - local -r subcommand='help' - local -a args=() - while (( $# > 0 )); do - case $1 in - -[hH] | --help ) - print_help "${subcommand}" - ;; - -V | --version ) - print_help 'version' - ;; - -- ) - : - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} == 0 )); then - print_help 'help' - fi - local arg - for arg in "${args[@]}"; do - if [[ -n "${Help[${arg}]}" ]] ; then - print_help "${arg}" - else - # :FIXME: print help of newest *available* module - # (respecting UsedReleases) - "${modulecmd}" "${g_shell}" "${subcommand}" "${arg}" - fi - done -} - -############################################################################## -# -# whatis -# -Subcommands[whatis]='whatis' -Options[whatis]='-o H -l help' -Help[whatis]=' -USAGE: - module whatis [modulefile...] - Display the information set up by the module-whatis commands - inside the specified modulefile(s). If no modulefile is - specified, all 'whatis' lines will be shown. -' - -subcommand_whatis() { - if (( $# == 0 )); then - subcommand_generic0 'whatis' - else - subcommand_generic1plus 'whatis' "$@" - fi -} - -############################################################################## -# -# apropos -# -Subcommands[apropos]='apropos' -Subcommands[keyword]='apropos' -Options[apropos]='-o H -l help' -Help[apropos]=' -USAGE: - module apropos string - module keyword string Seeks through the 'whatis' informations of - all modulefiles for the specified string. All module-whatis - informations matching the string will be displayed. -' - -subcommand_apropos() { - subcommand_generic1 'apropos' "$@" -} - -############################################################################## -# -# initadd module... -# -Subcommands[initadd]='initadd' -Options[initadd]='-o H -l help' -Help[initadd]=" -USAGE: - module initadd modulefile... - Add modulefile(s) to the shell's initialization file in the - user's home directory. The startup files checked (in order) - are: - - csh - .modules, .cshrc(.ext), .csh_variables, and - .login(.ext) - tcsh - .modules, .tcshrc, .cshrc(.ext), .csh_variables, - and .login(.ext) - (k)sh - .modules, .profile(.ext), and .kshenv(.ext) - bash - .modules, .bash_profile, .bash_login, - .profile(.ext) and .bashrc(.ext) - zsh - .modules, .zcshrc(.ext), .zshenv(.ext), and - .zlogin(.ext) - - If a 'module load' line is found in any of these files, the - modulefile(s) is(are) appended to any existing list of - modulefiles. The 'module load' line must be located in at - least one of the files listed above for any of the 'init' - sub-commands to work properly. If the 'module load' line - line is found in multiple shell initialization files, all - of the lines are changed. -" - -subcommand_initadd() { - subcommand_generic1plus 'initadd' "$@" -} - -############################################################################## -# -# initprepend module... -# -Subcommands[initprepend]='initprepend' -Options[initprepend]='-o H -l help' -Help[initprepend]=" -USAGE: - module initprepend modulefile... - Does the same as initadd but prepends the given modules to - the beginning of the list. -" - -subcommand_initprepend() { - subcommand_generic1plus 'initprepend' "$@" -} - -############################################################################## -# -# initrm module... -# -Subcommands[initrm]='initrm' -Options[initrm]='-o H -l help' -Help[initrm]=" -USAGE: - module initrm modulefile... - Remove modulefile(s) from the shell's initialization files. -" - -subcommand_initrm() { - subcommand_generic1plus 'initrm' "$@" -} - -############################################################################## -# -# initswitch module1 module2 -# -Subcommands[initswitch]='initswitch' -Options[initswitch]='-o H -l help' -Help[initswitch]=" -USAGE: - module initswitch modulefile1 modulefile2 - Switch modulefile1 with modulefile2 in the shell's initialization files. -" - -subcommand_initswitch() { - subcommand='initswitch' - local args=() - while (( $# > 0 )); do - case $1 in - -h | --help ) - print_help "${subcommand}" - ;; - -- ) - : - ;; - * ) - args+=( "$1" ) - ;; - esac - shift - done - if (( ${#args[@]} != 2 )); then - std::die 3 "%s %s: two arguments required not less not more\n" \ - "${CMD}" "${subcommand}" - fi - "${modulecmd}" "${g_shell}" "${subcommand}" "${args[@]}" -} - -############################################################################## -# -# initlist -# -Subcommands[initlist]='initlist' -Options[initlist]='-o H -l help' -Help[initlist]=" -USAGE: - module initlist - List all of the modulefiles loaded from the shell's initialization file. -" - -subcommand_initlist() { - subcommand_generic0 'initlist' "$@" -} - -############################################################################## -# -# initclear -# -Subcommands[initclear]='initclear' -Options[initclear]='-o H -l help' -Help[initclear]=" -USAGE: - module initclear - Clear all of the modulefiles from the shell's initialization files. -" - -subcommand_initclear() { - subcommand_generic0 'initclear' "$@" -} - -############################################################################## -# -# main -# -case "$1" in - bash | zsh ) - declare g_shell="$1" - ;; - csh | tcsh ) - declare g_shell='csh' - ;; - * ) - std::die 1 "${CMD}: unsupported shell -- $1\n" - ;; -esac -shift - -declare -a opts=() -while (( $# > 0 )); do - case $1 in - -H | -\? | --help | -help ) - print_help 'help' - ;; - -V | --version ) - print_help 'version' - ;; - --debug ) - set -x - ;; - '' | -- ) - ;; - -* ) - opts+=( "$1" ) - ;; - * ) - subcommand="$1" - shift - break - ;; - esac - shift -done - -if [[ -z "${subcommand}" ]]; then - std::die 1 "${CMD}: no sub-command specified.\n" -fi - -if [[ -z "${Subcommands[${subcommand}]}" ]]; then - std::die 1 "${CMD}: unknown sub-command -- ${subcommand}\n" -fi - -if [[ -n ${PMODULES_ENV} ]]; then - eval "$("${base64}" -d <<< "${PMODULES_ENV}" 2>/dev/null)" -else - pmodules_init -fi - -if (( ${#GroupDepths[@]} == 0 )); then - get_group_depths "${!Overlays[@]}" -fi - -declare options -options=$( "${getopt}" ${Options[${subcommand}]} -- -- "${opts[@]}" "$@" ) \ - || print_help "${subcommand}" -eval set -- ${options} -subcommand_${Subcommands[$subcommand]} "$@" - -# Local Variables: -# mode: sh -# sh-basic-offset: 8 -# tab-width: 8 -# End: