mirror of
https://github.com/Pmodules/Pmodules.git
synced 2026-06-23 00:07:57 +02:00
189 lines
4.6 KiB
Bash
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:
|