From dbd86817c7fd7ad232f71de68d4c8a98eae6734d Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Tue, 26 Dec 2017 21:23:48 +0100 Subject: [PATCH] install: deploy MODULE_VERSION and version modfile When --enable-versioning is set at configure time, deploy the setup of the MODULE_VERSION and MODULE_VERSION_STACK environment variables in modulecmd.tcl and in a version-specific modulefile. This version-specific modulefile is deployed in a @baseprefix@/versions modulepath directory, which is also created specifically for versioning installation mode. MODULE_VERSION and MODULE_VERSION_STACK environment variables setup in modulecmd.tcl is commented if versioning installation mode is not enabled rather deleted to guaranty consistency across code coverage tests (same code line numbering whatever the installation options set). version-specific modulefile is a bit different than the one used before <4.0 as now module version is initialized when loading this module by calling the autoinit action on the modulecmd.tcl script. These version-specific modulefiles enable to switch from one module version to another but there is an incompatibility of initialization between Modules 3.2 and Modules >=4. Switching from Modules 3.2 to Modules >4 will be possible, but not going back from >4 to version 3.2. --- .gitignore | 1 + INSTALL.rst | 6 ++- Makefile | 8 ++++ Makefile.inc.in | 4 ++ configure | 11 ++++-- contrib/modulefiles/modules.in | 3 ++ contrib/modulefiles/version.in | 43 +++++++++++++++++++++ init/Makefile | 28 ++++++++++++++ modulecmd.tcl.in | 6 +++ site.exp.in | 2 + testsuite/install.00-init/010-environ.exp | 4 ++ testsuite/modules.00-init/010-environ.exp | 4 ++ testsuite/modules.70-maint/120-autoinit.exp | 26 ++++++++++++- 13 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 contrib/modulefiles/version.in diff --git a/.gitignore b/.gitignore index c70edb5c..832fd5af 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ /contrib/rpm/environment-modules.spec /contrib/scripts/add.modules /contrib/modulefiles/modules +/contrib/modulefiles/version /testsuite/example/.modulespath /testsuite/example/modulerc /compat diff --git a/INSTALL.rst b/INSTALL.rst index 1c508e46..2bac3225 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -225,7 +225,11 @@ instance ``--disable-set-manpath``): script between the two installed version of Modules (by setting-up the ``switchml`` shell function or alias). (default=yes) ---enable-versioning Append Modules version to installation prefix. +--enable-versioning Append Modules version to installation prefix and deploy + a ``versions`` modulepath shared between all versioning + enabled Modules installation. A modulefile corresponding + to Modules version is added to the shared modulepath and + enables to switch from one Modules version to another. (default=no) Optional Packages (the default for each option is displayed within diff --git a/Makefile b/Makefile index 186deae3..e19c7655 100644 --- a/Makefile +++ b/Makefile @@ -96,6 +96,13 @@ endif include version.inc endif +# comment entries if feature not enabled +ifeq ($(versioning),y) + setversioning := +else + setversioning := \# +endif + define translate-in-script sed -e 's|@prefix@|$(prefix)|g' \ -e 's|@libexecdir@|$(libexecdir)|g' \ @@ -106,6 +113,7 @@ sed -e 's|@prefix@|$(prefix)|g' \ -e 's|@TCLSH@|$(TCLSH)|g' \ -e 's|@pager@|$(pager)|g' \ -e 's|@pageropts@|$(pageropts)|g' \ + -e 's|@VERSIONING@|$(setversioning)|g' \ -e 's|@MODULES_RELEASE@|$(MODULES_RELEASE)|g' \ -e 's|@MODULES_BUILD@|$(MODULES_BUILD)|g' \ -e 's|@MODULES_RPM_RELEASE@|$(MODULES_RPM_RELEASE)|g' \ diff --git a/Makefile.inc.in b/Makefile.inc.in index 3e75891e..6ce03305 100644 --- a/Makefile.inc.in +++ b/Makefile.inc.in @@ -2,6 +2,7 @@ # run ./configure to generate Makefile.inc # set default installation paths +baseprefix := @baseprefix@ prefix := @prefix@ bindir := @bindir@ libexecdir := @libexecdir@ @@ -12,6 +13,9 @@ datarootdir := @datarootdir@ mandir := @mandir@ docdir := @docdir@ +# versioning mode installation +versioning := @versioning@ + # modulepaths and modulefiles to enable in default config modulepath := @modulepath@ loadedmodules := @loadedmodules@ diff --git a/configure b/configure index 6feaf734..f0fe247b 100755 --- a/configure +++ b/configure @@ -26,8 +26,8 @@ prog=${progpath##*/} targetlist="${progdir}/Makefile.inc ${progdir}/site.exp" # argument list -arglist="TCLSH SPHINXBUILD prefix bindir libexecdir etcdir initdir \ -datarootdir mandir docdir modulefilesdir setmanpath setbinpath \ +arglist="TCLSH SPHINXBUILD baseprefix prefix bindir libexecdir etcdir \ +initdir datarootdir mandir docdir modulefilesdir setmanpath setbinpath \ setdotmodulespath docinstall examplemodulefiles compatversion versioning \ pager pageropts modulepath loadedmodules quarantinevars" compatarglist= @@ -126,7 +126,11 @@ Optional Features: --enable-compat-version also build and install Modules compatibility (C) version and enable switching capabilities between the two versions [yes] - --enable-versioning append modules version to installation prefix [no] + --enable-versioning append modules version to installation prefix and + deploy a \`versions' modulepath, shared between all + versioning enabled Modules installation, containing + modulefiles that enable to switch from one Modules + version to another [no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -329,6 +333,7 @@ if [ $defpageropts -eq 1 -a "${pager##*/}" != 'less' ]; then fi # adapt prefix if versioning enabled +baseprefix=$prefix if [ "$versioning" = 'y' ]; then # fetch modules version from git repository tags if [ -d '.git' ]; then diff --git a/contrib/modulefiles/modules.in b/contrib/modulefiles/modules.in index 4d1c1842..554afd86 100644 --- a/contrib/modulefiles/modules.in +++ b/contrib/modulefiles/modules.in @@ -21,3 +21,6 @@ set prefix @prefix@ setenv MODULESHOME $prefix prepend-path PATH @bindir@ prepend-path MANPATH @mandir@ + +# enable module versioning modulepath +@VERSIONING@module use @baseprefix@/versions diff --git a/contrib/modulefiles/version.in b/contrib/modulefiles/version.in new file mode 100644 index 00000000..e9f0647d --- /dev/null +++ b/contrib/modulefiles/version.in @@ -0,0 +1,43 @@ +#%Module1.0##################################################################### +## +## version modulefile +## +proc ModulesHelp { } { + global version + + puts stderr "\tInitializes new version of the module command" + puts stderr "\n\tVersion $version\n" +} + +module-whatis "Initializes new version of the module command" + +# for Tcl script use only +set version @VERSION@ + +if [ expr [ module-info mode load ] || [ module-info mode display ] ] { +# get rid of old version + module unload null + module unload modules + setenv MODULE_VERSION @VERSION@ +} + +# version stack +prepend-path MODULE_VERSION_STACK @VERSION@ + +if [ module-info mode remove ] { + set prevversion [lindex [split $env(MODULE_VERSION_STACK) : ] 0 ] + unsetenv MODULE_VERSION $prevversion + + # re-initialize previous module command version (if >4.0) + regsub $version "@libexecdir@/modulecmd.tcl" $prevprefix prevmodulecmd + if {[file exists $prevmodulecmd]} { + puts stdout [exec @TCLSH@ $prevmodulecmd [module-info shell] autoinit] + } +} + +if [ expr [ module-info mode load ] || [ module-info mode display ] ] { + # bring in new version + module load modules + puts stdout [exec @TCLSH@ @libexecdir@/modulecmd.tcl [module-info shell] autoinit] +} + diff --git a/init/Makefile b/init/Makefile index f0d78744..c1551cef 100644 --- a/init/Makefile +++ b/init/Makefile @@ -44,6 +44,9 @@ endif ALL_SHELLS = $(SH_LIKE) $(CSH_LIKE) $(OTHER) all: $(ALL_SHELLS) $(ALL_CONFIG) $(EXAMPLE_MODFILES_SRCDIR)/modules +ifeq ($(versioning),y) +all: $(EXAMPLE_MODFILES_SRCDIR)/version +endif # if enabled translate to keep text after markup elsewhere remove the # entire line @@ -65,6 +68,14 @@ else notcompatversionre := s|@notcompatversion@||g endif +# comment entries if feature not enabled +ifeq ($(versioning),y) + versdir := $(baseprefix)/versions + setversioning := +else + setversioning := \# +endif + # define translation rules for quarantine mechanism ifeq ($(quarantinevars),) setquarvarsre := /@setquarvars@/d @@ -84,6 +95,7 @@ endif define translate-in-script sed -e 's|@prefix@|$(prefix)|g' \ + -e 's|@baseprefix@|$(baseprefix)|g' \ -e 's|@libexecdir@|$(libexecdir)|g' \ -e 's|@initdir@|$(initdir)|g' \ -e 's|@etcdir@|$(etcdir)|g' \ @@ -99,6 +111,7 @@ sed -e 's|@prefix@|$(prefix)|g' \ -e '$(setquarvarsre)' $(quarvarsre) \ -e '$(notsetquarvarsre)' \ -e 's|@SHELLNAME@|$@|g' \ + -e 's|@VERSIONING@|$(setversioning)|g' \ -e 's|@VERSION@|$(MODULES_RELEASE)$(MODULES_BUILD)|g' \ -e 's|@TCLSH@|$(TCLSH)|g' $< > $@ endef @@ -124,6 +137,9 @@ profile-compat.sh: profile-compat.sh.in $(EXAMPLE_MODFILES_SRCDIR)/modules: $(EXAMPLE_MODFILES_SRCDIR)/modules.in ../version.inc $(translate-in-script) +$(EXAMPLE_MODFILES_SRCDIR)/version: $(EXAMPLE_MODFILES_SRCDIR)/version.in ../version.inc + $(translate-in-script) + # example configs for test rules install-testconfig: mkdir -p $(DESTDIR)$(initdir) @@ -157,6 +173,10 @@ endif ifeq ($(examplemodulefiles),y) cp $(addprefix $(EXAMPLE_MODFILES_SRCDIR)/,$(EXAMPLE_MODFILES)) $(DESTDIR)$(modulefilesdir)/ endif +ifeq ($(versioning),y) + mkdir -p $(DESTDIR)$(versdir) + cp $(EXAMPLE_MODFILES_SRCDIR)/version $(DESTDIR)$(versdir)/$(MODULES_RELEASE)$(MODULES_BUILD) +endif uninstall: rm -f $(addprefix $(DESTDIR)$(initdir)/,$(ALL_SHELLS) fish_completion) @@ -172,6 +192,14 @@ endif rmdir $(DESTDIR)$(initdir)/zsh-functions rmdir --ignore-fail-on-non-empty $(DESTDIR)$(initdir) @if [ -d $(DESTDIR)$(initdir) ]; then echo -e "\nWARNING: $(DESTDIR)$(initdir) is not empty so skip removal\n" >&2; fi +ifeq ($(versioning),y) + rm -f $(DESTDIR)$(versdir)/$(MODULES_RELEASE)$(MODULES_BUILD) + rmdir --ignore-fail-on-non-empty $(DESTDIR)$(versdir) + @if [ -d $(DESTDIR)$(versdir) ]; then echo -e "\nWARNING: $(DESTDIR)$(versdir) is not empty so skip removal\n" >&2; fi +endif clean: rm -f $(ALL_SHELLS) modulerc .modulespath $(EXAMPLE_MODFILES_SRCDIR)/modules +ifeq ($(versioning),y) + rm -f $(EXAMPLE_MODFILES_SRCDIR)/version +endif diff --git a/modulecmd.tcl.in b/modulecmd.tcl.in index 260dd762..4ef5e333 100755 --- a/modulecmd.tcl.in +++ b/modulecmd.tcl.in @@ -5785,6 +5785,12 @@ proc cmdModuleAutoinit {} { # default MODULESHOME setenv MODULESHOME "@prefix@" + # define current Modules version if versioning enabled + @VERSIONING@if {![info exists env(MODULE_VERSION)]} { + @VERSIONING@ setenv MODULE_VERSION "@MODULES_RELEASE@@MODULES_BUILD@" + @VERSIONING@ setenv MODULE_VERSION_STACK "@MODULES_RELEASE@@MODULES_BUILD@" + @VERSIONING@} + # initialize default MODULEPATH and LOADEDMODULES if {![info exists env(MODULEPATH)] || $env(MODULEPATH) eq ""} { # set modpaths defined in .modulespath config file if it exists diff --git a/site.exp.in b/site.exp.in index 93bfc439..9a3f1e89 100644 --- a/site.exp.in +++ b/site.exp.in @@ -6,6 +6,8 @@ set install_initdir "@initdir@" set install_libexecdir "@libexecdir@" set install_modulefilesdir "@modulefilesdir@" +set install_versioning "@versioning@" + set install_modulepath "@modulepath@" set install_loadedmodules "@loadedmodules@" diff --git a/testsuite/install.00-init/010-environ.exp b/testsuite/install.00-init/010-environ.exp index 204ba5c1..57e6697a 100644 --- a/testsuite/install.00-init/010-environ.exp +++ b/testsuite/install.00-init/010-environ.exp @@ -49,6 +49,10 @@ catch {unset env(LESS)} catch {unset env(PAGER)} catch {unset env(MODULES_PAGER)} +# clean any versioning configuration +catch {unset env(MODULE_VERSION)} +catch {unset env(MODULE_VERSION_STACK)} + catch {unset env(ENV)} catch {unset env(BASH_ENV)} catch {unset env(BASH_FUNC_module\(\))} diff --git a/testsuite/modules.00-init/010-environ.exp b/testsuite/modules.00-init/010-environ.exp index f5a68989..5283d734 100644 --- a/testsuite/modules.00-init/010-environ.exp +++ b/testsuite/modules.00-init/010-environ.exp @@ -48,5 +48,9 @@ catch {unset env(MODULES_PAGER)} catch {unset env(MODULES_COLLECTION_PIN_VERSION)} catch {unset env(MODULES_COLLECTION_TARGET)} +# clean any versioning configuration +catch {unset env(MODULE_VERSION)} +catch {unset env(MODULE_VERSION_STACK)} + set env(MODULERCFILE) "$env(TESTSUITEDIR)/etc/empty" catch {unset env(MODULESHOME)} diff --git a/testsuite/modules.70-maint/120-autoinit.exp b/testsuite/modules.70-maint/120-autoinit.exp index 47f6daa6..f19b9d05 100644 --- a/testsuite/modules.70-maint/120-autoinit.exp +++ b/testsuite/modules.70-maint/120-autoinit.exp @@ -320,7 +320,13 @@ foreach shell $supported_shells { } else { set ans [list] lappend ans [list [set "func_$shell"]] - lappend ans [list set MODULESHOME $moduleshome] + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION_STACK "(.*)"] + lappend ans [list set MODULESHOME $moduleshome] + lappend ans [list set MODULE_VERSION "(.*)"] + } else { + lappend ans [list set MODULESHOME $moduleshome] + } test_cmd_re $shell "autoinit" $ans } @@ -342,22 +348,40 @@ if {(!$insmodspath || $modspath_exinstalled) && (!$insmodrc || $modrc_exinstalle set ans [list] lappend ans [list [set "func_$shell"]] if {!$insmodspath && !$insmodrc} { + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION_STACK "(.*)"] + } lappend ans [list set LOADEDMODULES ""] lappend ans [list set MODULESHOME $moduleshome] lappend ans [list set MODULEPATH ""] + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION "(.*)"] + } } elseif {$modspath_exinstalled} { + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION_STACK "(.*)"] + } lappend ans [list set MODULEPATH_modshare "(.*)"] lappend ans [list set LOADEDMODULES ""] lappend ans [list set MODULESHOME $moduleshome] lappend ans [list set MODULEPATH "$install_modulefilesdir:$install_prefix/test/modulefiles:$install_prefix/test/etc"] + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION "(.*)"] + } } elseif {!$insmodspath && $modrc_exinstalled} { lappend ans [list set _LMFILES__modshare "$install_modulefilesdir/null:1"] lappend ans [list set LOADEDMODULES_modshare "null:1"] + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION_STACK "(.*)"] + } lappend ans [list set MODULEPATH_modshare "$install_modulefilesdir:1"] lappend ans [list set _LMFILES_ "$install_modulefilesdir/null"] lappend ans [list set LOADEDMODULES "null"] lappend ans [list set MODULESHOME $moduleshome] lappend ans [list set MODULEPATH "$install_modulefilesdir"] + if {$install_versioning eq "y"} { + lappend ans [list set MODULE_VERSION "(.*)"] + } } test_cmd_re $shell "autoinit" $ans