diff --git a/Pmodules/Pmodules.conf b/Pmodules/Pmodules.conf new file mode 100644 index 0000000..fffe8a3 --- /dev/null +++ b/Pmodules/Pmodules.conf @@ -0,0 +1,8 @@ +# set groups which should be available after initialization +DefaultGroups='Tools Programming' + +# define available release stages +ReleaseStages=':unstable:stable:deprecated:' + +# set releases which should be available after initialization +DefaultReleaseStages='stable' diff --git a/Pmodules/bash b/Pmodules/bash index c7e9bf5..5afa1be 100644 --- a/Pmodules/bash +++ b/Pmodules/bash @@ -35,6 +35,11 @@ unset MODULE_VERSION_STACK unset MODULESHOME unset PMODULES_ENV +declare -x PMODULES_MODULEFILES_DIR='modulefiles' +declare -x PMODULES_CONFIG_DIR='config' +declare -x PMODULES_DIR="${PMODULES_HOME}" + + ############################################################################# # implement module comand as shell function # diff --git a/Pmodules/csh b/Pmodules/csh index 854152a..5fb9926 100644 --- a/Pmodules/csh +++ b/Pmodules/csh @@ -35,7 +35,7 @@ unset prefix unset postfix setenv MODULEPATH -foreach group ( ${PMODULES_DEFAULT_GROUPS} ) +foreach group ( ${DefaultGroups} ) if ( "${MODULEPATH}" == "" ) then setenv MODULEPATH "${PMODULES_ROOT}/${group}/${PMODULES_MODULEFILES_DIR}" else diff --git a/Pmodules/libmodules.tcl b/Pmodules/libmodules.tcl index 58e266d..7bba9db 100644 --- a/Pmodules/libmodules.tcl +++ b/Pmodules/libmodules.tcl @@ -45,6 +45,8 @@ proc _pmodules_parse_pmodules_env { } { foreach k $l { lappend ::OverlayList $tmp($k) } + UsedGroups { + set ::UsedGroups $value } } } diff --git a/Pmodules/libpbuild.bash b/Pmodules/libpbuild.bash index 944eeab..8272a93 100644 --- a/Pmodules/libpbuild.bash +++ b/Pmodules/libpbuild.bash @@ -1303,7 +1303,7 @@ pbuild.build_module() { build_dependency() { local -r m=$1 std::debug "${m}: module not available" - local rels=( ${PMODULES_DEFINED_RELEASES//:/ } ) + local rels=( ${ReleaseStages//:/ } ) [[ ${dry_run} == yes ]] && \ std::die 1 \ "%s " \ diff --git a/Pmodules/modulecmd.bash.in b/Pmodules/modulecmd.bash.in index d6b5d56..c14eaa5 100644 --- a/Pmodules/modulecmd.bash.in +++ b/Pmodules/modulecmd.bash.in @@ -38,10 +38,6 @@ fi source "${libdir}/libstd.bash" -: ${PMODULES_DEFINED_RELEASES:=':unstable:stable:deprecated:'} - -declare -r version='@PMODULES_VERSION@' - if [[ ${PMODULES_PURETCL} == yes ]]; then declare -r modulecmd="${libexecdir}/modulecmd.tcl" else @@ -67,8 +63,10 @@ declare -A Subcommands declare -A Options declare -A Help +declare -r pmodules_config_file="${PMODULES_ROOT}/${PMODULES_CONFIG_DIR}/Pmodules.conf" + Help['version']=" -Pmodules ${version} using Tcl Environment Modules @MODULES_VERSION@ +Pmodules @PMODULES_VERSION@ using Tcl Environment Modules @MODULES_VERSION@ Copyright GNU GPL v2 " @@ -94,6 +92,18 @@ export_env() { printf "${fmt}" "$1" "${!1}" shift done + # :FIXME: UsedGroups can be modified in libmodule.tcl using + # append-path/remove-path! But we keep the state in PMODULES_ENV + # so we don't have to export it. + # + case "${Shell}" in + sh | bash | zsh ) + echo "unset UsedGroups; " + ;; + csh | tcsh ) + echo "unsetenv UsedGroups; " + ;; + esac } # @@ -107,9 +117,11 @@ declare g_env_must_be_saved='no' save_env() { [[ $1 == 'no' ]] && return 0 - local vars=( Version GroupDepths UsedReleases UseFlags UsedGroups ) - vars+=( PMODULES_DEFAULT_GROUPS PMODULES_DEFINED_RELEASES ) - vars+=( PMODULES_DEFAULT_RELEASES ) + local vars=( Version ) + vars+=( UsedReleaseStages UsedFlags UsedGroups ) + vars+=( DefaultGroups DefaultReleaseStages ) + vars+=( ReleaseStages ) + vars+=( GroupDepths ) vars+=( OverlayList ) vars+=( OverlayDict Dir2OverlayMap) @@ -139,18 +151,18 @@ get_overlay_of_moduledir() { } # -# get release of module +# get release stage of module # Note: -# - the release of a module outside ${OverlayDict[@]} is always 'stable' -# - the release of a module inside ${OverlayDict[@]} without a -# coresponding release file is always 'unstable' +# - the release stage of a module outside ${OverlayDict[@]} is always 'stable' +# - the release stage of a module inside ${OverlayDict[@]} without a +# coresponding file is always 'unstable' # # Args: -# $1 upvar for returned release +# $1 upvar for returned release stage # $2 modulefile directory (element of MODULEPATH) # $3 module name/version # -get_release() { +get_release_stage() { local "$1" local -r moduledir=$2 local -r name=$3 @@ -166,20 +178,59 @@ get_release() { # # In an overlay the name of the module-file is something like # dir/modulefiles/name/version - # the corresponding release file is + # the corresponding file is # dir/modulefiles/name/.release-version # - local -r releasefile="${modulefile%/*}/.release-${modulefile##*/}" - if [[ -r ${releasefile} ]]; then - # read releasefile, remove empty lines, spaces etc - std::upvar $1 $( < "${releasefile}" ) + local -r rel_stage_file="${modulefile%/*}/.release-${modulefile##*/}" + if [[ -r ${rel_stage_file} ]]; then + # read file, remove empty lines, spaces etc + std::upvar $1 $( < "${rel_stage_file}" ) else std::upvar $1 'unstable' fi } -is_release() { - [[ ${PMODULES_DEFINED_RELEASES} =~ :$1: ]] +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} -L "${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 overlays and compute group depth's +# +# Args: +# $1: array of overlays +# +scan_groups () { + local -r overlays=( "$@" ) + local overlay + for overlay in "${overlays[@]}"; do + local moduledir + for moduledir in ${overlay}/*/${PMODULES_MODULEFILES_DIR}; do + compute_group_depth "${moduledir}" + done + done } # @@ -324,6 +375,7 @@ USAGE: subcommand_load() { local -r subcommand='load' + local rel_stage='undef' local current_modulefile='' local prefix='' local m='' @@ -352,12 +404,12 @@ subcommand_load() { # # possible return values: # 0: module is loadable - # 1: either not a modulefile or unsused release + # 1: either not a modulefile or unsused release stage # # The following variables in the enclosing function are set: # current_modulefile # prefix - # release + # rel_stage # is_available() { local m=$1 @@ -378,7 +430,7 @@ subcommand_load() { current_modulefile="${array[0]}" prefix="${array[1]}" test -n "${current_modulefile}" || return 1 - get_release release "${current_modulefile}" "${UsedReleases}" + get_release_stage rel_stage "${current_modulefile}" "${UsedReleaseStages}" } # @@ -393,12 +445,12 @@ subcommand_load() { get_load_hints() { local "$1" local output='' - local release='' + local rel_stage='' while read -a line; do [[ -z ${line} ]] && continue - release=${line[1]} - if [[ ! ":${UsedReleases}:" =~ "${release}" ]]; then - output+="module use ${release}; " + rel_stage=${line[1]} + if [[ ! ":${UsedReleaseStages}:" =~ "${rel_stage}" ]]; then + output+="module use ${rel_stage}; " fi local group=${line[2]} if [[ ! ":${UsedGroups}:" =~ ":${group}:" ]] && \ @@ -510,25 +562,24 @@ subcommand_load() { for m in "${args[@]}"; do if [[ "$m" =~ ":" ]]; then - # $m is an extended module name - # the format is one of - # - group:name - # - group:name:release - # - release:name - # - release:group:name - # - name:release + # extendet module name is either + # - group:name or + # - group:name:rel_stage or + # - rel_stage:name or + # - rel_stage:group:name or + # - name:rel_stage IFS=':' local -a toks=($m) unset IFS local group='' - local release='' + local rel_stage='' if is_group "${toks[0]}"; then group=${toks[0]} m=${toks[1]} - release=${toks[2]} - elif is_release "${toks[0]}"; then - release=${toks[0]} + rel_stage=${toks[2]} + elif is_release_stage "${toks[0]}"; then + rel_stage=${toks[0]} if is_group "${toks[1]}"; then group=${toks[1]} m=${toks[2]} @@ -540,9 +591,9 @@ subcommand_load() { m=${toks[0]} if is_group "${toks[1]}"; then group=${toks[1]} - release=${toks[2]} + rel_stage=${toks[2]} else - release=${toks[1]} + rel_stage=${toks[1]} group=${toks[2]} fi fi @@ -566,17 +617,17 @@ subcommand_load() { modulepath=( "${overlay}/${group}/" "${modulepath[@]}" ) done fi - if [[ -n ${release} ]]; then - is_release "${release}" || \ + if [[ -n ${rel_stage} ]]; then + is_release_stage "${rel_stage}" || \ std::die 3 "%s %s: %s -- %s" \ "${CMD}" "${subcommand}" \ - "illegal release name" - "${release}" - UsedReleases=( "${release}" ) + "illegal release stage" \ + "${rel_stage}" + std::append_path UsedReleaseStages "${rel_stage}" + g_env_must_be_saved='yes' fi fi # handle extended module names - local release='' - find_module current_modulefile release "${m}" "${modulepath[@]}" + find_module current_modulefile rel_stage "${m}" "${modulepath[@]}" if [[ -z ${current_modulefile} ]]; then local text='' get_load_hints text @@ -651,11 +702,11 @@ subcommand_load() { fi local msg=$(printf "%s %s: %s -- %s" \ - "${CMD}" 'load' \ - "${release} module has been loaded" \ - "${m}") + "${CMD}" 'load' \ + "${rel_stage} module has been loaded" \ + "${m}") if [[ ${verbosity_lvl} != silent ]] && \ - [[ ${release} != stable ]]; then + [[ ${rel_stage} != stable ]]; then std::info "%s" "${msg}" fi ${logger} -t Pmodules "${msg}" @@ -842,18 +893,18 @@ subcommand_show() { # # Find all modules in a given modulepath matching a specific string. -# The search can be restricted to certain releases. +# The search can be restricted to certain release stages. # # return list like -# modulename1 release1 modulefile1 modulename2 release2 modulefile2 ... +# modulename_1 rel_stage_1 modulefile_1 modulename_2 rel_stage_2 modulefile_1 ... # get_available_modules() { local var="$1" local -r module="$2" - local -r releases="${3:-${UsedReleases}}" + local -r used_rel_stages="${3:-${UsedReleaseStages}}" shift 3 # in the for loop below we use $@ to loop over the directories local -a mods=() - local release + local rel_stage local -A dict local -A modulenames @@ -877,11 +928,11 @@ get_available_modules() { local entries=$(echo *) [[ -n ${entries} ]] || continue while read mod; do - get_release \ - release \ + get_release_stage \ + rel_stage \ "${dir}" \ "${mod}" - [[ :${releases}: =~ ${release} ]] || continue + [[ :${used_rel_stages}: =~ :${rel_stage}: ]] || continue local add='no' if [[ -n "${overlay}" ]]; then # module is in an overlay @@ -909,7 +960,7 @@ get_available_modules() { add='yes' fi if [[ "${add}" == 'yes' ]]; then - mods+=( "${mod}" ${release} "${dir}/${mod}" ) + mods+=( "${mod}" ${rel_stage} "${dir}/${mod}" ) dict[${mod}]=1 fi done < <(${find} -L ${entries} \ @@ -924,7 +975,7 @@ get_available_modules() { # # find module(file) to load. Input arguments are # $1 upvar: return module file -# $2 upvar: return module release +# $2 upvar: return module release stage # $3 module to load # $4 a modulepath (usually MODULEPATH) # @@ -950,11 +1001,10 @@ find_module() { test -d "${dir}" || continue local -i col=$((${#dir} + 2 )) local -a modules - local -a releases if [[ ${module} == */* ]]; then # a version number has been specified. But we still might # have the same module/version with different use flags. - # Releases we ignore in this case. + # The different release stages we ignore in this case. modules=$(${find} -L "${dir}" -type f -not -name ".*" \ -ipath "${dir}/${module}*" \ | cut -b${col}-) @@ -962,42 +1012,42 @@ find_module() { # # loop over all used flags. If a module with # a used flag is available load this module. + local rel_stage for flag in "${UseFlags[@]/#/_}" ""; do [[ ${mod} == ${module}${flag} ]] || continue std::upvar $1 "${dir}/${mod}" - get_release \ - release \ + get_release_stage \ + rel_stage \ "${dir}" \ "${mod}" - std::upvar $2 "${release}" + std::upvar $2 "${rel_stage}" return 0 done done else # no version has been specified. This makes it more # difficult. We have to load the newest version taking - # the used releases and flags into account. + # the used release stages and flags into account. (( col += ${#module} + 1 )) modules=( $(${find} -L "${dir}" -type f -not -name ".*" \ -ipath "${dir}/${module}/*" \ | cut -b${col}- \ | sort -rV ) ) modules=( "${modules[@]/#/${module}/}" ) - releases=":${UsedReleases}:" for mod in "${modules[@]}"; do # # loop over all used flags. If a module with # a used flag is available load this module. - local release='' + local rel_stage='' for flag in "${UseFlags[@]/#/_}" ""; do [[ ${mod} == ${module}/*${flag} ]] || continue std::upvar $1 "${dir}/${mod}" get_release \ - release \ + rel_stage \ "${dir}" \ - "${mod}" \ - std::upvar $2 "${release}" - [[ :${release}: =~ :${UsedReleases}: ]] && \ + "${mod}" + std::upvar $2 "${rel_stage}" + [[ :${release}: =~ :${UsedReleaseStages}: ]] && \ return 0 done done @@ -1011,7 +1061,7 @@ find_module() { # avail [-hlt] [...] # Subcommands[avail]='avail' -Options[avail]='-l help -o Hahlmt -l all -l all-releases -l human -l long -l machine -l terse' +Options[avail]='-l help -o Hahlmt -l all -l all-release-stages -l human -l long -l machine -l terse' Help[avail]=" USAGE: module avail [switches] string @@ -1025,8 +1075,8 @@ USAGE: e.g. a compiler, or with the sub-command 'use'. SWITCHES: - -a|--all||--all-releases - List all available modules independend of the release. + -a|--all||--all-release-stages + List all available modules independend of the release stage. -t|--terse Output in short format. @@ -1060,15 +1110,16 @@ subcommand_avail() { terse_output() { output_header "$1" - for (( i=0; i<${#mods[@]}; i+=3 )); do + local -i i=0 + for i in ${!mods[@]}; do local mod=${mods[i]} - local release=${mods[i+1]} - case $release in + local rel_stage=${mods[i+1]} + case ${rel_stage} in stable ) out='' ;; * ) - out="${release}" + out="${rel_stage}" ;; esac printf "%-20s\t%s\n" "${mod}" "${out}" 1>&2 @@ -1088,13 +1139,13 @@ subcommand_avail() { output_header "$1" for (( i=0; i<${#mods[@]}; i+=3 )); do local mod=${mods[i]} - local release=${mods[i+1]} - case $release in + local rel_stage=${mods[i+1]} + case ${rel_stage} in stable ) out='' ;; * ) - out=${release} + out=${rel_stage} ;; esac printf "%-20s\t%s\n" "${mod}" "${out}" 1>&2 @@ -1110,13 +1161,13 @@ subcommand_avail() { local -i max_length=1 for ((i=0; i<${#mods[@]}; i+=3)); do if [[ ${verbosity_lvl} == 'verbose' ]]; then - local release=${mods[i+1]} - case ${mods[i+1]} in + local rel_stage=${mods[i+1]} + case ${rel_stage} in stable ) mod="${mods[i]}" ;; * ) - mod="${mods[i]}(${release:0:1})" + mod="${mods[i]}(${rel_stage:0:1})" ;; esac else @@ -1149,7 +1200,7 @@ subcommand_avail() { } local pattern=() local output_function='human_readable_output' - local opt_use_releases="${UsedReleases}" + local opt_use_rel_stages="${UsedReleaseStages}" local -A opt_groups=() local val='' while (($# > 0)); do @@ -1157,8 +1208,8 @@ subcommand_avail() { -H | --help | -\? ) print_help "${subcommand}" ;; - -a | --all | --all-releases ) - opt_use_releases="${PMODULES_DEFINED_RELEASES}" + -a | --all | --all-release-stages ) + opt_use_rel_stages="${ReleaseStages}" ;; -h | --human ) output_function='human_readable_output' @@ -1208,7 +1259,7 @@ subcommand_avail() { path+=("${dir}") done local p - for p in "${pattern[@]}"; do + for string in "${pattern[@]}"; do for group in ${UsedGroups//:/ } other; do if (( ${#opt_groups[@]} > 0 )) && [[ ! -v opt_groups[${group}] ]]; then continue @@ -1217,8 +1268,8 @@ subcommand_avail() { typeset -n path=modulepath_${group} get_available_modules \ mods \ - "${p}" \ - "${opt_use_releases}" \ + "${string}" \ + "${opt_use_rel_stages}" \ "${path[@]}" [[ ${#mods[@]} == 0 ]] && continue @@ -1227,58 +1278,19 @@ subcommand_avail() { done } -# -# 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} -L "${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 overlays and compute group depth's -# -# Args: -# $1: array of overlays -# -scan_groups () { - local -r overlays=( "$@" ) - local overlay - for overlay in "${overlays[@]}"; do - local moduledir - for moduledir in ${overlay}/*/${PMODULES_MODULEFILES_DIR}; do - compute_group_depth "${moduledir}" - done - done -} - ############################################################################## # -# use [-a|--append|-p|--prepend] [directory|group|release...] +# use [-a|--append|-p|--prepend] [directory|group|release_stage...] # 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...] + module use [-a|--append|-p|--prepend] [directory|group|release_stage|...] 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. + the module search path, used groups and release stages. You can + use this sub-command to get a list of available groups and + releases stages. With a directory as argument, this directory will either be prepended or appended to the module search path. The default @@ -1307,10 +1319,6 @@ subcommand_use() { [[ :${UsedGroups}: =~ :$1: ]] } - release_is_used() { - [[ ":${UsedReleases}:" =~ :$1: ]] - } - print_info() { local f local r @@ -1328,22 +1336,17 @@ subcommand_use() { fi done - std::info '' - std::info "Used releases:" - for r in ${UsedReleases//:/ }; do + std::info "\nUsed releases stages:" + for r in ${UsedReleaseStages//:/ }; do std::info "\t${r}" done - std::info '' - std::info "Unused releases:" - for r in ${PMODULES_DEFINED_RELEASES//:/ }; do - if ! release_is_used $r; then - std::info "\t${r}" - fi + std::info "\nUnused release stages:" + for r in ${ReleaseStages//:/ }; do + [[ ! ":${UsedReleaseStages}:" =~ :$r: ]] && std::info "\t${r}" done - std::info '' - std::info "Used flags:" - for flag in "${!UseFlags[@]}"; do + std::info "\nUsed flags:" + for flag in "${UsedFlags[@]}"; do std::info "\t${flag}" done @@ -1474,14 +1477,14 @@ subcommand_use() { local arg=$1 - if is_release "${arg}"; then - # argument is release - std::append_path UsedReleases "${arg}" + if is_release_stage "${arg}"; then + # argument is release stage + std::append_path UsedReleaseStages "${arg}" return fi if [[ "${arg}" =~ "flag=" ]]; then # argument is flag - UseFlags["${arg/flag=}"]=1 + UsedFlags+=( "${arg/flag=}" ) return fi if [[ "${arg}" =~ "overlay=" ]]; then @@ -1574,14 +1577,14 @@ subcommand_use() { ############################################################################## # -# unuse directory|group|release... +# unuse directory|group|release_stage|... # 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. + Remove the given modulefiles directory, group, release stage, + flag or overlay from the search path. ' subcommand_unuse() { @@ -1670,14 +1673,18 @@ subcommand_unuse() { local arg=$1 - if is_release "${arg}"; then - # argument is release - std::remove_path UsedReleases "${arg}" + if is_release_stage "${arg}"; then + # argument is release stage + std::remove_path UsedReleaseStages "${arg}" return fi if [[ "${arg}" =~ "flag=" ]]; then # argument is flag - unset UseFlags["${arg/flag=}"] + local flag="${arg/flag=}" + local i + for i in ${!UsedFlags[@]}; do + [[ ${UsedFlags[i]} == ${flag} ]] && unset UsedFlags[i] + done return fi if [[ ${arg} =~ ^overlay= ]]; then @@ -1803,17 +1810,17 @@ reset_modulepath() { reset_used_groups() { UsedGroups='' - local group - for group in ${PMODULES_DEFAULT_GROUPS}; do - std::prepend_path UsedGroups "${group}" - done - g_env_must_be_saved='yes' + local group + for group in ${DefaultGroups}; do + std::append_path UsedGroups "${group}" + done + g_env_must_be_saved='yes' } reset_used_releases() { - declare -g UsedReleases='' - for r in ${PMODULES_DEFAULT_RELEASES//:/ }; do - std::append_path UsedReleases "${r}" + declare -g UsedReleaseStages='' + for r in ${DefaultReleaseStages//:/ }; do + std::append_path UsedReleaseStages "${r}" done g_env_must_be_saved='yes' } @@ -1843,17 +1850,20 @@ init_manpath() { } pmodules_init() { + source "${pmodules_config_file}" || \ + std::die 3 "Oops: cannot parse config file -- %s\n" \ + "${pmodules_config_file}" + declare -gx LOADEDMODULES='' declare -gx _LMFILES_='' - - declare -Ag OverlayDict=([${PMODULES_ROOT}]="0") - declare -ag OverlayList=( "${PMODULES_ROOT}" ) - declare -g UsedGroups='' + declare -gx UsedGroups='' declare -gx MODULEPATH='' declare -Ag GroupDepths='()' - unset UseFlags - declare -Ag UseFlags=() - declare -g Version="${PMODULES_VERSION}" + declare -ag UsedFlags=() + declare -g Version="${PMODULES_VERSION}" + declare -Ag OverlayDict=([${PMODULES_ROOT}]="0") + declare -ag OverlayList=( "${PMODULES_ROOT}" ) + reset_used_groups reset_modulepath reset_used_releases @@ -2049,7 +2059,7 @@ subcommand_clear() { # 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 ' +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' Help[search]=' @@ -2059,7 +2069,7 @@ USAGE: for modules whose name match the argument. SWITCHES: - -a|--all-releases + -a|--all-release-stages Search within all releases. --all-deps @@ -2068,10 +2078,10 @@ 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. + --release-stage=RELEASE_STAGE + Search for modules within this release stage. You can specify + this switch multiple times. Without this switch, the release + stages in use will be searched. --verbose vebose output @@ -2131,7 +2141,7 @@ subcommand_search() { print_header_default() { std::info '' - std::info "${fmt}" "Module" "Release" "Group" "Requires" + std::info "${fmt}" "Module" "Rel.stage" "Group" "Requires" std::info '-%.0s' $(seq 1 ${cols}) } @@ -2170,7 +2180,7 @@ subcommand_search() { print_header_verbose() { std::info '' - std::info "${fmt}" "Module" "Release" "Group" "Dependencies/Modulefile" + std::info "${fmt}" "Module" "Rel.stage" "Group" "Dependencies/Modulefile" std::info '-%.0s' $(seq 1 ${cols}) } @@ -2264,19 +2274,18 @@ subcommand_search() { local modulepath=( ${src_prefix[@]/%//${group}/modulefiles$s} ) # get and print all available modules in $mpath - # with respect to the requested releases - # tmpfile: module/version release group group- - # dependencies... + # with respect to the requested release stage + # tmpfile: module/version rel_stage group dependencies... local mods get_available_modules \ mods \ "${module}" \ - "${opt_use_releases}" \ + "${opt_use_rel_stages}" \ "${modulepath[@]}" \ for (( i=0; i<${#mods[@]}; i+=3 )); do local name=${mods[i]} - local release=${mods[i+1]} + local rel_stage=${mods[i+1]} local modulefile=${mods[i+2]} if (( ${#name} > max_len_modulename)); then @@ -2304,7 +2313,7 @@ subcommand_search() { unset IFS fi - echo ${name} ${release} ${group} ${modulefile} \ + echo ${name} ${rel_stage} ${group} ${modulefile} \ ${deps[@]} >> "${tmpfile}" done done @@ -2330,19 +2339,19 @@ subcommand_search() { opt_print_csv='yes' opt_print_header='no' ;; - --release | --release=* ) + --release-stage | --release-stage=* ) if [[ "$1" == "--release" ]]; then local arg=$2 shift else local arg=${1/--release=} fi - is_release "${arg}" || \ + is_release_stage "${arg}" || \ std::die 1 "%s %s: %s -- %s" \ "${CMD}" 'search' \ - "illegal release name" \ + "illegal release stage" \ "${arg}" - opt_use_releases+="${arg}:" + opt_use_rel_stages+="${arg}:" ;; --with | --with=* ) if [[ "$1" == --with ]]; then @@ -2364,7 +2373,7 @@ subcommand_search() { done ;; -a | --all-releases ) - opt_use_releases="${PMODULES_DEFINED_RELEASES}" + opt_use_rel_stages+="${ReleaseStages}" ;; --src ) # :FIXME: do we have to add some sanity checks here? @@ -2389,8 +2398,8 @@ subcommand_search() { local -a src_prefix=( "${OverlayList[@]}" ) fi - if [[ "${opt_use_releases}" == ":" ]]; then - opt_use_releases=":${UsedReleases}:" + if [[ "${opt_use_rel_stages}" == ":" ]]; then + opt_use_rel_stages=":${UsedReleaseStages}:" fi if [[ ${#modules[@]} == 0 ]]; then @@ -2476,7 +2485,7 @@ subcommand_help() { print_help "${arg}" else # :FIXME: print help of newest *available* module - # (respecting UsedReleases) + # (respecting UsedReleaseStages) "${modulecmd}" "${Shell}" "${subcommand}" "${arg}" fi done @@ -2737,8 +2746,39 @@ if [[ -n ${PMODULES_ENV} ]]; then # the Pmodules version changed! declare -g Version="${PMODULES_VERSION}" _init_overlay_vars + # renamed in version 1.0.0rc10 and type changed from + # associative array to normal array + if [[ -v UseFlags ]]; then + declare -a UsedFlags=( "${!UseFlags[@]}" ) + unset UseFlags + fi + if [[ ! -v UsedFlags ]]; then + declare -a UsedFlags=() + fi + if [[ -v UsedReleases ]]; then + declare -- UsedReleaseStages="${UsedReleases}" + unset UsedReleases + fi + if [[ -v PMODULES_DEFAULT_GROUPS ]]; then + declare -- DefaultGroups="${PMODULES_DEFAULT_GROUPS}" + unset PMODULES_DEFAULT_GROUPS + fi + if [[ -v PMODULES_DEFINED_RELEASES ]]; then + declare -- ReleaseStages="${PMODULES_DEFINED_RELEASES}" + unset PMODULES_DEFINED_RELEASES + fi + if [[ -v PMODULES_DEFAULT_RELEASES ]]; then + declare -- DefaultReleaseStages="${PMODULES_DEFAULT_RELEASES}" + unset PMODULES_DEFAULT_RELEASES + fi g_env_must_be_saved='yes' fi + if [[ -v DefaultGroups ]] || [[ -v DefaultReleaseStages ]] || [[ -v ReleaseStages ]]; then + source "${pmodules_config_file}" || \ + std::die 3 "Oops: cannot parse config file -- %s\n" \ + "${pmodules_config_file}" + + fi else pmodules_init fi diff --git a/Pmodules/profile.bash.in b/Pmodules/profile.bash.in index 3cc380c..f25eee8 100644 --- a/Pmodules/profile.bash.in +++ b/Pmodules/profile.bash.in @@ -3,36 +3,11 @@ # The following settings are system defaults. They can be (re-)defined # in a system wide profile or in a user's profile. -# set groups which should be available after initialization -: ${PMODULES_DEFAULT_GROUPS:='Tools Programming'} - -# set releases which should be available after initialization -: ${PMODULES_DEFAULT_RELEASES:='stable'} - # set default version : ${PMODULES_VERSION:=@PMODULES_VERSION@} -############################################################################# -# N O C H A N G E S B E L O W T H I S L I N E ! # -# -# Notes: -# - PMODULES_ROOT is derived from the location of this file. -# - Some for PMODULES_CONFIG_DIR. -# - The Pmodules software must be installed in -# ${PMODULES_ROOT}/Tools/Pmodules/${PMODULES_VERSION} -# - -export PMODULES_DEFAULT_GROUPS -export PMODULES_DEFAULT_RELEASES -export PMODULES_VERSION - -declare -x PMODULES_MODULEFILES_DIR='modulefiles' -declare -x PMODULES_DEFINED_RELEASES=':unstable:stable:deprecated:' - declare -x PMODULES_ROOT=$(cd $(dirname "${BASH_SOURCE}")/.. && pwd) -declare -x PMODULES_CONFIG_DIR=$(basename $(cd $(dirname "${BASH_SOURCE}") && pwd)) declare -x PMODULES_HOME="${PMODULES_ROOT}/Tools/Pmodules/${PMODULES_VERSION}" -declare -x PMODULES_DIR="${PMODULES_HOME}" test -r "${PMODULES_HOME}/init/bash" && source "$_" diff --git a/Pmodules/profile.csh.in b/Pmodules/profile.csh.in index 0047bdb..b00013e 100755 --- a/Pmodules/profile.csh.in +++ b/Pmodules/profile.csh.in @@ -1,7 +1,7 @@ #!/bin/tcsh -setenv PMODULES_DEFAULT_GROUPS 'Tools Programming' -setenv PMODULES_DEFAULT_RELEASES 'stable' +setenv DefaultGroups 'Tools Programming' +setenv DefaultReleaseStages 'stable' if ( ! $?PMODULES_VERSION ) then setenv PMODULES_VERSION "@PMODULES_VERSION@" endif @@ -14,7 +14,7 @@ endif ############################################################################# setenv PMODULES_MODULEFILES_DIR 'modulefiles' -setenv PMODULES_DEFINED_RELEASES ':unstable:stable:deprecated:' +setenv ReleaseStages ':unstable:stable:deprecated:' setenv PMODULES_ROOT "@PMODULES_ROOT@" setenv PMODULES_CONFIG_DIR 'config' diff --git a/Pmodules/profile.zsh.in b/Pmodules/profile.zsh.in index 83a2ac9..8077e79 100644 --- a/Pmodules/profile.zsh.in +++ b/Pmodules/profile.zsh.in @@ -7,12 +7,12 @@ # ${PMODULES_ROOT}/Tools/Pmodules/${PMODULES_VERSION} # -declare -xa PMODULES_DEFAULT_GROUPS -declare -xa PMODULES_DEFAULT_RELEASES +declare -xa DefaultGroups +declare -xa DefaultReleaseStages declare -x PMODULES_VERSION -: ${PMODULES_DEFAULT_GROUPS:=(Tools Programming)} -: ${PMODULES_DEFAULT_RELEASES:=(stable)} +: ${DefaultGroups:=(Tools Programming)} +: ${DefaultReleaseStages:=(stable)} : ${PMODULES_VERSION:=@PMODULES_VERSION@} ############################################################################# @@ -20,7 +20,7 @@ declare -x PMODULES_VERSION ############################################################################# declare -x PMODULES_MODULEFILES_DIR='modulefiles' -declare -x PMODULES_DEFINED_RELEASES=':unstable:stable:deprecated:' +declare -x ReleaseStages=':unstable:stable:deprecated:' declare -x PMODULES_ROOT=$(cd $(dirname "${(%):-%N}")/.. && pwd) declare -x PMODULES_CONFIG_DIR=$(basename $(cd $(dirname "${(%):-%N}") && pwd)) diff --git a/Pmodules/zsh b/Pmodules/zsh index 80dc338..f1a0a4c 100644 --- a/Pmodules/zsh +++ b/Pmodules/zsh @@ -70,7 +70,7 @@ declare -x _LMFILES_='' # build initial MODULEPATH declare -x MODULEPATH='' typeset -T MODULEPATH modulepath -for group in ${PMODULES_DEFAULT_GROUPS[@]}; do +for group in ${DefaultGroups[@]}; do dir="${PMODULES_ROOT}/${group}/${PMODULES_MODULEFILES_DIR}" modulepath=( "${dir}" ${(m)modulepath:#${dir}} ) done @@ -78,16 +78,16 @@ done # build initial list of used releases declare -x UsedReleases='' typeset -T UsedReleases usedreleases -for r in ${PMODULES_DEFAULT_RELEASES[@]}; do +for r in ${DefaultReleaseStages[@]}; do usedreleases=( "${r}" ${(m)usedreleases:#${r}} ) done -eval $(save_env UsedReleases PMODULES_DEFAULT_RELEASES PMODULES_DEFAULT_GROUPS PMODULES_DEFINED_RELEASES) +eval $(save_env UsedReleases DefaultReleaseStages DefaultGroups ReleaseStages) unset UsedReleases -unset PMODULES_DEFAULT_RELEASES -unset PMODULES_DEFAULT_GROUPS -unset PMODULES_DEFINED_RELEASES +unset DefaultReleaseStages +unset DefaultGroups +unset ReleaseStages # initialize MANPATH with output of `man --path` if not set [[ -z "${MANPATH}" ]] && manpath=$( man --path ) diff --git a/Tools/tcllib/build b/Tools/tcllib/build index af189fe..ea151ba 100755 --- a/Tools/tcllib/build +++ b/Tools/tcllib/build @@ -1,5 +1,5 @@ #!/usr/bin/env modbuild pbuild::set_download_url "https://core.tcl-lang.org/tcllib/uv/$P-$V.tar.xz" -#uild::install_docfiles 'license.terms' 'README.md' + diff --git a/build b/build index cdd6ac4..755daf8 100755 --- a/build +++ b/build @@ -495,6 +495,9 @@ pmodules::install() { sed "${sed_cmd}" "${SRC_DIR}/modmanage.bash.in" > "${PMODULES_HOME}/libexec/modmanage.bash" chmod 0755 "${PMODULES_HOME}/libexec/modmanage.bash" + test -e "${PMODULES_ROOT}/${CONFIG_DIR}/Pmodules.conf" || \ + install -m 0644 "${SRC_DIR}/Pmodules.conf" "${PMODULES_ROOT}/${CONFIG_DIR}" + install -m 0644 "${SRC_DIR}/bash" "${PMODULES_HOME}/init" install -m 0644 "${SRC_DIR}/bash_completion" "${PMODULES_HOME}/init" install -m 0644 "${SRC_DIR}/csh" "${PMODULES_HOME}/init" diff --git a/config/modbuild.conf.in b/config/modbuild.conf.in index 60d33c3..cfce2aa 100644 --- a/config/modbuild.conf.in +++ b/config/modbuild.conf.in @@ -12,7 +12,7 @@ declare -x PMODULES_MODULEFILES_DIR='modulefiles' declare -x PMODULES_HOME="${PMODULES_ROOT}/Tools/Pmodules/${PMODULES_VERSION}" -declare -x PMODULES_DEFAULT_GROUPS='Tools Programming' -declare -x PMODULES_DEFINED_RELEASES=':unstable:stable:deprecated:' -declare -x PMODULES_DEFAULT_RELEASES='stable' +declare -x DefaultGroups='Tools Programming' +declare ReleaseStages=':unstable:stable:deprecated:' +declare DefaultReleaseStages='stable'