Files
Pmodules/Pmodules/libpmodules.bash.in
T

189 lines
4.6 KiB
Bash

#!/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
VERSION = @MODULES_VERSION@
"
#
# 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: