Commit 9b106fd4 authored by gsell's avatar gsell
Browse files

Bootstrap (building Pmodules itself) removed

parent 2601c606
environment.bash
modulecmd.bash
modmanage.bash
#!/usr/bin/env modbuild
TCL_DIR="${PMODULES_ROOT}/Tools/Pmodules/${PMODULES_VERSION}"
PATH="${TCL_DIR}/bin:${PATH}"
pbuild::configure() {
case ${OS} in
Linux )
declare -x LIBS="-lz -lpthread"
;;
Darwin )
declare -x LIBS="-lz -framework CoreFoundation"
;;
esac
CPPFLAGS="-DUSE_INTERP_ERRORLINE" "${MODULE_SRCDIR}"/configure \
--prefix="${PREFIX}" \
--exec-prefix="${PREFIX}" \
--with-module-path="${PMODULES_ROOT}/Tools/${PMODULES_MODULEFILES_DIR}" \
--with-tcl="${TCL_DIR}/lib" \
--without-x \
--disable-versioning \
|| exit 1
}
pbuild::post_install() {
rm -v ${PREFIX}/Modules/bin/add.modules
rm -v ${PREFIX}/Modules/bin/mkroot
rm -rfv ${PREFIX}/Modules/modulefiles
mv -v ${PREFIX}/Modules/share/man/man1/module.1 ${PREFIX}/share/man/man1
mv -v ${PREFIX}/Modules/share/man/man4/modulefile.4 ${PREFIX}/share/man/man4
rmdir ${PREFIX}/Modules/bin
rmdir ${PREFIX}/Modules/share/man/man1
rmdir ${PREFIX}/Modules/share/man/man4
rmdir ${PREFIX}/Modules/share/man
rmdir ${PREFIX}/Modules/share
rmdir ${PREFIX}/Modules
}
# fake module command
module() {
:
}
# use system gcc to compile
declare -rx CC=gcc
pbuild::add_to_group 'Tools'
pbuild::make_all
# Local Variables:
# mode: sh
# sh-basic-offset: 8
# tab-width: 8
# End:
#!/bin/bash
#############################################################################
# bash 3 or newer ...
#
if [ ${BASH_VERSINFO:-0} -lt 3 ]; then
echo "BASH version ${BASH_VERSION} ist not supported! You need at least version 3..."
return
fi
#############################################################################
# implement module comand as function
#
module() {
local -r modulecmd="${PMODULES_HOME}/bin/modulecmd"
local -a args=()
local -a switches=()
while (( $# > 0 ));do
case $1 in
-* )
switches+=( $1 )
;;
[/~a-zA-Z]* )
args+=( $1 )
;;
esac
shift
done
[[ ${#args[@]} == 0 ]] && args+=( 'help' )
[[ ${#args[@]} == 1 ]] && args+=( '--' )
# we have to eval here, otherwise we cannot do something like
# $ module load gcc/5.2.0 openmpi/1.8.8 hdf5/1.8.15
local -i i=1
for (( i=1; i < ${#args[@]}; i++ )); do
eval $( "${modulecmd}" bash "${args[0]}" "${switches[@]}" "${args[i]}" )
done
}
export -f module
#############################################################################
# helper functions
#
std::append_path () {
local -r P=$1
local -r d=$2
if ! echo ${!P} | egrep -q "(^|:)${d}($|:)" ; then
if [[ -z ${!P} ]]; then
eval $P=${d}
else
eval $P="${!P}:${d}"
fi
fi
}
#
# Replace or remove a directory in a path variable.
#
# To remove a dir:
# std::replace_path PATH <pattern>
#
# To replace a dir:
# std::replace_path PATH <pattern> /replacement/path
#
# Args:
# $1 name of the shell variable to set (e.g. PATH)
# $2 a grep pattern identifying the element to be removed/replaced
# $3 the replacement string (use "" for removal)
#
# Based on solution published here:
# https://stackoverflow.com/questions/273909/how-do-i-manipulate-path-elements-in-shell-scripts
#
std::replace_path () {
local -r path=$1
local -r removepat=$2
local -r replacestr=$3
local -r removestr=$(echo "${!path}" | tr ":" "\n" | grep -m 1 "^$removepat\$")
export $path=$(echo "${!path}" | tr ":" "\n" | sed "s:^${removestr}\$:${replacestr}:" |
sed '/^\s*$/d' | tr "\n" ":" | sed -e 's|^:||' -e 's|:$||')
}
save_env() {
local s=''
while (( $# > 0 )); do
s+="$( typeset -p $1 );"
shift
done
echo export PMODULES_ENV=$( "${PMODULES_HOME}/bin/base64" --wrap=0 <<< "$s" )
}
#module purge
#############################################################################
# setup environment
#
declare -x LOADEDMODULES=''
declare -x _LMFILES_=''
declare -x PMODULES_USED_GROUPS=''
declare -x MODULEPATH=''
for group in ${PMODULES_DEFAULT_GROUPS//:/ }; do
std::append_path MODULEPATH "${PMODULES_ROOT}/${group}/${PMODULES_MODULEFILES_DIR}"
std::append_path PMODULES_USED_GROUPS "${group}"
done
declare -x UsedReleases=''
for r in ${PMODULES_DEFAULT_RELEASES//:/ }; do
std::append_path UsedReleases "${r}"
done
eval $(save_env UsedReleases PMODULES_DEFAULT_RELEASES PMODULES_DEFAULT_GROUPS PMODULES_DEFINED_RELEASES)
unset UsedReleases
unset PMODULES_DEFAULT_RELEASES
unset PMODULES_DEFAULT_GROUPS
unset PMODULES_DEFINED_RELEASES
std::replace_path PATH "${PMODULES_HOME%/*}/.*"
std::replace_path MANPATH "${PMODULES_HOME%/*}/.*"
std::append_path PATH "${PMODULES_HOME}/bin"
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
#############################################################################
# initialize bash completion
#
if [[ -r "${PMODULES_HOME}/init/bash_completion" ]]; then
source "${PMODULES_HOME}/init/bash_completion"
fi
#############################################################################
# legacy...
#
unset MODULE_VERSION
unset MODULE_VERSION_STACK
unset MODULESHOME
# Local Variables:
# mode: sh
# sh-basic-offset: 8
# tab-width: 8
# End:
#
# Bash commandline completion (bash 3.0 and above) for Modules 3.2.10
#
_module_avail() {
"${PMODULES_HOME}"/bin/modulecmd bash -t avail 2>&1 | sed '
/:$/d;
/:ERROR:/d;
s#^\(.*\)/\(.\+\)(default)#\1\n\1\/\2#;
s#/(default)##g;
s#/*$##g;'
}
_module_not_yet_loaded() {
comm -23 <(_module_avail|sort) <(tr : '\n' <<<${LOADEDMODULES}|sort)
}
_module_long_arg_list() {
local cur="$1" i
if [[ ${COMP_WORDS[COMP_CWORD-2]} == sw* ]]
then
COMPREPLY=( $(compgen -W "$(_module_not_yet_loaded)" -- "$cur") )
return
fi
for ((i = COMP_CWORD - 1; i > 0; i--))
do case ${COMP_WORDS[$i]} in
add|load)
COMPREPLY=( $(compgen -W "$(_module_not_yet_loaded)" -- "$cur") )
break;;
rm|remove|unload|switch|swap)
COMPREPLY=( $(IFS=: compgen -W "${LOADEDMODULES}" -- "$cur") )
break;;
esac
done
}
_module() {
local cur="$2" prev="$3" cmds opts
COMPREPLY=()
cmds="add apropos avail clear dependencies display help\
initadd initclear initlist initprepend initrm initswitch\
keyword list load purge refresh rm search show swap switch sync\
unload unuse update use whatis"
opts="-c -f -h -i -l -s -t -u -v -H -V\
--create --force --help --human --icase\
--long --silent --terse --userlvl --verbose --version"
case "$prev" in
add|load) COMPREPLY=( $(compgen -W "$(_module_not_yet_loaded)" -- "$cur") );;
rm|remove|unload|switch|swap)
COMPREPLY=( $(IFS=: compgen -W "${LOADEDMODULES}" -- "$cur") );;
unuse) COMPREPLY=( $(IFS=: compgen -W "${MODULEPATH}" -- "$cur") );;
use|*-a*) ;; # let readline handle the completion
-u|--userlvl) COMPREPLY=( $(compgen -W "novice expert advanced" -- "$cur") );;
display|help|show|whatis)
COMPREPLY=( $(compgen -W "$(_module_avail)" -- "$cur") );;
*) if test $COMP_CWORD -gt 2
then
_module_long_arg_list "$cur"
else
case "$cur" in
# The mappings below are optional abbreviations for convenience
ls) COMPREPLY="list";; # map ls -> list
r*) COMPREPLY="rm";; # also covers 'remove'
sw*) COMPREPLY="switch";;
-*) COMPREPLY=( $(compgen -W "$opts" -- "$cur") );;
*) COMPREPLY=( $(compgen -W "$cmds" -- "$cur") );;
esac
fi;;
esac
}
complete -o default -F _module module
if ($?tcsh) then
set modules_shell="tcsh"
else
set modules_shell="csh"
endif
set exec_prefix = $PMODULES_HOME/bin'
set prefix=""
set postfix=""
if ( $?histchars ) then
set histchar = `echo $histchars | cut -c1`
set _histchars = $histchars
set prefix = 'unset histchars;'
set postfix = 'set histchars = $_histchars;'
else
set histchar = \!
endif
if ($?prompt) then
set prefix = "$prefix"'set _prompt="$prompt";set prompt="";'
set postfix = "$postfix"'set prompt="$_prompt";unset _prompt;'
endif
if ($?noglob) then
set prefix = "$prefix""set noglob;"
set postfix = "$postfix""unset noglob;"
endif
set postfix = "set _exit="'$status'"; $postfix; test 0 = "'$_exit;'
alias module $prefix'eval `'$exec_prefix'/modulecmd '$modules_shell' '$histchar'*`; '$postfix
unset exec_prefix
unset prefix
unset postfix
if (! $?MODULEPATH ) then
setenv MODULEPATH `sed -n 's/[ #].*$//; /./H; $ { x; s/^\n//; s/\n/:/g; p; }' ${MODULESHOME}/init/.modulespath`
endif
if (! $?LOADEDMODULES ) then
setenv LOADEDMODULES ""
endif
#!/usr/bin/env bash
# Hardcoded path to dialog software
DIALOG_CMD=$PMODULES_HOME/bin/dialog
declare -a modlist # module info
declare -A selected # module info indices selected
declare -a depcnt # dependency reference counter by module info index
declare -A uidmap # unique module id to module info index
declare -A modmap # map module names to module info indices for modlist
declare -A fdmap # module name to family definition mapping
declare -A fmmap # module name to family member mapping
declare -a relmap # module info index to release mapping
declare tempfile # temporary dialog results
set_difference() { # $1 \ $2
local -a operand1=($1)
local -a operand2=($2)
local -A members
local -i elem
for elem in "${operand1[@]}"; do
members[$elem]=1
done
for elem in "${operand2[@]}"; do
unset members[$elem]
done
echo ${!members[@]}
}
set_merge() { # $1 U $2 (where $1 and $2 are disjoint)
if [[ -z "$1" ]]; then
echo "$2"
elif [[ -z "$2" ]]; then
echo "$1"
else
echo "$1 $2"
fi
}
set_union() { # $1 U $2 (sorted)
local -a operand1=($1)
local -a operand2=($2)
local -A members
local -i elem
for elem in ${operand1[@]} ${operand2[@]}; do
members[$elem]=1
done
{ IFS=$'\n'; echo "${!members[*]}"; } | sort -n
}
# unique id for a module
unique_id() { # $1: module info index
local -a minfo=( ${modlist[$1]} )
if (( ${#minfo[@]} < 4 )); then
echo ${minfo[0]}
else
echo "${minfo[@]:3} ${minfo[0]}"
fi
}
mod_path() { # $1: module info index
local -i i
local -a m=(${modlist[$1]})
local res="$PMODULES_ROOT/${fmmap[${m[0]%%/*}]}/${m[0]}"
for (( i=${#m[@]}; i>3; i-- )); do
res+="/${m[i-1]}"
done
echo "$res"
}
calc_deps() { # $1: module info index
local dpath="$(mod_path $1)/.dependencies"
[[ ! -r "$dpath" ]] && return
local -a d=( $(< "$dpath") ) # dependencies as versioned module names
local -A p # map family to versioned module name
local -A did # map dependency (versioned module name) to unique module id
local -a deps # set of module info indices
local m n f
for m in ${d[@]}; do
n=${m%%/*}
f=${fdmap[$n]}
[[ -n "$f" ]] && { p[$f]=$m; }
f=${fmmap[$n]}
if [[ -z "$f" ]]; then
did[$m]=$m
else
n=${p[$f]}
if [[ -z "$n" ]]; then
did[$m]=$m
else
did[$m]="${did[$n]} $m"
fi
fi
deps+=( ${uidmap["${did[$m]}"]} )
done
echo "${deps[@]}"
}
update_deps() { # $1: 1-add dependency, -1-remove dependency $2: set of module info indices
[[ -z "$2" ]] && return
local -a q=($2) # work queue
local deps="" # set of dependencies
local -i m
while (( ${#q[@]} > 0 )); do
m=${q[-1]}
unset q[-1]
d="$(calc_deps $m)"
[[ -z "$d" ]] && continue
d="$(set_difference "$d" "$deps")"
[[ -z "$d" ]] && continue
q+=($d)
deps="$(set_merge "$d" "$deps")"
done
for m in $deps; do
let depcnt[m]+=$1
done
}
# "$1": source module environment
find_modules() {
# construct modlist/modmap/uidmap/depcnt/fmmap/relmap arrays from module search output
local -a mc # module info components
local -i i=0
local current=""
local name m uid
while read m; do
mc=($m)
[[ "${mc[2]}" == "Legacy" ]] && continue # filter out legacy stuff
name=${mc[0]%%/*}
if [[ "$current" != "$name" ]]; then
modmap[$name]="$i"
current=$name
else
modmap[$name]+=" $i"
fi
modlist[i]=$m
uid="$(unique_id $i)"
uidmap["$uid"]=$i
depcnt[i]=0
[[ -z ${fmmap[$name]} ]] && { fmmap[$name]=${mc[2]}; }
relmap[i]=${mc[1]}
i+=1
done < <(${PMODULES_HOME}/bin/modulecmd bash search --src="$1" --no-header -a 2>&1)
}
# "$1": source module environment
find_families() {
# construct fdmap
local -a t # tcl file components
local l s n
while read l; do
s=${l%%:*}
s=${s%/*}
n=${s##*/}
if [[ -z "${fdmap[$n]}" ]]; then
t=( ${l##*:} )
fdmap[$n]=${t[-1]//\"}
fi
done < <(grep -R set-family "$1/*/${PMODULES_MODULEFILES_DIR}")
}
select_uid() { # $1: module uid
local -a uidc=($1) # uid components
local name=${uidc[-1]%%/*} # module name
local midx=${uidmap["$1"]} # module info index
[[ -z "$midx" ]] && return
selected[$name]="$(set_union "${selected[$name]}" "$midx")"
update_deps 1 "$midx"
}
preselect() { # "$1": prefix for preselected modules
# module paths must not contain white space
[[ -z "$1" ]] && return
local -a mpc # module path components
local -i i
local uid n
pushd "$1/$PMODULES_MODULEFILES_DIR" > /dev/null || exit 1;
trap "popd" EXIT
for m in $(find . -follow -type f); do
n=${m##*/}
[[ "${n:0:1}" == "." ]] && continue
uid=""
mpc=( ${m//\// } )
for ((i=2; i<${#mpc[@]}-2; i+=2)); do
uid+="${mpc[i]}/${mpc[i+1]} "
done
uid+="${mpc[-2]}/${mpc[-1]}"
PMODULES_ROOT="$1" select_uid "$uid"
done
popd
trap - EXIT
}
is_dependency() { # $1: module name
local -a map=(${modmap[$1]})
local -i m
for ((m=0; m<${#map[@]}; m++)); do
(( ${depcnt[${map[m]}]} > 0 )) && return 0
done
return 1
}
dialog_1() {
local -a input
local marker
local m
for m in $(IFS=$'\n'; echo "${!modmap[*]}" | sort); do
marker=""
[[ -n ${selected[$m]} ]] && { marker+="*"; }
is_dependency $m && { marker+="+"; }
input+=($m "$marker$m")
done
$DIALOG_CMD --ok-label 'Select' \
--extra-button --extra-label 'Exit' \
--no-tags \
--menu Modules 50 80 50 "${input[@]}" 2>$tempfile
return $?
}
module_id() { # $@: module info components
echo "$1 ${@:4}"
}
module_release() { # $@: module info components
echo "$2"
}
dialog_2() { # $1: module name
local -a map=(${modmap[$1]})
local -a sel=(${selected[$1]})
local -i j # mapping index
local -i k=0 # selection index
local -a input
local marker minfo rel m s
for (( j=0; j!=${#map[@]}; j++ )); do
minfo=${modlist[${map[j]}]}
m="$(module_id $minfo)"
rel=" ($(module_release $minfo))"
[[ $rel = " (stable)" ]] && { rel=""; }
[[ "${map[j]}" = "${sel[k]}" ]] && { s="on"; k+=1; } || { s="off"; }
(( ${depcnt[${map[j]}]} > 0 )) && { marker="+"; l+=1; } || { marker=""; }
input+=( ${map[j]} "$marker$m$rel" $s )
done
$DIALOG_CMD --extra-button --extra-label 'Clear' --no-tags --checklist Versions 80 90 80 "${input[@]}" 2>$tempfile
return $?
}
# final dialog output
module_out() { # $1: module info index
local -a args=(${modlist[$1]})
echo "${args[@]}"
}
# "$1": prefix for preselected modules (destination module environment)
# "$2": prefix for selectable modules (source module environment)
module_picker() {
find_families "$2"
find_modules "$2"
preselect "$1"
tempfile=$(mktemp ${TMPDIR:-/tmp}/msyncXXXXXX) || {
echo "Unable to create temporary file!"
exit 1
}
trap "rm -f $tempfile" EXIT
local -i level=1
local -i operation=0 # 0: OK, 1: Cancel
local oldsel
local sel
local m
while (( level != 0 )); do
case $level in
1)
dialog_1