subcmd.tcl.in (modules-5.1.1.tar.bz2) | : | subcmd.tcl.in (modules-5.2.0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 33 | skipping to change at line 33 | |||
proc cmdModuleList {show_oneperline show_mtime search_match args} { | proc cmdModuleList {show_oneperline show_mtime search_match args} { | |||
set json [isStateEqual report_format json] | set json [isStateEqual report_format json] | |||
# load tags from loaded modules | # load tags from loaded modules | |||
cacheCurrentModules | cacheCurrentModules | |||
if {[llength $args] > 0} { | if {[llength $args] > 0} { | |||
defineModEqProc [isIcase] [getConf extended_default] | defineModEqProc [isIcase] [getConf extended_default] | |||
# match passed name against any part of loaded module names | # match passed name against any part of loaded module names | |||
set mtest [expr {{contains} in $search_match ? {matchin} : {match}}] | set mtest [expr {{contains} in $search_match ? {matchin} : {match}}] | |||
# use first arg as query to highlight as reportModules only accepts one | set search_queries $args | |||
# search specification | ||||
set searchquery [lindex $args 0] | ||||
# prepare header message which depend if search is performed | # prepare header message which depend if search is performed | |||
set loadedmsg {Currently Loaded Matching Modulefiles} | set loadedmsg {Currently Loaded Matching Modulefiles} | |||
} else { | } else { | |||
set searchquery {} | set search_queries {} | |||
set loadedmsg {Currently Loaded Modulefiles} | set loadedmsg {Currently Loaded Modulefiles} | |||
} | } | |||
# filter-out hidden loaded modules unless all module should be seen | # filter-out hidden loaded modules unless all module should be seen | |||
if {[getState hiding_threshold] > 1} { | if {[getState hiding_threshold] > 1} { | |||
set loadedmodlist [getLoadedModuleList] | set loadedmodlist [getLoadedModulePropertyList name] | |||
} else { | } else { | |||
set loadedmodlist [list] | set loadedmodlist [list] | |||
foreach mod [getLoadedModuleList] { | foreach mod [getLoadedModulePropertyList name] { | |||
if {![isModuleTagged $mod hidden-loaded 1]} { | if {![isModuleTagged $mod hidden-loaded 1]} { | |||
lappend loadedmodlist $mod | lappend loadedmodlist $mod | |||
} | } | |||
} | } | |||
} | } | |||
# same header msg if no module loaded at all whether search is made or not | # same header msg if no module loaded at all whether search is made or not | |||
set noloadedmsg [expr {[llength $loadedmodlist] == 0 ? {No Modulefiles\ | set noloadedmsg [expr {[llength $loadedmodlist] == 0 ? {No Modulefiles\ | |||
Currently Loaded.} : {No Matching Modulefiles Currently Loaded.}}] | Currently Loaded.} : {No Matching Modulefiles Currently Loaded.}}] | |||
skipping to change at line 105 | skipping to change at line 103 | |||
} | } | |||
set ::g_symbolHash($mod) [lsort -dictionary $sym_list] | set ::g_symbolHash($mod) [lsort -dictionary $sym_list] | |||
} | } | |||
set one_per_line [expr {$show_mtime || $show_oneperline}] | set one_per_line [expr {$show_mtime || $show_oneperline}] | |||
set show_idx [expr {!$show_mtime && [isEltInReport idx]}] | set show_idx [expr {!$show_mtime && [isEltInReport idx]}] | |||
set header [expr {!$json && [isEltInReport header] ? $loadedmsg :\ | set header [expr {!$json && [isEltInReport header] ? $loadedmsg :\ | |||
{noheader}}] | {noheader}}] | |||
set theader_cols [list hi Package 39 Versions 19 {Last mod.} 19] | set theader_cols [list hi Package 39 Versions 19 {Last mod.} 19] | |||
reportModules $searchquery $header {} terse $show_mtime $show_idx\ | reportModules $search_queries $header {} terse $show_mtime $show_idx\ | |||
$one_per_line $theader_cols loaded $loadedmodlist | $one_per_line $theader_cols loaded $loadedmodlist | |||
# display output key | # display output key | |||
if {!$show_mtime && !$json && [isEltInReport key]} { | if {!$show_mtime && !$json && [isEltInReport key]} { | |||
displayKey | displayKey | |||
} | } | |||
} | } | |||
} | } | |||
proc cmdModuleDisplay {args} { | proc cmdModuleDisplay {args} { | |||
skipping to change at line 282 | skipping to change at line 280 | |||
$elt]] | $elt]] | |||
# register resolution error if alias name matches search | # register resolution error if alias name matches search | |||
} elseif {[modEq $mod $elt]} { | } elseif {[modEq $mod $elt]} { | |||
set err_list($modname) [list $issuetype $issuemsg] | set err_list($modname) [list $issuetype $issuemsg] | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
version { | version { | |||
# report error of version target if matching query | # report error of version target if matching query | |||
set elt_target [getArrayKey mod_list [lindex $mod_list($elt) 1]\ | set elt_target [getArrayKey mod_list [lindex $mod_list($elt)\ | |||
$icase] | 1] $icase] | |||
if {[info exists mod_list($elt_target)] && [lindex\ | if {[info exists mod_list($elt_target)] && [lindex\ | |||
$mod_list($elt_target) 0] in [list invalid accesserr] &&\ | $mod_list($elt_target) 0] in [list invalid accesserr] &&\ | |||
[modEq $mod $elt]} { | [modEq $mod $elt]} { | |||
set err_list($elt_target) $mod_list($elt_target) | set err_list($elt_target) $mod_list($elt_target) | |||
} elseif {![info exists mod_list($elt_target)]} { | } elseif {![info exists mod_list($elt_target)]} { | |||
set extra_search($elt_target) [list $dir [modEq $mod $elt]] | set extra_search($elt_target) [list $dir [modEq $mod $elt]] | |||
} | } | |||
} | } | |||
invalid - accesserr { | invalid - accesserr { | |||
# register any error occurring on element matching search | # register any error occurring on element matching search | |||
skipping to change at line 367 | skipping to change at line 365 | |||
# interpret all modulefile we got for each modulepath | # interpret all modulefile we got for each modulepath | |||
foreach dir $dir_list { | foreach dir $dir_list { | |||
if {[info exists interp_save($dir)]} { | if {[info exists interp_save($dir)]} { | |||
array unset interp_list | array unset interp_list | |||
array set interp_list $interp_save($dir) | array set interp_list $interp_save($dir) | |||
set foundmod 1 | set foundmod 1 | |||
set display_list {} | set display_list {} | |||
# interpret every modulefiles obtained to get their whatis text | # interpret every modulefiles obtained to get their whatis text | |||
foreach elt [lsort -dictionary [array names interp_list]] { | foreach elt [lsort -dictionary [array names interp_list]] { | |||
set ::g_whatis {} | set ::g_whatis {} | |||
##nagelfar ignore Suspicious variable name | ||||
execute-modulefile $interp_list($elt) $elt $elt $elt 0 | execute-modulefile $interp_list($elt) $elt $elt $elt 0 | |||
# treat whatis as a multi-line text | # treat whatis as a multi-line text | |||
if {$search eq {} || [regexp -nocase $search $::g_whatis]} { | if {$search eq {} || [regexp -nocase $search $::g_whatis]} { | |||
if {$json} { | if {$json} { | |||
lappend display_list [formatListEltToJsonDisplay $elt\ | lappend display_list [formatListEltToJsonDisplay $elt\ | |||
whatis a $::g_whatis 1] | whatis a $::g_whatis 1] | |||
} else { | } else { | |||
set eltsgr [string map $matchmodmap $elt] | set eltsgr [string map $matchmodmap $elt] | |||
foreach line $::g_whatis { | foreach line $::g_whatis { | |||
set linesgr [string map $matchsearchmap $line] | set linesgr [string map $matchsearchmap $line] | |||
lappend display_list "[string repeat { } [expr {20 -\ | lappend display_list "[string repeat { } [expr {20 -\ | |||
[string length $elt]}]]$eltsgr: $linesgr" | [string length $elt]}]]$eltsgr: $linesgr" | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
displayElementList $dir mp sepline 1 0 $display_list | displayElementList $dir mp sepline 1 0 0 $display_list | |||
} | } | |||
} | } | |||
lpopState mode | lpopState mode | |||
setState inhibit_errreport 0 | setState inhibit_errreport 0 | |||
# report errors if a modulefile was searched but not found | # report errors if a modulefile was searched but not found | |||
if {$mod ne {} && !$foundmod} { | if {$mod ne {} && !$foundmod} { | |||
# no error registered means nothing was found to match search | # no error registered means nothing was found to match search | |||
if {![array exists err_list]} { | if {![array exists err_list]} { | |||
skipping to change at line 447 | skipping to change at line 446 | |||
# enable unload of sticky mod if stickiness is preserved on swapped-on mod | # enable unload of sticky mod if stickiness is preserved on swapped-on mod | |||
# need to resolve swapped-off module here to get stickiness details | # need to resolve swapped-off module here to get stickiness details | |||
lassign [getPathToModule $old {} 0 $unload_match] modfile oldmod oldmodvr | lassign [getPathToModule $old {} 0 $unload_match] modfile oldmod oldmodvr | |||
if {[set sticky_reload [isStickinessReloading $oldmodvr [list $new]]]} { | if {[set sticky_reload [isStickinessReloading $oldmodvr [list $new]]]} { | |||
lappendState reloading_sticky $oldmod | lappendState reloading_sticky $oldmod | |||
} | } | |||
if {[set supersticky_reload [isStickinessReloading $oldmodvr [list $new]\ | if {[set supersticky_reload [isStickinessReloading $oldmodvr [list $new]\ | |||
super-sticky]]} { | super-sticky]]} { | |||
lappendState reloading_supersticky $oldmod | lappendState reloading_supersticky $oldmod | |||
} | } | |||
##nagelfar implicitvarcmd {cmdModuleUnload swunload *} oldhidden olduasked\ | ||||
oldmsgrecid deprelist depreisuasked deprevr depreextratag | ||||
set ret [cmdModuleUnload swunload $unload_match 1 0 0 0 $old] | set ret [cmdModuleUnload swunload $unload_match 1 0 0 0 $old] | |||
if {$sticky_reload} { | if {$sticky_reload} { | |||
lpopState reloading_sticky | lpopState reloading_sticky | |||
} | } | |||
if {$supersticky_reload} { | if {$supersticky_reload} { | |||
lpopState reloading_supersticky | lpopState reloading_supersticky | |||
} | } | |||
# register modulefile to unload as conflict if an unload module is | # register modulefile to unload as conflict if an unload module is | |||
# mentioned on this module switch command set in a modulefile | # mentioned on this module switch command set in a modulefile | |||
skipping to change at line 478 | skipping to change at line 479 | |||
} | } | |||
} | } | |||
# attempt load and depre reload only if unload succeed | # attempt load and depre reload only if unload succeed | |||
if {!$ret} { | if {!$ret} { | |||
if {[info exists depreisuasked]} { | if {[info exists depreisuasked]} { | |||
set undepreisuasked $depreisuasked | set undepreisuasked $depreisuasked | |||
set undeprevr $deprevr | set undeprevr $deprevr | |||
set undepreextratag $depreextratag | set undepreextratag $depreextratag | |||
} | } | |||
cmdModuleLoad swload $uasked $tag_list $new | ##nagelfar implicitvarcmd {cmdModuleLoad swload *} newhidden newmsgrecid | |||
cmdModuleLoad swload $uasked 0 0 $tag_list $new | ||||
# merge depre info of unload and load phases | # merge depre info of unload and load phases | |||
if {[info exists undepreisuasked]} { | if {[info exists undepreisuasked]} { | |||
set depreisuasked [list {*}$undepreisuasked {*}$depreisuasked] | set depreisuasked [list {*}$undepreisuasked {*}$depreisuasked] | |||
set deprevr [list {*}$undeprevr {*}$deprevr] | set deprevr [list {*}$undeprevr {*}$deprevr] | |||
set depreextratag [list {*}$undepreextratag {*}$depreextratag] | set depreextratag [list {*}$undepreextratag {*}$depreextratag] | |||
} | } | |||
if {[getConf auto_handling] && [info exists deprelist] && [llength\ | if {[getConf auto_handling] && [info exists deprelist] && [llength\ | |||
$deprelist] > 0} { | $deprelist] > 0} { | |||
skipping to change at line 518 | skipping to change at line 520 | |||
reportMsgRecord "Switching from [getModuleDesignation $oldmsgrecid {} 2]\ | reportMsgRecord "Switching from [getModuleDesignation $oldmsgrecid {} 2]\ | |||
to [getModuleDesignation $newmsgrecid $new 2]" [expr {$oldhidden &&\ | to [getModuleDesignation $newmsgrecid $new 2]" [expr {$oldhidden &&\ | |||
!$olduasked && $newhidden && !$uasked}] | !$olduasked && $newhidden && !$uasked}] | |||
popMsgRecordId | popMsgRecordId | |||
if {$inhibit_req_rec} { | if {$inhibit_req_rec} { | |||
lpopState inhibit_req_record | lpopState inhibit_req_record | |||
} | } | |||
# register modulefile to load as prereq when called from modulefile | # register modulefile to load as prereq when called from modulefile | |||
if {!$uasked && !$ret && $argnew ne {}} { | if {!$uasked && !$ret && $argnew ne {}} { | |||
setConf auto_handling 0 | prereqAnyModfileCmd 0 0 $argnew | |||
prereq $argnew | ||||
setConf auto_handling $orig_auto_handling | ||||
} | } | |||
} | } | |||
proc cmdModuleSave {{coll default}} { | proc cmdModuleSave {{coll default}} { | |||
if {![areModuleConstraintsSatisfied]} { | if {![areModuleConstraintsSatisfied]} { | |||
reportErrorAndExit {Cannot save collection, some module constraints are\ | reportErrorAndExit {Cannot save collection, some module constraints are\ | |||
not satistied} | not satistied} | |||
} | } | |||
# format collection content, version number of modulefile are saved if | # format collection content, version number of modulefile are saved if | |||
skipping to change at line 572 | skipping to change at line 572 | |||
if {[catch { | if {[catch { | |||
set fid [open $collfile w] | set fid [open $collfile w] | |||
puts $fid $save | puts $fid $save | |||
close $fid | close $fid | |||
} errMsg ]} { | } errMsg ]} { | |||
reportErrorAndExit "Collection $colldesc cannot be saved.\n$errMsg" | reportErrorAndExit "Collection $colldesc cannot be saved.\n$errMsg" | |||
} | } | |||
} | } | |||
proc cmdModuleRestore {{coll default}} { | proc cmdModuleRestore {args} { | |||
# get corresponding collection, raise error if it does not exist | # distinguish between zero and one argument provided | |||
lassign [findCollections $coll exact 1] collfile colldesc | if {[llength $args] == 0} { | |||
set arg_provided 0 | ||||
# read collection | set coll default | |||
lassign [readCollectionContent $collfile $colldesc] coll_path_list\ | } else { | |||
coll_mod_list coll_tag_arrser | set arg_provided 1 | |||
set coll [lindex $args 0] | ||||
# build list of module tagged auto-loaded in collection | ||||
array set coll_tag_arr $coll_tag_arrser | ||||
set coll_nuasked_list {} | ||||
foreach mod [array names coll_tag_arr] { | ||||
if {{auto-loaded} in $coll_tag_arr($mod)} { | ||||
lappend coll_nuasked_list $mod | ||||
} | ||||
} | } | |||
# collection should at least define a path or a mod | # get corresponding collection, raise error if it does not exist unless | |||
if {[llength $coll_path_list] == 0 && [llength $coll_mod_list] == 0} { | # if no collection name has been provided or if __init__ | |||
reportErrorAndExit "$colldesc is not a valid collection" | lassign [findCollections $coll exact [expr {!$arg_provided}]\ | |||
} | $arg_provided] collfile colldesc | |||
# forcibly enable implicit_default to restore colls saved in this mode | # forcibly enable implicit_default to restore colls saved in this mode | |||
setConf implicit_default 1 | setConf implicit_default 1 | |||
# load tags from loaded modules | # fetch collection content and differences compared current environment | |||
cacheCurrentModules | lassign [getDiffBetweenCurEnvAndColl $collfile $colldesc] coll_path_list\ | |||
coll_mod_list coll_tag_arrser coll_nuasked_list mod_to_unload\ | ||||
defineModEqProc [isIcase] [getConf extended_default] | mod_to_load path_to_unuse path_to_use is_tags_diff | |||
array set coll_tag_arr $coll_tag_arrser | ||||
# fetch what is currently loaded | ||||
set curr_path_list [getModulePathList returnempty 0] | ||||
# get current loaded module list | ||||
set curr_mod_list [getLoadedModuleList] | ||||
set curr_nuasked_list [getTaggedLoadedModuleList auto-loaded] | ||||
# determine what module to unload to restore collection from current | ||||
# situation with preservation of the load order (asking for a modeq | ||||
# comparison will help to check against simplified mod name and variants) | ||||
lassign [getMovementBetweenList $curr_mod_list $coll_mod_list\ | ||||
$curr_nuasked_list $coll_nuasked_list modeq] mod_to_unload mod_to_load | ||||
# proceed as well for modulepath | ||||
lassign [getMovementBetweenList $curr_path_list $coll_path_list] \ | ||||
path_to_unuse path_to_use | ||||
# create an eval id to track successful/failed module evaluations | # create an eval id to track successful/failed module evaluations | |||
pushMsgRecordId restore-$coll-[depthState modulename] 0 | pushMsgRecordId restore-$coll-[depthState modulename] 0 | |||
# unload modules one by one (no dependency auto unload) | # unload modules one by one (no dependency auto unload) | |||
foreach mod [lreverse $mod_to_unload] { | foreach mod [lreverse $mod_to_unload] { | |||
# test stickiness over full module name version variant designation | # test stickiness over full module name version variant designation | |||
if {[set vr [getVariantList $mod 1]] ne {}} { | if {[set vr [getVariantList $mod 1]] ne {}} { | |||
lassign [parseModuleSpecification 0 $mod {*}$vr] modvr | lassign [parseModuleSpecification 0 $mod {*}$vr] modvr | |||
} else { | } else { | |||
set modvr $mod | set modvr $mod | |||
} | } | |||
if {[set sticky_reload [isStickinessReloading $modvr $mod_to_load]]} { | # sticky modules can be unloaded when restoring collection | |||
lappendState reloading_sticky $mod | lappendState unloading_sticky $mod | |||
} | ||||
if {[set supersticky_reload [isStickinessReloading $modvr $mod_to_load\ | if {[set supersticky_reload [isStickinessReloading $modvr $mod_to_load\ | |||
super-sticky]]} { | super-sticky]]} { | |||
lappendState reloading_supersticky $mod | lappendState reloading_supersticky $mod | |||
} | } | |||
cmdModuleUnload unload match 0 0 0 0 $mod | cmdModuleUnload unload match 0 0 0 0 $mod | |||
if {$sticky_reload} { | lpopState unloading_sticky | |||
lpopState reloading_sticky | ||||
} | ||||
if {$supersticky_reload} { | if {$supersticky_reload} { | |||
lpopState reloading_supersticky | lpopState reloading_supersticky | |||
} | } | |||
} | } | |||
# unuse paths | # unuse paths | |||
if {[llength $path_to_unuse] > 0} { | if {[llength $path_to_unuse] > 0} { | |||
cmdModuleUnuse load {*}[lreverse $path_to_unuse] | cmdModuleUnuse load {*}[lreverse $path_to_unuse] | |||
} | } | |||
# since unloading a module may unload other modules or | # since unloading a module may unload other modules or | |||
# paths, what to load/use has to be determined after | # paths, what to load/use has to be determined after | |||
# the undo phase, so current situation is fetched again | # the undo phase, so current situation is fetched again | |||
set curr_path_list [getModulePathList returnempty 0] | set curr_path_list [getModulePathList returnempty 0] | |||
set curr_mod_list [getLoadedModuleList] | set curr_mod_list [getLoadedModulePropertyList name] | |||
set curr_nuasked_list [getTaggedLoadedModuleList auto-loaded] | set curr_nuasked_list [getTaggedLoadedModuleList auto-loaded] | |||
# update tags sets on the modules already loaded at correct position | # update tags sets on the modules already loaded at correct position | |||
# remove extra tags that are not defined in collection | # remove extra tags that are not defined in collection | |||
foreach modvr [getLoadedModuleWithVariantList] { | foreach modvr [getLoadedModuleWithVariantList] { | |||
if {[info exists coll_tag_arr($modvr)]} { | if {[info exists coll_tag_arr($modvr)]} { | |||
set tag_list $coll_tag_arr($modvr) | set tag_list $coll_tag_arr($modvr) | |||
} else { | } else { | |||
set tag_list {} | set tag_list {} | |||
} | } | |||
skipping to change at line 695 | skipping to change at line 670 | |||
# use paths | # use paths | |||
if {[llength $path_to_use] > 0} { | if {[llength $path_to_use] > 0} { | |||
# always append path here to guaranty the order | # always append path here to guaranty the order | |||
# computed above in the movement lists | # computed above in the movement lists | |||
cmdModuleUse load append {*}$path_to_use | cmdModuleUse load append {*}$path_to_use | |||
} | } | |||
# load modules one by one with user asked state preserved | # load modules one by one with user asked state preserved | |||
foreach mod $mod_to_load { | foreach mod $mod_to_load { | |||
cmdModuleLoad load [expr {$mod ni $coll_nuasked_list}]\ | cmdModuleLoad load [expr {$mod ni $coll_nuasked_list}] 0 0\ | |||
$coll_tag_arr($mod) $mod | $coll_tag_arr($mod) $mod | |||
} | } | |||
popMsgRecordId 0 | popMsgRecordId 0 | |||
} | } | |||
proc cmdModuleSaverm {{coll default}} { | proc cmdModuleSaverm {{coll default}} { | |||
# avoid to remove any kind of file with this command | # avoid to remove any kind of file with this command | |||
if {[string first / $coll] > -1} { | if {[string first / $coll] > -1} { | |||
reportErrorAndExit {Command does not remove collection specified as\ | reportErrorAndExit {Command does not remove collection specified as\ | |||
filepath} | filepath} | |||
} | } | |||
# get corresponding collection, raise error if it does not exist, but do | # get corresponding collection, raise error if it does not exist, but do | |||
# not check if collection is valid | # not check if collection is valid | |||
lassign [findCollections $coll exact 1 0] collfile colldesc | lassign [findCollections $coll exact 0 1 0] collfile colldesc | |||
# attempt to delete specified collection | # attempt to delete specified collection | |||
if {[catch { | if {[catch { | |||
file delete $collfile | file delete $collfile | |||
} errMsg ]} { | } errMsg ]} { | |||
reportErrorAndExit "Collection $colldesc cannot be removed.\n$errMsg" | reportErrorAndExit "Collection $colldesc cannot be removed.\n$errMsg" | |||
} | } | |||
} | } | |||
proc cmdModuleSaveshow {{coll default}} { | proc cmdModuleSaveshow {args} { | |||
# get corresponding collection, raise error if it does not exist | # distinguish between zero and one argument provided | |||
lassign [findCollections $coll exact 1] collfile colldesc | if {[llength $args] == 0} { | |||
set arg_provided 0 | ||||
# read collection | set coll default | |||
lassign [readCollectionContent $collfile $colldesc] coll_path_list\ | } else { | |||
coll_mod_list coll_tag_arrser | set arg_provided 1 | |||
set coll [lindex $args 0] | ||||
} | ||||
# get corresponding collection, raise error if it does not exist unless | ||||
# if no collection name has been provided or if __init__ | ||||
lassign [findCollections $coll exact [expr {!$arg_provided}]\ | ||||
$arg_provided] collfile colldesc | ||||
# read specific __init__ collection from __MODULES_LMINIT env var | ||||
if {$collfile eq {__init__}} { | ||||
lassign [parseCollectionContent [getLoadedModulePropertyList init]]\ | ||||
coll_path_list coll_mod_list coll_tag_arrser | ||||
set collfile {initial environment} | ||||
set coll __init__ | ||||
} else { | ||||
lassign [readCollectionContent $collfile $colldesc] coll_path_list\ | ||||
coll_mod_list coll_tag_arrser | ||||
} | ||||
# collection should at least define a path or a mod | # collection should at least define a path or a mod, but initial env may be | |||
if {[llength $coll_path_list] == 0 && [llength $coll_mod_list] == 0} { | # totally empty | |||
if {$coll ne {__init__} && [llength $coll_path_list] == 0 && [llength\ | ||||
$coll_mod_list] == 0} { | ||||
reportErrorAndExit "$colldesc is not a valid collection" | reportErrorAndExit "$colldesc is not a valid collection" | |||
} | } | |||
displaySeparatorLine | displaySeparatorLine | |||
report [sgr hi $collfile]:\n | report [sgr hi $collfile]:\n | |||
report [formatCollectionContent $coll_path_list $coll_mod_list\ | report [formatCollectionContent $coll_path_list $coll_mod_list\ | |||
$coll_tag_arrser {} 1] | $coll_tag_arrser {} 1] | |||
displaySeparatorLine | displaySeparatorLine | |||
} | } | |||
proc cmdModuleSavelist {show_oneperline show_mtime} { | proc cmdModuleSavelist {show_oneperline show_mtime search_match args} { | |||
# if a target is set, only list collection matching this | # if a target is set, only list collection matching this target (means | |||
# target (means having target as suffix in their name) | # having target as suffix in their name) unless if --all option is set | |||
set colltarget [getConf collection_target] | set colltarget [getConf collection_target] | |||
if {$colltarget ne {}} { | if {$colltarget ne {} && [getState hiding_threshold] < 2} { | |||
set suffix .$colltarget | set suffix .$colltarget | |||
set targetdesc " (for target \"$colltarget\")" | set targetdesc " (for target \"$colltarget\")" | |||
} else { | } else { | |||
set suffix {} | set suffix {} | |||
set targetdesc {} | set targetdesc {} | |||
} | } | |||
set json [isStateEqual report_format json] | set json [isStateEqual report_format json] | |||
reportDebug "list collections for target \"$colltarget\"" | reportDebug "list collections$targetdesc" | |||
# if only stash collection are expected, start result index at 0, sort | ||||
# results in reverse order (latest first) and ensure only collection from | ||||
# current target (and no-target if none set) are returned. | ||||
if {[getCallingProcName] eq {cmdModuleStashlist}} { | ||||
set start_idx 0 | ||||
set sort_opts [list -dictionary -decreasing] | ||||
set find_no_other_target 1 | ||||
set typedesc stash | ||||
# no icase match as stash collections are only lowercases | ||||
set icase 0 | ||||
} else { | ||||
set start_idx 1 | ||||
set sort_opts [list -dictionary] | ||||
set find_no_other_target 0 | ||||
set typedesc named | ||||
set icase [isIcase] | ||||
} | ||||
if {[llength $args] > 0} { | ||||
defineModEqProc $icase 0 | ||||
# match passed name against any part of collection names | ||||
set mtest [expr {{contains} in $search_match ? {matchin} : {match}}] | ||||
} | ||||
# prepare header message which depend if search is performed (no search | ||||
# considered if listing stash collections) | ||||
if {[llength $args] > 0 && $typedesc ne {stash}} { | ||||
set collmsg "Matching $typedesc collection list$targetdesc:" | ||||
} else { | ||||
set collmsg "[string totitle $typedesc] collection list$targetdesc:" | ||||
} | ||||
foreach collfile [findCollections * glob 0 0 1 $find_no_other_target] { | ||||
# remove target suffix from names to display | ||||
regsub $suffix$ [file tail $collfile] {} coll | ||||
# filter stash collections unless called by stashlist or --all opt set | ||||
if {$typedesc ne {named} || ![regexp {stash-\d+} $coll] || [getState\ | ||||
hiding_threshold] >= 2} { | ||||
set coll_arr($coll) $collfile | ||||
} | ||||
} | ||||
# same header msg if no collection at all whether search is made or not | ||||
if {![array exists coll_arr] || $typedesc eq {stash}} { | ||||
set nocollmsg "No $typedesc collection$targetdesc." | ||||
} else { | ||||
set nocollmsg "No matching $typedesc collection$targetdesc." | ||||
} | ||||
set coll_list [findCollections] | # filter collection not matching any of the passed specification | |||
if {[llength $args] > 0} { | ||||
set matchlist [list] | ||||
foreach coll [array names coll_arr] { | ||||
set match 0 | ||||
foreach pattern $args { | ||||
# compare pattern against collections using comparison module proc | ||||
# useful for suffix/prefix/icase checks, disabling module-specific | ||||
# checks (variants, alternative names, etc) | ||||
if {[modEq $pattern $coll $mtest 0 0 0 0 *]} { | ||||
set match 1 | ||||
break | ||||
} | ||||
} | ||||
if {!$match} { | ||||
unset coll_arr($coll) | ||||
} | ||||
} | ||||
} | ||||
if { [llength $coll_list] == 0} { | if {[array size coll_arr] == 0} { | |||
if {!$json} { | if {!$json} { | |||
report "No named collection$targetdesc." | report $nocollmsg | |||
} | } | |||
} else { | } else { | |||
set list {} | ||||
if {!$json} { | if {!$json} { | |||
if {$show_mtime} { | if {$show_mtime} { | |||
displayTableHeader hi Collection 59 {Last mod.} 19 | displayTableHeader hi Collection 59 {Last mod.} 19 | |||
} | } | |||
report "Named collection list$targetdesc:" | report $collmsg | |||
} | } | |||
set display_list {} | set display_list {} | |||
set len_list {} | set len_list {} | |||
set max_len 0 | set max_len 0 | |||
if {$show_mtime || $show_oneperline} { | set one_per_line [expr {$show_mtime || $show_oneperline}] | |||
set display_idx 0 | set show_idx [expr {!$one_per_line}] | |||
set one_per_line 1 | # prepare query to highlight | |||
} else { | set himatchmap [prepareMapToHightlightSubstr {*}$args] | |||
set display_idx 1 | ||||
set one_per_line 0 | ||||
} | ||||
foreach coll [lsort -dictionary $coll_list] { | foreach coll [lsort {*}$sort_opts [array names coll_arr]] { | |||
# remove target suffix from names to display | ||||
regsub $suffix$ [file tail $coll] {} mod | ||||
if {$json} { | if {$json} { | |||
lappend display_list [formatListEltToJsonDisplay $mod target s\ | lappend display_list [formatListEltToJsonDisplay $coll target s\ | |||
$colltarget 1 pathname s $coll 1] | $colltarget 1 pathname s $coll_arr($coll) 1] | |||
# no need to test mod consistency as findCollections does not return | # no need to test coll consistency as findCollections does not return | |||
# collection whose name starts with "." | # collection whose name starts with "." | |||
} elseif {$show_mtime} { | ||||
set filetime [clock format [getFileMtime $coll]\ | ||||
-format {%Y/%m/%d %H:%M:%S}] | ||||
lappend display_list [format %-60s%19s $mod $filetime] | ||||
} else { | } else { | |||
lappend display_list $mod | set collsgr [sgr {} $coll $himatchmap] | |||
lappend len_list [set len [string length $mod]] | if {$show_mtime} { | |||
if {$len > $max_len} { | set filetime [clock format [getFileMtime $coll_arr($coll)]\ | |||
set max_len $len | -format {%Y/%m/%d %H:%M:%S}] | |||
lappend display_list [format %-60s%19s $collsgr $filetime] | ||||
} else { | ||||
lappend display_list $collsgr | ||||
lappend len_list [set len [string length $coll]] | ||||
if {$len > $max_len} { | ||||
set max_len $len | ||||
} | ||||
} | } | |||
} | } | |||
} | } | |||
displayElementList noheader {} {} $one_per_line $display_idx\ | displayElementList noheader {} {} $one_per_line $show_idx $start_idx\ | |||
$display_list $len_list $max_len | $display_list $len_list $max_len | |||
} | } | |||
} | } | |||
proc cmdModuleSource {mode args} { | proc cmdModuleSource {mode args} { | |||
foreach fpath $args { | foreach mod $args { | |||
set absfpath [getAbsolutePath $fpath] | set rawarg [getRawArgumentFromVersSpec $mod] | |||
if {$fpath eq {}} { | if {$mod eq {}} { | |||
reportErrorAndExit {File name empty} | reportErrorAndExit {File name empty} | |||
} elseif {[file exists $absfpath]} { | # first check if raw specification is an existing file | |||
lappendState mode $mode | } elseif {[file exists [set absfpath [getAbsolutePath $rawarg]]]} { | |||
# sourced file must also have a magic cookie set at their start | set modfile $absfpath | |||
execute-modulefile $absfpath $absfpath $absfpath $absfpath 0 0 | set modname $absfpath | |||
lpopState mode | set modnamevr $absfpath | |||
# unset module specification not to confuse specific char in file | ||||
# path (like '+') with variant specification | ||||
unsetModuleVersSpec $mod | ||||
set mod $absfpath | ||||
# if not a path specification, try to resolve a modulefile | ||||
} elseif {![isModuleFullPath $rawarg]} { | ||||
lassign [getPathToModule $mod] modfile modname modnamevr | ||||
# stop if no module found, issue has been reported by getPathToModule | ||||
if {$modfile eq {}} { | ||||
break | ||||
} | ||||
} else { | } else { | |||
reportErrorAndExit "File $fpath does not exist" | reportErrorAndExit "File $rawarg does not exist" | |||
} | } | |||
##nagelfar ignore Found constant | ||||
lappendState mode $mode | ||||
# sourced file must also have a magic cookie set at their start | ||||
##nagelfar ignore Suspicious variable name | ||||
execute-modulefile $modfile $modname $modnamevr $mod 0 0 | ||||
##nagelfar ignore Found constant | ||||
lpopState mode | ||||
} | } | |||
} | } | |||
proc cmdModuleLoad {context uasked tag_list args} { | proc cmdModuleLoad {context uasked tryload loadany tag_list args} { | |||
reportDebug "loading $args (context=$context, uasked=$uasked)" | reportDebug "loading $args (context=$context, uasked=$uasked,\ | |||
tryload=$tryload, loadany=$loadany)" | ||||
set ret 0 | set ret 0 | |||
set loadok 0 | set loadok 0 | |||
lappendState mode load | lappendState mode load | |||
foreach mod $args { | foreach mod $args { | |||
# stop when first module in list is loaded if processing load-any cmd | # stop when first module in list is loaded if any mode enabled | |||
if {$loadok && [currentState any_modulefile]} { | if {$loadok && $loadany} { | |||
break | break | |||
} | } | |||
# if a switch action is ongoing... | # if a switch action is ongoing... | |||
if {$context eq {swload}} { | if {$context eq {swload}} { | |||
set swprocessing 1 | set swprocessing 1 | |||
# context is ReqLo if switch is called from a modulefile | # context is ReqLo if switch is called from a modulefile | |||
if {![isMsgRecordIdTop]} { | if {![isMsgRecordIdTop]} { | |||
set context reqlo | set context reqlo | |||
} | } | |||
upvar newhidden hidden | upvar newhidden hidden | |||
upvar newmsgrecid msgrecid | upvar newmsgrecid msgrecid | |||
} | } | |||
# loading module is visible by default | # loading module is visible by default | |||
set hidden 0 | set hidden 0 | |||
# error if module not found or forbidden | # error if module not found or forbidden | |||
set notfounderr [expr {![currentState try_modulefile]}] | set notfounderr [expr {!$tryload}] | |||
# record evaluation attempt on specified module name | # record evaluation attempt on specified module name | |||
registerModuleEvalAttempt $context $mod | registerModuleEvalAttempt $context $mod | |||
lassign [getPathToModule $mod {} $notfounderr] modfile modname modnamevr | lassign [getPathToModule $mod {} $notfounderr] modfile modname modnamevr | |||
# set a unique id to record messages related to this evaluation. | # set a unique id to record messages related to this evaluation. | |||
set msgrecid load-$modnamevr-[depthState modulename] | set msgrecid load-$modnamevr-[depthState modulename] | |||
# go to next module to load if not matching module found | # go to next module to load if not matching module found | |||
if {$modfile eq {}} { | if {$modfile eq {}} { | |||
skipping to change at line 1074 | skipping to change at line 1153 | |||
} | } | |||
} | } | |||
# loading visibility depends on hidden-loaded tag | # loading visibility depends on hidden-loaded tag | |||
set hidden [isModuleTagged $modnamevr hidden-loaded 1] | set hidden [isModuleTagged $modnamevr hidden-loaded 1] | |||
append-path LOADEDMODULES $modname | append-path LOADEDMODULES $modname | |||
# allow duplicate modfile entries for virtual modules | # allow duplicate modfile entries for virtual modules | |||
append-path --duplicates _LMFILES_ $modfile | append-path --duplicates _LMFILES_ $modfile | |||
# update cache arrays | # update cache arrays | |||
setLoadedModule $modname $modfile $uasked $modnamevr | setLoadedModule $modname $modfile $uasked $modnamevr [expr {$modname\ | |||
in [getState refresh_qualified]}] | ||||
# register declared source-sh in environment | # register declared source-sh in environment | |||
if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} { | if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} { | |||
append-path __MODULES_LMSOURCESH $modsrcsh | append-path __MODULES_LMSOURCESH $modsrcsh | |||
} | } | |||
# register declared conflict in environment | # register declared conflict in environment | |||
if {[set modcon [getLoadedConflict $modname 1]] ne {}} { | if {[set modcon [getLoadedConflict $modname 1]] ne {}} { | |||
append-path __MODULES_LMCONFLICT $modcon | append-path __MODULES_LMCONFLICT $modcon | |||
} | } | |||
skipping to change at line 1109 | skipping to change at line 1189 | |||
} | } | |||
# declare the tags of this module | # declare the tags of this module | |||
if {[set modtag [getExportTagList $modnamevr 1]] ne {}} { | if {[set modtag [getExportTagList $modnamevr 1]] ne {}} { | |||
append-path __MODULES_LMTAG $modtag | append-path __MODULES_LMTAG $modtag | |||
} | } | |||
if {[set modtag [getExtraTagList $modnamevr 1]] ne {}} { | if {[set modtag [getExtraTagList $modnamevr 1]] ne {}} { | |||
append-path __MODULES_LMEXTRATAG $modtag | append-path __MODULES_LMEXTRATAG $modtag | |||
} | } | |||
# declare module qualified for refresh evaluation | ||||
if {[isModuleRefreshQualified $modname]} { | ||||
append-path __MODULES_LMREFRESH $modname | ||||
} | ||||
# Load phase of dependent module reloading. These modules can adapt | # Load phase of dependent module reloading. These modules can adapt | |||
# now that mod is seen loaded. Except if switch action ongoing (DepRe | # now that mod is seen loaded. Except if switch action ongoing (DepRe | |||
# load phase will occur from switch) | # load phase will occur from switch) | |||
if {[getConf auto_handling] && [llength $deprelist] > 0 && ![info\ | if {[getConf auto_handling] && [llength $deprelist] > 0 && ![info\ | |||
exists swprocessing]} { | exists swprocessing]} { | |||
reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\ | reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\ | |||
$depreextratag [getState force] {Reload of dependent _MOD_\ | $depreextratag [getState force] {Reload of dependent _MOD_\ | |||
failed} depre | failed} depre | |||
} | } | |||
skipping to change at line 1169 | skipping to change at line 1254 | |||
} | } | |||
popMsgRecordId | popMsgRecordId | |||
if {$errCode == 0} { | if {$errCode == 0} { | |||
set loadok 1 | set loadok 1 | |||
} | } | |||
} | } | |||
lpopState mode | lpopState mode | |||
# raise error if no module has been loaded or has produced an error during | # raise error if no module has been loaded or has produced an error during | |||
# its load attempt in case of load-any sub-command | # its load attempt in case of top-level load-any sub-command | |||
if {!$ret && !$loadok && $context eq {load} && [currentState\ | if {!$ret && !$loadok && $context eq {load} && $loadany} { | |||
any_modulefile]} { | ||||
knerror "No module has been loaded" | knerror "No module has been loaded" | |||
} | } | |||
return $ret | return $ret | |||
} | } | |||
proc cmdModuleUnload {context match auto force onlyureq onlyndep args} { | proc cmdModuleUnload {context match auto force onlyureq onlyndep args} { | |||
reportDebug "unloading $args (context=$context, match=$match, auto=$auto,\ | reportDebug "unloading $args (context=$context, match=$match, auto=$auto,\ | |||
force=$force, onlyureq=$onlyureq, onlyndep=$onlyndep)" | force=$force, onlyureq=$onlyureq, onlyndep=$onlyndep)" | |||
skipping to change at line 1257 | skipping to change at line 1341 | |||
continue | continue | |||
} | } | |||
if {$onlyureq && ![isModuleUnloadable $modname]} { | if {$onlyureq && ![isModuleUnloadable $modname]} { | |||
reportDebug "$modname ($modfile) is required by loaded module or\ | reportDebug "$modname ($modfile) is required by loaded module or\ | |||
asked by user" | asked by user" | |||
continue | continue | |||
} | } | |||
if {[isModuleEvalFailed unload $modnamevr]} { | if {[isModuleEvalFailed unload $modnamevr]} { | |||
reportDebug "$modnamevr ($modfile) unload was already tried and failed" | reportDebug "$modnamevr ($modfile) unload was already tried and\ | |||
failed" | ||||
# nullify this evaluation attempt to avoid duplicate issue report | # nullify this evaluation attempt to avoid duplicate issue report | |||
unregisterModuleEvalAttempt $context $mod | unregisterModuleEvalAttempt $context $mod | |||
continue | continue | |||
} | } | |||
# register record message unique id (now we know mod will be evaluated) | # register record message unique id (now we know mod will be evaluated) | |||
pushMsgRecordId $msgrecid | pushMsgRecordId $msgrecid | |||
# record evaluation attempt on actual module name | # record evaluation attempt on actual module name | |||
registerModuleEvalAttempt $context $modnamevr | registerModuleEvalAttempt $context $modnamevr | |||
skipping to change at line 1282 | skipping to change at line 1367 | |||
1] [getExportTagList $modname] | 1] [getExportTagList $modname] | |||
pushSettings | pushSettings | |||
if {[set errCode [catch { | if {[set errCode [catch { | |||
# error if unloading module violates a registered prereq | # error if unloading module violates a registered prereq | |||
# and auto handling mode is disabled | # and auto handling mode is disabled | |||
set prereq_list [getDependentLoadedModuleList [list $modname]] | set prereq_list [getDependentLoadedModuleList [list $modname]] | |||
if {[llength $prereq_list] > 0 && (![getConf auto_handling] ||\ | if {[llength $prereq_list] > 0 && (![getConf auto_handling] ||\ | |||
!$auto)} { | !$auto)} { | |||
# force mode should not affect if we only look for mods w/o dep | # force mode should not affect if we only look for mods w/o dep | |||
##nagelfar ignore Found constant | ||||
if {([getState force] || $force) && !$onlyndep} { | if {([getState force] || $force) && !$onlyndep} { | |||
# in case unload is called for a DepRe mechanism do not warn | # in case unload is called for a DepRe mechanism do not warn | |||
# about prereq violation enforced as it is due to the dependent | # about prereq violation enforced as it is due to the dependent | |||
# module which is already in a violation state | # module which is already in a violation state | |||
# warn in case of a purge | # warn in case of a purge | |||
if {$auto || !$force || [currentState commandname] eq {purge}} { | if {$auto || !$force || [currentState commandname] eq\ | |||
{purge}} { | ||||
reportWarning [getDepLoadedMsg $prereq_list] | reportWarning [getDepLoadedMsg $prereq_list] | |||
} | } | |||
} else { | } else { | |||
set errlocalreport 1 | set errlocalreport 1 | |||
# exit treatment but no need to set return code to error if | # exit treatment but no need to set return code to error if | |||
# called from a 'module unload' command in a modulefile in a | # called from a 'module unload' command in a modulefile in a | |||
# load evaluation mode, as set conflict will raise error at end | # load evaluation mode, as set conflict will raise error at end | |||
# of modulefile evaluation | # of modulefile evaluation | |||
if {$onlyndep} { | if {$onlyndep} { | |||
set errharmless 1 | set errharmless 1 | |||
skipping to change at line 1313 | skipping to change at line 1400 | |||
} | } | |||
if {[getConf auto_handling] && $auto} { | if {[getConf auto_handling] && $auto} { | |||
# compute lists of modules to update due to modname unload prior | # compute lists of modules to update due to modname unload prior | |||
# unload to get requirement info before it vanishes | # unload to get requirement info before it vanishes | |||
# DepUn: Dependent to Unload (modules actively requiring modname | # DepUn: Dependent to Unload (modules actively requiring modname | |||
# or a module part of this DepUn batch) | # or a module part of this DepUn batch) | |||
set depunnpolist [getDependentLoadedModuleList [list $modname] 1\ | set depunnpolist [getDependentLoadedModuleList [list $modname] 1\ | |||
0 1 0] | 0 1 0] | |||
set depunlist [getDependentLoadedModuleList [list $modname] 1 0 0 0] | set depunlist [getDependentLoadedModuleList [list $modname] 1 0 0\ | |||
0] | ||||
# look at both regular dependencies or No Particular Order | # look at both regular dependencies or No Particular Order | |||
# dependencies: use NPO result if situation can be healed with NPO | # dependencies: use NPO result if situation can be healed with NPO | |||
# dependencies, which will be part of DepRe list to restore the | # dependencies, which will be part of DepRe list to restore the | |||
# correct loading order for them | # correct loading order for them | |||
if {[llength $depunnpolist] <= [llength $depunlist]} { | if {[llength $depunnpolist] <= [llength $depunlist]} { | |||
set depunlist $depunnpolist | set depunlist $depunnpolist | |||
} | } | |||
reportDebug "depun mod list is '$depunlist'" | reportDebug "depun mod list is '$depunlist'" | |||
# do not check for UReqUn mods coming from DepUn modules as these | # do not check for UReqUn mods coming from DepUn modules as these | |||
skipping to change at line 1357 | skipping to change at line 1445 | |||
{*}$depunlist {*}$deprelist] 1] | {*}$depunlist {*}$deprelist] 1] | |||
set depunlist {} | set depunlist {} | |||
} | } | |||
# Reload of all DepRe mods, as they may adapt from the mod unloads | # Reload of all DepRe mods, as they may adapt from the mod unloads | |||
# happening here. First perform unload phase of the reload, prior | # happening here. First perform unload phase of the reload, prior | |||
# mod unloads to ensure these dependent mods are unloaded with the | # mod unloads to ensure these dependent mods are unloaded with the | |||
# same loaded prereq as when they were loaded. Avoid modules not | # same loaded prereq as when they were loaded. Avoid modules not | |||
# satisfying their constraint. | # satisfying their constraint. | |||
if {[llength $deprelist] > 0} { | if {[llength $deprelist] > 0} { | |||
##nagelfar ignore +2 Found constant | ||||
lassign [reloadModuleListUnloadPhase deprelist [getState\ | lassign [reloadModuleListUnloadPhase deprelist [getState\ | |||
force] {Unload of dependent _MOD_ failed} depun]\ | force] {Unload of dependent _MOD_ failed} depun]\ | |||
depreisuasked deprevr depreextratag | depreisuasked deprevr depreextratag | |||
} | } | |||
# DepUn modules unload prior main mod unload | # DepUn modules unload prior main mod unload | |||
if {[llength $depunlist] > 0} { | if {[llength $depunlist] > 0} { | |||
foreach unmod [lreverse $depunlist] { | foreach unmod [lreverse $depunlist] { | |||
##nagelfar ignore Found constant | ||||
if {[cmdModuleUnload depun match 0 0 0 0 $unmod]} { | if {[cmdModuleUnload depun match 0 0 0 0 $unmod]} { | |||
# stop if one unload fails unless force mode enabled | # stop if one unload fails unless force mode enabled | |||
set errMsg "Unload of dependent [getModuleDesignation\ | set errMsg "Unload of dependent [getModuleDesignation\ | |||
loaded $unmod] failed" | loaded $unmod] failed" | |||
##nagelfar ignore Found constant | ||||
if {[getState force] || $force} { | if {[getState force] || $force} { | |||
reportWarning $errMsg 1 | reportWarning $errMsg 1 | |||
} else { | } else { | |||
knerror $errMsg | knerror $errMsg | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
# register this evaluation on the main one that triggered it (prior | # register this evaluation on the main one that triggered it (prior | |||
# unload evaluation to report correct order with other evaluations) | # unload evaluation to report correct order with other evaluations) | |||
registerModuleEval $context $msgrecid | registerModuleEval $context $msgrecid | |||
# no need to update modnamevr and tags after evaluation as these | # no need to update modnamevr and tags after evaluation as these | |||
# information were already complete in persistent environment | # information were already complete in persistent environment | |||
##nagelfar ignore Suspicious variable name | ||||
if {[execute-modulefile $modfile $modname $modnamevr $mod 0 0]} { | if {[execute-modulefile $modfile $modname $modnamevr $mod 0 0]} { | |||
break | break | |||
} | } | |||
# unloading visibility depends on hidden-loaded tag | # unloading visibility depends on hidden-loaded tag | |||
set hidden [isModuleTagged $modname hidden-loaded 1] | set hidden [isModuleTagged $modname hidden-loaded 1] | |||
# module was asked by user if tagged loaded instead of auto-loaded | # module was asked by user if tagged loaded instead of auto-loaded | |||
set uasked [isModuleTagged $modname loaded 1] | set uasked [isModuleTagged $modname loaded 1] | |||
# unset module from list of loaded modules qualified for refresh eval | ||||
if {[isModuleRefreshQualified $modname]} { | ||||
remove-path __MODULES_LMREFRESH $modname | ||||
} | ||||
# get module position in loaded list to remove corresponding loaded | # get module position in loaded list to remove corresponding loaded | |||
# modulefile (entry at same position in _LMFILES_) | # modulefile (entry at same position in _LMFILES_) | |||
# need the unfiltered loaded module list to get correct index | # need the unfiltered loaded module list to get correct index | |||
set lmidx [lsearch -exact [getLoadedModuleList 0] $modname] | set lmidx [lsearch -exact [getLoadedModulePropertyList name 0]\ | |||
$modname] | ||||
remove-path LOADEDMODULES $modname | remove-path LOADEDMODULES $modname | |||
remove-path --index _LMFILES_ $lmidx | remove-path --index _LMFILES_ $lmidx | |||
# update cache arrays | # update cache arrays | |||
unsetLoadedModule $modname $modfile | unsetLoadedModule $modname $modfile | |||
# unregister declared source-sh | # unregister declared source-sh | |||
if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} { | if {[set modsrcsh [getLoadedSourceSh $modname 1]] ne {}} { | |||
remove-path __MODULES_LMSOURCESH $modsrcsh | remove-path __MODULES_LMSOURCESH $modsrcsh | |||
} | } | |||
unsetLoadedSourceSh $modname | unsetLoadedSourceSh $modname | |||
skipping to change at line 1464 | skipping to change at line 1562 | |||
unsetModuleExtraTag $modnamevr {*}$extratag_list | unsetModuleExtraTag $modnamevr {*}$extratag_list | |||
} | } | |||
} | } | |||
if {[getConf auto_handling] && $auto} { | if {[getConf auto_handling] && $auto} { | |||
# UReqUn modules unload now DepUn+main mods are unloaded | # UReqUn modules unload now DepUn+main mods are unloaded | |||
if {[llength $urequnlist] > 0} { | if {[llength $urequnlist] > 0} { | |||
set urequnlist [lreverse $urequnlist] | set urequnlist [lreverse $urequnlist] | |||
for {set i 0} {$i < [llength $urequnlist]} {incr i 1} { | for {set i 0} {$i < [llength $urequnlist]} {incr i 1} { | |||
set unmod [lindex $urequnlist $i] | set unmod [lindex $urequnlist $i] | |||
##nagelfar ignore Found constant | ||||
if {[cmdModuleUnload urequn match 0 0 0 0 $unmod]} { | if {[cmdModuleUnload urequn match 0 0 0 0 $unmod]} { | |||
# just warn if UReqUn module cannot be unloaded, main | # just warn if UReqUn module cannot be unloaded, main | |||
# unload process continues, just the UReqUn modules that | # unload process continues, just the UReqUn modules that | |||
# are required by unmod (whose unload failed) are | # are required by unmod (whose unload failed) are | |||
# withdrawn from UReqUn module list | # withdrawn from UReqUn module list | |||
reportWarning "Unload of useless requirement\ | reportWarning "Unload of useless requirement\ | |||
[getModuleDesignation loaded $unmod] failed" 1 | [getModuleDesignation loaded $unmod] failed" 1 | |||
lassign [getDiffBetweenList $urequnlist\ | lassign [getDiffBetweenList $urequnlist\ | |||
[getRequiredLoadedModuleList [list $unmod]]]\ | [getRequiredLoadedModuleList [list $unmod]]]\ | |||
urequnlist | urequnlist | |||
} | } | |||
} | } | |||
} | } | |||
# DepRe modules load phase now DepUn+UReqUn+main mods are unloaded | # DepRe modules load phase now DepUn+UReqUn+main mods are unloaded | |||
# except if a switch action is ongoing as this DepRe load phase | # except if a switch action is ongoing as this DepRe load phase | |||
# will occur after the new mod load | # will occur after the new mod load | |||
if {[llength $deprelist] > 0 && ![info exists swprocessing]} { | if {[llength $deprelist] > 0 && ![info exists swprocessing]} { | |||
##nagelfar ignore +2 Found constant | ||||
reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\ | reloadModuleListLoadPhase deprelist $depreisuasked $deprevr\ | |||
$depreextratag [getState force] {Reload of dependent _MOD_\ | $depreextratag [getState force] {Reload of dependent _MOD_\ | |||
failed} depre | failed} depre | |||
} | } | |||
} | } | |||
# consider evaluation hidden if hidden loaded module was auto loaded | # consider evaluation hidden if hidden loaded module was auto loaded | |||
# and no specific messages are recorded for this evaluation | # and no specific messages are recorded for this evaluation | |||
if {$hidden && !$uasked && ![isMsgRecorded]} { | if {$hidden && !$uasked && ![isMsgRecorded]} { | |||
registerModuleEvalHidden $context $msgrecid | registerModuleEvalHidden $context $msgrecid | |||
skipping to change at line 1540 | skipping to change at line 1640 | |||
proc cmdModulePurge {} { | proc cmdModulePurge {} { | |||
# create an eval id to track successful/failed module evaluations | # create an eval id to track successful/failed module evaluations | |||
pushMsgRecordId purge-[depthState modulename] 0 | pushMsgRecordId purge-[depthState modulename] 0 | |||
# unload one by one to ensure same behavior whatever auto_handling state | # unload one by one to ensure same behavior whatever auto_handling state | |||
# force it to handle loaded modules in violation state | # force it to handle loaded modules in violation state | |||
# remove dependent modules if force mode enabled | # remove dependent modules if force mode enabled | |||
set onlyndep [expr {![getState force]}] | set onlyndep [expr {![getState force]}] | |||
cmdModuleUnload unload match 0 1 0 $onlyndep {*}[lreverse\ | cmdModuleUnload unload match 0 1 0 $onlyndep {*}[lreverse\ | |||
[getLoadedModuleList]] | [getLoadedModulePropertyList name]] | |||
popMsgRecordId 0 | popMsgRecordId 0 | |||
} | } | |||
proc cmdModuleReload {args} { | proc cmdModuleReload {args} { | |||
# reload all loaded modules if no module list passed | # reload all loaded modules if no module list passed | |||
if {[llength $args] == 0} { | if {[llength $args] == 0} { | |||
set lmlist [getLoadedModuleList] | set lmlist [getLoadedModulePropertyList name] | |||
} else { | } else { | |||
set lmlist $args | set lmlist $args | |||
} | } | |||
reportDebug "reloading $lmlist" | reportDebug "reloading $lmlist" | |||
# create an eval id to track successful/failed module evaluations | # create an eval id to track successful/failed module evaluations | |||
pushMsgRecordId reload-[depthState modulename] 0 | pushMsgRecordId reload-[depthState modulename] 0 | |||
# no reload of all loaded modules attempt if constraints are violated | # no reload of all loaded modules attempt if constraints are violated | |||
if {[llength $args] == 0 && ![areModuleConstraintsSatisfied]} { | if {[llength $args] == 0 && ![areModuleConstraintsSatisfied]} { | |||
skipping to change at line 1596 | skipping to change at line 1696 | |||
setState inhibit_errreport 0 | setState inhibit_errreport 0 | |||
set display_list {} | set display_list {} | |||
foreach name [lsort -dictionary [array names ::g_moduleAlias]] { | foreach name [lsort -dictionary [array names ::g_moduleAlias]] { | |||
# exclude hidden aliases from result | # exclude hidden aliases from result | |||
if {![isModuleHidden $name]} { | if {![isModuleHidden $name]} { | |||
lappend display_list "[sgr al $name] -> $::g_moduleAlias($name)" | lappend display_list "[sgr al $name] -> $::g_moduleAlias($name)" | |||
} | } | |||
} | } | |||
displayElementList Aliases hi sepline 1 0 $display_list | displayElementList Aliases hi sepline 1 0 0 $display_list | |||
set display_list {} | set display_list {} | |||
foreach name [lsort -dictionary [array names ::g_moduleVersion]] { | foreach name [lsort -dictionary [array names ::g_moduleVersion]] { | |||
# exclude hidden versions or versions targeting an hidden module | # exclude hidden versions or versions targeting an hidden module | |||
if {![isModuleHidden $name] && ![isModuleHidden\ | if {![isModuleHidden $name] && ![isModuleHidden\ | |||
$::g_moduleVersion($name)]} { | $::g_moduleVersion($name)]} { | |||
lappend display_list "[sgr sy $name] -> $::g_moduleVersion($name)" | lappend display_list "[sgr sy $name] -> $::g_moduleVersion($name)" | |||
} | } | |||
} | } | |||
displayElementList Versions hi sepline 1 0 $display_list | displayElementList Versions hi sepline 1 0 0 $display_list | |||
} | } | |||
proc cmdModuleAvail {show_oneperline show_mtime show_filter search_filter\ | proc cmdModuleAvail {show_oneperline show_mtime show_filter search_filter\ | |||
search_match args} { | search_match args} { | |||
if {[llength $args] == 0} { | if {[llength $args] == 0} { | |||
lappend args * | lappend args * | |||
} | } | |||
if {$show_mtime || $show_oneperline} { | if {$show_mtime || $show_oneperline} { | |||
set one_per_line 1 | set one_per_line 1 | |||
skipping to change at line 1643 | skipping to change at line 1743 | |||
# consolidate search filters | # consolidate search filters | |||
lappend search_filter $search_match wild | lappend search_filter $search_match wild | |||
set search_rc_filter $search_filter | set search_rc_filter $search_filter | |||
lappend search_rc_filter rc_alias_only | lappend search_rc_filter rc_alias_only | |||
# disable error reporting to avoid modulefile errors | # disable error reporting to avoid modulefile errors | |||
# to mix with avail results | # to mix with avail results | |||
inhibitErrorReport | inhibitErrorReport | |||
foreach mod $args { | foreach mod $args { | |||
set search_queries [list $mod] | ||||
array unset mod_list | array unset mod_list | |||
# look if aliases have been defined in the global or user-specific | # look if aliases have been defined in the global or user-specific | |||
# modulerc and display them if any in a dedicated list | # modulerc and display them if any in a dedicated list | |||
array set mod_list [getModules {} $mod $show_mtime $search_rc_filter\ | array set mod_list [getModules {} $mod $show_mtime $search_rc_filter\ | |||
$show_filter] | $show_filter] | |||
if {$report_modulepath} { | if {$report_modulepath} { | |||
reportModules $mod {global/user modulerc} hi $hstyle $show_mtime 0\ | reportModules $search_queries {global/user modulerc} hi $hstyle\ | |||
$one_per_line $theader_cols hidden-loaded | $show_mtime 0 $one_per_line $theader_cols hidden-loaded | |||
} | } | |||
foreach dir [getModulePathList exiterronundef] { | foreach dir [getModulePathList exiterronundef] { | |||
if {$report_modulepath} { | if {$report_modulepath} { | |||
array unset mod_list | array unset mod_list | |||
# get module list (process full dir content and do not exit when | # get module list (process full dir content and do not exit when | |||
# err is raised from a modulerc) | # err is raised from a modulerc) | |||
array set mod_list [getModules $dir $mod $show_mtime\ | array set mod_list [getModules $dir $mod $show_mtime\ | |||
$search_filter $show_filter] | $search_filter $show_filter] | |||
reportModules $mod $dir mp $hstyle $show_mtime 0 $one_per_line\ | reportModules $search_queries $dir mp $hstyle $show_mtime 0\ | |||
$theader_cols hidden-loaded | $one_per_line $theader_cols hidden-loaded | |||
} else { | } else { | |||
# add result if not already added from an upper priority modpath | # add result if not already added from an upper priority modpath | |||
foreach {elt props} [getModules $dir $mod $show_mtime\ | foreach {elt props} [getModules $dir $mod $show_mtime\ | |||
$search_filter $show_filter] { | $search_filter $show_filter] { | |||
if {![info exists mod_list($elt)]} { | if {![info exists mod_list($elt)]} { | |||
set mod_list($elt) $props | set mod_list($elt) $props | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
# no report by modulepath, mix all aggregated results | # no report by modulepath, mix all aggregated results | |||
if {!$report_modulepath} { | if {!$report_modulepath} { | |||
reportModules $mod noheader {} {} $show_mtime 0 $one_per_line\ | reportModules $search_queries noheader {} {} $show_mtime 0\ | |||
$theader_cols hidden-loaded | $one_per_line $theader_cols hidden-loaded | |||
} | } | |||
} | } | |||
# display output key | # display output key | |||
if {!$show_mtime && ![isStateEqual report_format json] && [isEltInReport\ | if {!$show_mtime && ![isStateEqual report_format json] && [isEltInReport\ | |||
key]} { | key]} { | |||
displayKey | displayKey | |||
} | } | |||
setState inhibit_errreport 0 | setState inhibit_errreport 0 | |||
skipping to change at line 1759 | skipping to change at line 1860 | |||
# define path command to call | # define path command to call | |||
set pathcmd [expr {$pos eq {remove} ? {unload-path} : {add-path}}] | set pathcmd [expr {$pos eq {remove} ? {unload-path} : {add-path}}] | |||
# by-pass any reference counter in case use is called from top level | # by-pass any reference counter in case use is called from top level | |||
# not to increase reference counter if paths are already defined | # not to increase reference counter if paths are already defined | |||
if {[isTopEvaluation]} { | if {[isTopEvaluation]} { | |||
lappend optlist --ignore-refcount | lappend optlist --ignore-refcount | |||
} | } | |||
if {[isTopEvaluation]} { | if {[isTopEvaluation]} { | |||
##nagelfar ignore Found constant | ||||
lappendState mode load | lappendState mode load | |||
} | } | |||
$pathcmd $pos-path $mode $pos {*}$optlist MODULEPATH {*}$pathlist | $pathcmd $pos-path $mode $pos {*}$optlist MODULEPATH {*}$pathlist | |||
if {[isTopEvaluation]} { | if {[isTopEvaluation]} { | |||
##nagelfar ignore Found constant | ||||
lpopState mode | lpopState mode | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
proc cmdModuleUse {mode pos args} { | proc cmdModuleUse {mode pos args} { | |||
if {$mode eq {unload}} { | if {$mode eq {unload}} { | |||
set pos remove | set pos remove | |||
} | } | |||
skipping to change at line 1817 | skipping to change at line 1920 | |||
} | } | |||
if {![info exists ::env(LOADEDMODULES)]} { | if {![info exists ::env(LOADEDMODULES)]} { | |||
setenv LOADEDMODULES {} | setenv LOADEDMODULES {} | |||
} | } | |||
# initialize user environment if found undefined (both MODULEPATH and | # initialize user environment if found undefined (both MODULEPATH and | |||
# LOADEDMODULES empty) | # LOADEDMODULES empty) | |||
if {[get-env MODULEPATH] eq {} && [get-env LOADEDMODULES] eq {}} { | if {[get-env MODULEPATH] eq {} && [get-env LOADEDMODULES] eq {}} { | |||
# set modpaths defined in modulespath config file if it exists | # set modpaths defined in modulespath config file if it exists | |||
# use .modulespath file in initdir if conf file are located in this dir | # use .modulespath file in initdir if conf file are located in this dir | |||
if {[file readable @modulespath@]} { | if {[file readable {@modulespath@}]} { | |||
set fdata [split [readFile @modulespath@] \n] | set fdata [split [readFile {@modulespath@}] \n] | |||
foreach fline $fdata { | foreach fline $fdata { | |||
if {[regexp {^\s*(.*?)\s*(#.*|)$} $fline match patharg] == 1\ | if {[regexp {^\s*(.*?)\s*(#.*|)$} $fline match patharg] == 1\ | |||
&& $patharg ne {}} { | && $patharg ne {}} { | |||
foreach path [split $patharg :] { | foreach path [split $patharg :] { | |||
# resolve path directory in case wildcard character used | # resolve path directory in case wildcard character used | |||
set globlist [glob -types d -nocomplain $path] | set globlist [glob -types d -nocomplain $path] | |||
if {[llength $globlist] == 0} { | if {[llength $globlist] == 0} { | |||
lappend pathlist $path | lappend pathlist $path | |||
} else { | } else { | |||
lappend pathlist {*}$globlist | lappend pathlist {*}$globlist | |||
skipping to change at line 1840 | skipping to change at line 1943 | |||
} | } | |||
} | } | |||
} | } | |||
if {[info exists pathlist]} { | if {[info exists pathlist]} { | |||
cmdModuleUse load append {*}$pathlist | cmdModuleUse load append {*}$pathlist | |||
} | } | |||
} | } | |||
# source initialization initrc after modulespaths if it exists | # source initialization initrc after modulespaths if it exists | |||
# use modulerc file in initdir if conf files are located in this dir | # use modulerc file in initdir if conf files are located in this dir | |||
if {[file exists @initrc@]} { | if {[file exists {@initrc@}]} { | |||
lappendState commandname source | lappendState commandname source | |||
cmdModuleSource load @initrc@ | cmdModuleSource load {@initrc@} | |||
lpopState commandname | lpopState commandname | |||
} | } | |||
# record what has just been loaded in the virtual init collection | ||||
setenv __MODULES_LMINIT [getLoadedInit] | ||||
# if user environment is already initialized, refresh the already loaded | # if user environment is already initialized, refresh the already loaded | |||
# modules unless if environment is inconsistent | # modules unless if environment is inconsistent | |||
} elseif {![catch {cacheCurrentModules}]} { | } elseif {![catch {cacheCurrentModules}]} { | |||
cmdModuleRefresh | cmdModuleRefresh | |||
} | } | |||
# default MODULESHOME | # default MODULESHOME | |||
setenv MODULESHOME [getConf home] | setenv MODULESHOME [getConf home] | |||
# append dir where to find module function for ksh (to get it defined in | # append dir where to find module function for ksh (to get it defined in | |||
# interactive and non-interactive sub-shells). also applies for shells | # interactive and non-interactive sub-shells). also applies for shells | |||
# listed in shells_with_ksh_fpath conf | # listed in shells_with_ksh_fpath conf | |||
if {[getState shell] in [list {*}[split [getConf shells_with_ksh_fpath] :]\ | if {[getState shell] in [list {*}[split [getConf shells_with_ksh_fpath] :]\ | |||
ksh]} { | ksh]} { | |||
append-path FPATH @initdir@/ksh-functions | append-path FPATH {@initdir@/ksh-functions} | |||
} | } | |||
# define Modules init script as shell startup file | # define Modules init script as shell startup file | |||
if {[getConf set_shell_startup] && [getState shelltype] in [list sh csh\ | if {[getConf set_shell_startup] && [getState shelltype] in [list sh csh\ | |||
fish]} { | fish]} { | |||
# setup ENV variables to get module defined in sub-shells (works for | # setup ENV variables to get module defined in sub-shells (works for | |||
# 'sh' and 'ksh' in interactive mode and 'sh' (zsh-compat), 'bash' and | # 'sh' and 'ksh' in interactive mode and 'sh' (zsh-compat), 'bash' and | |||
# 'ksh' (zsh-compat) in non-interactive mode. | # 'ksh' (zsh-compat) in non-interactive mode. | |||
setenv ENV @initdir@/profile.sh | setenv ENV {@initdir@/profile.sh} | |||
setenv BASH_ENV @initdir@/bash | setenv BASH_ENV {@initdir@/bash} | |||
} | ||||
if {[getState shelltype] in {sh csh fish}} { | ||||
# add Modules bin directory to PATH if enabled but do not increase ref | ||||
# counter variable if already there | ||||
@setbinpath@if {{@bindir@} ni [split [get-env PATH] :]} { | ||||
@setbinpath@@appendbinpath@-path --ignore-refcount PATH {@bindir@} | ||||
@setbinpath@} | ||||
# add Modules man directory to MANPATH if enabled | ||||
# initialize MANPATH if not set with a value that preserves manpath | ||||
# system configuration even after addition of paths to this variable by | ||||
# modulefiles | ||||
@setmanpath@set manpath {} | ||||
# use manpath tool if found at configure step, use MANPATH otherwise | ||||
##nagelfar ignore +2 Too long line | ||||
##nagelfar ignore Found constant | ||||
@setmanpath@@usemanpath@catch {set manpath [exec -ignorestderr 2>/dev/null | ||||
manpath]} | ||||
@setmanpath@@notusemanpath@if {[info exists ::env(MANPATH)]} { | ||||
@setmanpath@@notusemanpath@ set manpath $::env(MANPATH) | ||||
@setmanpath@@notusemanpath@} | ||||
@setmanpath@if {{@mandir@} ni [split $manpath :]} { | ||||
@setmanpath@ if {![info exists ::env(MANPATH)]} { | ||||
@setmanpath@ append-path MANPATH {} | ||||
@setmanpath@ # ensure no duplicate ':' is set | ||||
@setmanpath@ } elseif {[get-env MANPATH] eq {:}} { | ||||
@setmanpath@ remove-path MANPATH {} | ||||
@setmanpath@ append-path MANPATH {} | ||||
@setmanpath@ } | ||||
@setmanpath@ @appendmanpath@-path MANPATH {@mandir@} | ||||
@setmanpath@} | ||||
} | ||||
# source shell completion script if available, not installed in default | ||||
# completion locations and only if shell is interactive | ||||
if {[getState shell] in {@shellcompsource@} && [getState is_stderr_tty]} { | ||||
set compfile "@initdir@/[getState shell]_completion" | ||||
if {[file readable $compfile]} { | ||||
putsModfileCmd dummy "source '$compfile';" | ||||
} | ||||
} | } | |||
# clear in progress flag | # clear in progress flag | |||
unsetenv __MODULES_AUTOINIT_INPROGRESS | unsetenv __MODULES_AUTOINIT_INPROGRESS | |||
lpopState mode | lpopState mode | |||
} | } | |||
proc cmdModuleInit {args} { | proc cmdModuleInit {args} { | |||
set init_cmd [lindex $args 0] | set init_cmd [lindex $args 0] | |||
skipping to change at line 2071 | skipping to change at line 2217 | |||
report "Are you sure you want to clear all loaded modules!? \[n\] " 1 | report "Are you sure you want to clear all loaded modules!? \[n\] " 1 | |||
flush [getState reportfd] | flush [getState reportfd] | |||
} | } | |||
# fetch stdin content even if not attached to terminal in case some | # fetch stdin content even if not attached to terminal in case some | |||
# content has been piped to this channel | # content has been piped to this channel | |||
set doit [gets stdin] | set doit [gets stdin] | |||
} | } | |||
# should be confirmed or forced to proceed | # should be confirmed or forced to proceed | |||
if {[string equal -nocase -length 1 $doit y] || [getState force]} { | if {[string equal -nocase -length 1 $doit y] || [getState force]} { | |||
set vartoclear [list LOADEDMODULES __MODULES_LMALTNAME\ | ||||
__MODULES_LMCONFLICT __MODULES_LMPREREQ __MODULES_LMSOURCESH \ | ||||
__MODULES_LMTAG __MODULES_LMEXTRATAG __MODULES_LMVARIANT _LMFILES_] | ||||
# add any reference counter variable to the list to unset | ||||
lappend vartoclear {*}[array names ::env -glob __MODULES_SHARE_*] | ||||
# unset all Modules runtime variables | ||||
lappendState mode load | lappendState mode load | |||
foreach var $vartoclear { | # unset all Modules runtime variables | |||
unset-env $var | foreach globvar [getModulesEnvVarGlobList 1] { | |||
foreach var [array names ::env -glob $globvar] { | ||||
unset-env $var | ||||
} | ||||
} | } | |||
lpopState mode | lpopState mode | |||
} else { | } else { | |||
reportInfo "Modules runtime information were not cleared" | reportInfo "Modules runtime information were not cleared" | |||
} | } | |||
} | } | |||
proc cmdModuleState {args} { | proc cmdModuleState {args} { | |||
if {[llength $args] > 0} { | if {[llength $args] > 0} { | |||
set name [lindex $args 0] | set name [lindex $args 0] | |||
} | } | |||
if {[info exists name] && $name ni [concat [array names ::g_state_defs]\ | if {[info exists name] && $name ni [concat [array names ::g_state_defs]\ | |||
[array names ::g_states]]} { | [array names ::g_states]]} { | |||
knerror "State '$name' does not exist" | knerror "State '$name' does not exist" | |||
} | } | |||
# report module version unless if called by cmdModuleConfig | # report module version unless if called by cmdModuleConfig | |||
if {[lindex [info level -1] 0] ne {cmdModuleConfig}} { | if {[getCallingProcName] ne {cmdModuleConfig}} { | |||
reportVersion | reportVersion | |||
reportSeparateNextContent | reportSeparateNextContent | |||
} | } | |||
displayTableHeader hi {State name} 24 {Value} 54 | displayTableHeader hi {State name} 24 {Value} 54 | |||
# fetch specified state or all states | # fetch specified state or all states | |||
if {[info exists name]} { | if {[info exists name]} { | |||
if {$name in [array names ::g_state_defs]} { | if {$name in [array names ::g_state_defs]} { | |||
set stateval($name) [getState $name <undef> 1] | set stateval($name) [getState $name <undef> 1] | |||
skipping to change at line 2141 | skipping to change at line 2282 | |||
reportSeparateNextContent | reportSeparateNextContent | |||
# only report specified state if any | # only report specified state if any | |||
if {[info exists name]} { | if {[info exists name]} { | |||
return | return | |||
} | } | |||
# report environment variable set related to Modules | # report environment variable set related to Modules | |||
displayTableHeader hi {Env. variable} 24 {Value} 54 | displayTableHeader hi {Env. variable} 24 {Value} 54 | |||
set envvar_list {} | set envvar_list {} | |||
foreach var [list LOADEDMODULES _LMFILES_ MODULE* __MODULES_* *_module*] { | foreach var [getModulesEnvVarGlobList] { | |||
lappend envvar_list {*}[array names ::env -glob $var] | lappend envvar_list {*}[array names ::env -glob $var] | |||
} | } | |||
unset displist | unset displist | |||
foreach var [lsort -unique $envvar_list] { | foreach var [lsort -unique $envvar_list] { | |||
append displist [format {%-25s %s} $var $::env($var)] \n | append displist [format {%-25s %s} $var $::env($var)] \n | |||
} | } | |||
report $displist 1 | report $displist 1 | |||
} | } | |||
proc cmdModuleConfig {dump_state args} { | proc cmdModuleConfig {dump_state args} { | |||
skipping to change at line 2235 | skipping to change at line 2376 | |||
1]} { | 1]} { | |||
set validval 1 | set validval 1 | |||
} else { | } else { | |||
reportErrorAndExit "Invalid value for configuration option\ | reportErrorAndExit "Invalid value for configuration option\ | |||
'$name'\nValue should be an integer comprised between\ | '$name'\nValue should be an integer comprised between\ | |||
[lindex $confvalid($name) 0] and [lindex\ | [lindex $confvalid($name) 0] and [lindex\ | |||
$confvalid($name) 1]" | $confvalid($name) 1]" | |||
} | } | |||
} | } | |||
{} { | {} { | |||
##nagelfar ignore +2 Non static subcommand | ||||
if {([llength $confvalid($name)] == 1 && ![string is\ | if {([llength $confvalid($name)] == 1 && ![string is\ | |||
$confvalid($name) -strict $value]) || ([llength\ | $confvalid($name) -strict $value]) || ([llength\ | |||
$confvalid($name)] > 1 && $value ni $confvalid($name))} { | $confvalid($name)] > 1 && $value ni $confvalid($name))} { | |||
reportErrorAndExit "Valid values for configuration option\ | reportErrorAndExit "Valid values for configuration option\ | |||
'$name' are: $confvalid($name)" | '$name' are: $confvalid($name)" | |||
} else { | } else { | |||
set validval 1 | set validval 1 | |||
} | } | |||
} | } | |||
} | } | |||
skipping to change at line 2272 | skipping to change at line 2414 | |||
overridden)} 54 | overridden)} 54 | |||
# report all configs or just queried one | # report all configs or just queried one | |||
if {[info exists name]} { | if {[info exists name]} { | |||
set varlist [list $name] | set varlist [list $name] | |||
} else { | } else { | |||
set varlist [lsort [array names confval]] | set varlist [lsort [array names confval]] | |||
} | } | |||
foreach var $varlist { | foreach var $varlist { | |||
##nagelfar ignore +2 Suspicious variable name | ||||
set valrep [displayConfig $confval($var) $confvar($var) [info exists\ | set valrep [displayConfig $confval($var) $confvar($var) [info exists\ | |||
::asked_$var] $confvtrans($var) [expr {$conflockable($var) eq {1}\ | ::asked_$var] $confvtrans($var) [expr {$conflockable($var) eq {1}\ | |||
&& [isConfigLocked $var]}]] | && [isConfigLocked $var]}]] | |||
append displist [format {%-25s %s} $var $valrep] \n | append displist [format {%-25s %s} $var $valrep] \n | |||
} | } | |||
report $displist 1 | report $displist 1 | |||
reportSeparateNextContent | reportSeparateNextContent | |||
if {$dump_state} { | if {$dump_state} { | |||
cmdModuleState | cmdModuleState | |||
skipping to change at line 2325 | skipping to change at line 2468 | |||
} | } | |||
proc cmdModuleRefresh {} { | proc cmdModuleRefresh {} { | |||
lappendState mode refresh | lappendState mode refresh | |||
# create an eval id to track successful/failed module evaluations | # create an eval id to track successful/failed module evaluations | |||
pushMsgRecordId refresh-[depthState modulename] 0 | pushMsgRecordId refresh-[depthState modulename] 0 | |||
# load variants from loaded modules | # load variants from loaded modules | |||
cacheCurrentModules | cacheCurrentModules | |||
foreach lm [getLoadedModuleList] { | foreach lm [getLoadedModulePropertyList refresh] { | |||
# prepare info to execute modulefile | # prepare info to execute modulefile | |||
set vrlist [getVariantList $lm 1] | set vrlist [getVariantList $lm 1] | |||
if {[llength $vrlist] > 0} { | if {[llength $vrlist] > 0} { | |||
lassign [parseModuleSpecification 0 $lm {*}$vrlist] lmvr | lassign [parseModuleSpecification 0 $lm {*}$vrlist] lmvr | |||
} else { | } else { | |||
set lmvr $lm | set lmvr $lm | |||
} | } | |||
set lmfile [getModulefileFromLoadedModule $lm] | set lmfile [getModulefileFromLoadedModule $lm] | |||
set taglist [getExportTagList $lm] | set taglist [getExportTagList $lm] | |||
skipping to change at line 2503 | skipping to change at line 2646 | |||
popMsgRecordId | popMsgRecordId | |||
# indicates that new tags have been applied | # indicates that new tags have been applied | |||
set ret 2 | set ret 2 | |||
} | } | |||
} | } | |||
return $ret | return $ret | |||
} | } | |||
proc cmdModuleLint {args} { | ||||
# stop if no linter defined | ||||
if {[llength [getConf tcl_linter]] == 0} { | ||||
knerror {No Tcl linter program configured} | ||||
} | ||||
# extract linter program name | ||||
set linter [file rootname [file tail [lindex [getConf tcl_linter] 0]]] | ||||
# build command line | ||||
set linter_mfile [getConf tcl_linter] | ||||
set linter_mrc [getConf tcl_linter] | ||||
set linter_gmrc [getConf tcl_linter] | ||||
# add module-specific syntax database in addition to regular Tcl one | ||||
@nagelfaraddons@if {$linter eq {nagelfar}} { | ||||
@nagelfaraddons@ lappend linter_mfile -s _\ | ||||
@nagelfaraddons@ -s {@nagelfardatadir@/syntaxdb_modulefile.tcl}\ | ||||
@nagelfaraddons@ -plugin {@nagelfardatadir@/plugin_modulefile.tcl} | ||||
@nagelfaraddons@ lappend linter_mrc -s _\ | ||||
@nagelfaraddons@ -s {@nagelfardatadir@/syntaxdb_modulerc.tcl}\ | ||||
@nagelfaraddons@ -plugin {@nagelfardatadir@/plugin_modulerc.tcl} | ||||
@nagelfaraddons@ lappend linter_gmrc -s _\ | ||||
@nagelfaraddons@ -s {@nagelfardatadir@/syntaxdb_modulefile.tcl}\ | ||||
@nagelfaraddons@ -plugin {@nagelfardatadir@/plugin_globalrc.tcl} | ||||
@nagelfaraddons@} | ||||
set global_rclist [getGlobalRcFileList] | ||||
set modfilelist {} | ||||
# fetch every available modulefiles if no argument provided | ||||
if {[llength $args] == 0} { | ||||
# add global RC files | ||||
foreach rc $global_rclist { | ||||
set tolint($rc) gmrc | ||||
} | ||||
inhibitErrorReport | ||||
foreach dir [getModulePathList exiterronundef] { | ||||
# fetch all existing rc file current user has access to | ||||
foreach {elt props} [findModules $dir * 0 0] { | ||||
switch -- [lindex $props 0] { | ||||
modulerc { | ||||
set tolint($dir/$elt) mrc | ||||
} | ||||
} | ||||
} | ||||
# collect all modulefile from dir that current user has access to | ||||
# getModules will reuse the result collected for findModules | ||||
foreach {elt props} [getModules $dir *] { | ||||
switch -- [lindex $props 0] { | ||||
modulefile - virtual { | ||||
set tolint([lindex $props 2]) mfile | ||||
} | ||||
} | ||||
} | ||||
} | ||||
setState inhibit_errreport 0 | ||||
} else { | ||||
foreach mod $args { | ||||
lassign [getPathToModule $mod] modfile modname modnamevr | ||||
# error mesg has already been produced if mod not found or forbidden | ||||
if {$modfile ne {}} { | ||||
if {$modfile in $global_rclist} { | ||||
set mkind gmrc | ||||
} elseif {[file tail $modfile] in {.modulerc .version}} { | ||||
set mkind mrc | ||||
} else { | ||||
set mkind mfile | ||||
} | ||||
set tolint($modfile) $mkind | ||||
} | ||||
} | ||||
} | ||||
# execute linter program over every gathered file | ||||
foreach lintfile [lsort -dictionary [array names tolint]] { | ||||
# set a record message unique id and record modulefile title | ||||
set msgrecid lint-$lintfile | ||||
pushMsgRecordId $msgrecid | ||||
registerModuleDesignation $msgrecid $lintfile {} {} | ||||
##nagelfar ignore Suspicious variable name | ||||
if {[catch {set out [runCommand {*}[set linter_$tolint($lintfile)]\ | ||||
$lintfile]} errMsg]} { | ||||
# re-throw error but as an external one (not as a module issue) | ||||
knerror $errMsg | ||||
} | ||||
# report linting messages | ||||
displayLinterOutput $linter $out | ||||
# report all lint messages for this modulefile | ||||
reportMsgRecord "Linting [getModuleDesignation $msgrecid {} 2]" | ||||
popMsgRecordId | ||||
} | ||||
} | ||||
proc cmdModuleModToSh {shell args} { | ||||
# save shell modulecmd is initialized to | ||||
##nagelfar ignore Found constant | ||||
setState modtosh_real_shell [getState shell] | ||||
# set shell and shellType states to mod-to-sh target value | ||||
if {$shell ni [getState supported_shells]} { | ||||
reportErrorAndExit "Unsupported shell type \'$shell\'" | ||||
} | ||||
##nagelfar ignore Found constant | ||||
setState shell $shell | ||||
unsetState shelltype | ||||
# silence message report (avoid mix with produced shell code) unless if | ||||
# a debugging mode is set | ||||
if {![isVerbosityLevel trace]} { | ||||
unsetConf verbosity | ||||
set ::asked_verbosity silent | ||||
} | ||||
# modulefile evaluation is done against mod-to-sh target shell which means | ||||
# module-info will return mod-to-sh shell value | ||||
return [cmdModuleLoad load 1 0 0 {} {*}$args] | ||||
# after evaluation, renderSettings will produce shell code for mod-to-sh | ||||
# target shell. modtosh_real_shell state helps to know that shell code has | ||||
# to be output on report message channel | ||||
} | ||||
proc cmdModuleReset {} { | ||||
# use reset_target_state configuration option to know the environment state | ||||
# to restore | ||||
if {[getConf reset_target_state] eq {__purge__}} { | ||||
cmdModulePurge | ||||
} else { | ||||
cmdModuleRestore [getConf reset_target_state] | ||||
} | ||||
} | ||||
proc cmdModuleStash {} { | ||||
# check if there is something to stash | ||||
if {[getConf reset_target_state] eq {__purge__}} { | ||||
# load tags from loaded modules | ||||
cacheCurrentModules | ||||
# current environment differs from initial 'purge' state when at least | ||||
# a module is loaded and it is not super-sticky and not sticky or force | ||||
# mode is enabled to allow sticky tag unload | ||||
set diff_from_init 0 | ||||
foreach mod [getLoadedModulePropertyList name] { | ||||
if {![isModuleTagged $mod super-sticky 1] && (![isModuleTagged $mod\ | ||||
sticky 1] || [getState force])} { | ||||
set diff_from_init 1 | ||||
break | ||||
} | ||||
} | ||||
} else { | ||||
# compare current environment against initial collection to check if | ||||
# something differ | ||||
set coll [getConf reset_target_state] | ||||
# get corresponding collection or init, raise error if it does not exist | ||||
lassign [findCollections $coll exact 0 1] collfile colldesc | ||||
# fetch collection content and differences compared current environment | ||||
lassign [getDiffBetweenCurEnvAndColl $collfile $colldesc]\ | ||||
coll_path_list coll_mod_list coll_tag_arrser coll_nuasked_list\ | ||||
mod_to_unload mod_to_load path_to_unuse path_to_use is_tags_diff | ||||
array set coll_tag_arr $coll_tag_arrser | ||||
set diff_from_init [expr {[llength $mod_to_unload] > 0 || [llength\ | ||||
$mod_to_load] > 0 || [llength $path_to_unuse] > 0 || [llength\ | ||||
$path_to_use] > 0 || $is_tags_diff}] | ||||
} | ||||
if {!$diff_from_init} { | ||||
reportWarning {No specific environment to save} | ||||
return | ||||
} | ||||
# record current environment | ||||
cmdModuleSave stash-[clock milliseconds] | ||||
# restore initial environment | ||||
cmdModuleReset | ||||
} | ||||
proc cmdModuleStashpop {{stash 0}} { | ||||
# determine stash collection name from argument | ||||
set coll [getCollectionFromStash $stash] | ||||
# restore stash collection environment state | ||||
cmdModuleRestore $coll | ||||
# delete stash collection file | ||||
cmdModuleSaverm $coll | ||||
} | ||||
proc cmdModuleStashrm {{stash 0}} { | ||||
# determine stash collection name from argument | ||||
set coll [getCollectionFromStash $stash] | ||||
# delete stash collection file | ||||
cmdModuleSaverm $coll | ||||
} | ||||
proc cmdModuleStashshow {{stash 0}} { | ||||
# determine stash collection name from argument | ||||
set coll [getCollectionFromStash $stash] | ||||
# display stash collection file | ||||
cmdModuleSaveshow $coll | ||||
} | ||||
proc cmdModuleStashclear {} { | ||||
# get all stash collections (only from current target) | ||||
set collfile_list [findCollections stash-* glob 0 0 1 1] | ||||
# delete all stash collections starting from most recent | ||||
foreach collfile [lsort -decreasing $collfile_list] { | ||||
# extract collection name (without path and target extension) | ||||
set coll [file rootname [file tail $collfile]] | ||||
# delete stash collection file | ||||
cmdModuleSaverm $coll | ||||
} | ||||
} | ||||
proc cmdModuleStashlist {show_oneperline show_mtime} { | ||||
cmdModuleSavelist $show_oneperline $show_mtime {} stash-* | ||||
} | ||||
# ;;; Local Variables: *** | # ;;; Local Variables: *** | |||
# ;;; mode:tcl *** | # ;;; mode:tcl *** | |||
# ;;; End: *** | # ;;; End: *** | |||
# vim:set tabstop=3 shiftwidth=3 expandtab autoindent: | # vim:set tabstop=3 shiftwidth=3 expandtab autoindent: | |||
End of changes. 81 change blocks. | ||||
155 lines changed or deleted | 525 lines changed or added |