#!/bin/bash declare PMODULES_MODULEFILES_DIR='modulefiles' declare PMODULES_CONFIG_DIR='config' declare PMODULES_VERSION='@PMODULES_VERSION@' declare -A GroupDepths=() declare -A Subcommands=() declare -A Options=() declare -A Help=() declare -a Overlays=() declare -A OverlayInfo declare -a UsedOverlays declare -A Dir2OverlayMap declare -r ol_normal='n' declare -r ol_hiding='h' declare -r ol_replacing='r' # initialize help text of 'module --version' Help['version']=" Pmodules @PMODULES_VERSION@ using Tcl Environment Modules Copyright GNU GPL v2 " # # display help text for command given in $1 # print_help() { echo -e "${Help[$1]}" 1>&2 std::die 1 } # # compute depth of modulefile directory. # # Args: # $1: absolute path of a modulefile directory # compute_group_depth () { local -n result="$1" local -r dir="$2" if [[ ! -d "${dir}" ]]; then ${mkdir} -p "${dir}" || \ std::die 1 "Cannot create directory -- ${dir}" fi local group=${dir%/*} local group=${group##*/} result=$(${find} "${dir}" -depth \( -type f -o -type l \) \ -printf "%d" -quit 2>/dev/null) (( result-=2 )) # if a group doesn't contain a modulefile, depth is negativ # :FIXME: better solution? (( result < 0 )) && (( result = 0 )) } # # (Re-)Scan available groups in given overlays and compute group depth's # # Args: # $@: overlay names # scan_groups () { local ol local depth for ol in "$@"; do local mod_root="${OverlayInfo[${ol}:mod_root]}" local dir for dir in ${mod_root}/*/${PMODULES_MODULEFILES_DIR}; do local group="${dir%/*}" group="${group##*/}" if [[ ! -v GroupDepths[${group}] ]]; then compute_group_depth depth "${dir}" GroupDepths[$group]=${depth} fi Dir2OverlayMap[${dir%/${PMODULES_MODULEFILES_DIR}*}]="${ol}" done done } pm::read_config(){ local -a config_files=() _get_config_files(){ # # return array with overlay configuration files # # Args: # $1 [upvar] result local -n fnames="$1" # user defined via environment variable if [[ -v PMODULES_OVERLAYS_DEF ]]; then test -r "${PMODULES_OVERLAYS_DEF}" || \ std::die 3 \ "%s -- %s" \ "overlay definition file is not readable" \ "$_" fnames+=("${PMODULES_OVERLAYS_DEF}") fi # user defined if [[ -r "${HOME}/.Pmodules/Pmodules.yaml" ]]; then fnames+=("${HOME}/.Pmodules/Pmodules.yaml") fi # system config file test -r "${PMODULES_HOME%%/Tools*}/config/Pmodules.yaml" || \ std::die 3 \ "%s %s -- %s" \ "base overlay definition file" \ "does not exist or is not readable" \ "$_" fnames+=("${PMODULES_HOME%%/Tools*}/config/Pmodules.yaml") } _get_ol_names(){ # # get the names of all overlays # local -n fnames="$1" ${yq} -Ne eval-all '. as $item ireduce ({}; . *+ $item) |.Overlays|keys()' \ "${fnames[@]}" | awk '{print $2}' } _get_config_files config_files eval $(std::parse_yaml "${config_files[-1]}" 'cfg_') [[ -v cfg_DefaultGroups ]] && DefaultGroups="${cfg_DefaultGroups}" [[ -v cfg_DefaultReleaseStages ]] && DefaultReleaseStages="${cfg_DefaultReleaseStages}" [[ -v cfg_ReleaseStages ]] && ReleaseStages="${cfg_ReleaseStages}" unset ${!cfg_*} # # loop over all overlays and save config in OverlayInfo and Dir2OverlayMap # # - at least install_root must be specified # - modulefiles_root default so install_root # - the type defaults to ${ol_normal} # Overlays=( $(_get_ol_names config_files) ) local ol='' for ol in "${Overlays[@]}"; do eval $(${yq} -Ne eval-all \ ". as \$item ireduce ({}; . *+ \$item) |.Overlays.${ol}" \ "${config_files[@]}" | \ sed 's/: /=/; s/\(.*\)/local \1/') [[ -n ${install_root} ]] || \ std::die 3 \ "install_root missing for overlay -- ${ol}" [[ -d ${install_root} ]] || \ std::die 3 \ "Invalid installation root directory for overlay '${ol}' -- ${install_root}" OverlayInfo[${ol}:inst_root]="${install_root}" : ${modulefiles_root:=${install_root}} [[ -d ${modulefiles_root} ]] || \ std::die 3 \ "Invalid modulefiles root directory for overlay '${ol}' -- ${modulefiles_root}" OverlayInfo[${ol}:mod_root]="${modulefiles_root}" Dir2OverlayMap[${modulefiles_root}]="${ol}" : ${type:=${ol_normal}} case ${type} in ${ol_normal} | ${ol_replacing} | ${ol_hiding} ) : ;; * ) std::die 3 "Invalid type for overlay '${ol}' -- ${type}" ;; esac OverlayInfo[${ol}:type]="${type}" OverlayInfo[${ol}:used]='no' unset type modulefiles_root install_root done } # Local Variables: # mode: sh # sh-basic-offset: 8 # tab-width: 8 # End: