130130
131131class ModulesTool (object ):
132132 """An abstract interface to a tool that deals with modules."""
133+ # name of this modules tool (used in log/warning/error messages)
134+ NAME = None
133135 # position and optionname
134136 TERSE_OPTION = (0 , '--terse' )
135137 # module command to use
@@ -143,6 +145,8 @@ class ModulesTool(object):
143145 VERSION_OPTION = '--version'
144146 # minimal required version (StrictVersion; suffix rc replaced with b (and treated as beta by StrictVersion))
145147 REQ_VERSION = None
148+ # deprecated version limit (support for versions below this version is deprecated)
149+ DEPR_VERSION = None
146150 # maximum version allowed (StrictVersion; suffix rc replaced with b (and treated as beta by StrictVersion))
147151 MAX_VERSION = None
148152 # the regexp, should have a "version" group (multiline search)
@@ -159,7 +163,7 @@ def __init__(self, mod_paths=None, testing=False):
159163 # this can/should be set to True during testing
160164 self .testing = testing
161165
162- self .log = fancylogger .getLogger (self .__class__ . __name__ , fname = False )
166+ self .log = fancylogger .getLogger (self .NAME , fname = False )
163167
164168 # DEPRECATED!
165169 self ._modules = []
@@ -178,19 +182,20 @@ def __init__(self, mod_paths=None, testing=False):
178182
179183 # only use command path in environment variable if command in not available in $PATH
180184 if which (self .cmd ) is None and env_cmd_path is not None :
181- self .log .debug ('Set command via environment variable %s: %s' , self .COMMAND_ENVIRONMENT , self .cmd )
185+ self .log .debug ("Set %s command via environment variable %s: %s" ,
186+ self .NAME , self .COMMAND_ENVIRONMENT , self .cmd )
182187 self .cmd = env_cmd_path
183188
184189 # check whether paths obtained via $PATH and $LMOD_CMD are different
185190 elif which (self .cmd ) != env_cmd_path :
186- self .log .debug ("Different paths found for module command '%s' via which/$PATH and $%s: %s vs %s" ,
187- self .COMMAND , self .COMMAND_ENVIRONMENT , self .cmd , env_cmd_path )
191+ self .log .debug ("Different paths found for %s command '%s' via which/$PATH and $%s: %s vs %s" ,
192+ self .NAME , self . COMMAND , self .COMMAND_ENVIRONMENT , self .cmd , env_cmd_path )
188193
189194 # make sure the module command was found
190195 if self .cmd is None :
191- raise EasyBuildError ("No command set." )
196+ raise EasyBuildError ("No command set for %s" , self . NAME )
192197 else :
193- self .log .debug ('Using command %s' % self .cmd )
198+ self .log .debug ('Using %s command %s' , self . NAME , self .cmd )
194199
195200 # version of modules tool
196201 self .version = None
@@ -204,13 +209,13 @@ def __init__(self, mod_paths=None, testing=False):
204209
205210 def buildstats (self ):
206211 """Return tuple with data to be included in buildstats"""
207- return (self .__class__ . __name__ , self .cmd , self .version )
212+ return (self .NAME , self .cmd , self .version )
208213
209214 def set_and_check_version (self ):
210215 """Get the module version, and check any requirements"""
211- if self .COMMAND in MODULE_VERSION_CACHE :
212- self .version = MODULE_VERSION_CACHE [self .COMMAND ]
213- self .log .debug ("Found cached version for %s: %s" , self .COMMAND , self .version )
216+ if self .cmd in MODULE_VERSION_CACHE :
217+ self .version = MODULE_VERSION_CACHE [self .cmd ]
218+ self .log .debug ("Found cached version for %s command %s : %s" , self . NAME , self .COMMAND , self .version )
214219 return
215220
216221 if self .VERSION_REGEXP is None :
@@ -223,7 +228,7 @@ def set_and_check_version(self):
223228 res = ver_re .search (txt )
224229 if res :
225230 self .version = res .group ('version' )
226- self .log .info ("Found version %s" % self .version )
231+ self .log .info ("Found %s version %s" , self . NAME , self .version )
227232
228233 # make sure version is a valid StrictVersion (e.g., 5.7.3.1 is invalid),
229234 # and replace 'rc' by 'b', to make StrictVersion treat it as a beta-release
@@ -233,47 +238,59 @@ def set_and_check_version(self):
233238
234239 self .log .info ("Converted actual version to '%s'" % self .version )
235240 else :
236- raise EasyBuildError ("Failed to determine version from option '%s' output: %s" ,
237- self .VERSION_OPTION , txt )
241+ raise EasyBuildError ("Failed to determine %s version from option '%s' output: %s" ,
242+ self .NAME , self . VERSION_OPTION , txt )
238243 except (OSError ) as err :
239- raise EasyBuildError ("Failed to check version: %s" , err )
244+ raise EasyBuildError ("Failed to check %s version: %s" , self . NAME , err )
240245
241246 if self .REQ_VERSION is None and self .MAX_VERSION is None :
242247 self .log .debug ("No version requirement defined." )
243248
244249 elif build_option ('modules_tool_version_check' ):
245- self .log .debug ("Checking whether modules tool version '%s' meets requirements" , self .version )
250+ self .log .debug ("Checking whether %s version %s meets requirements" , self . NAME , self .version )
246251
247252 if self .REQ_VERSION is not None :
248- self .log .debug ("Required minimum version defined." )
253+ self .log .debug ("Required minimum %s version defined: %s" , self . NAME , self . REQ_VERSION )
249254 if StrictVersion (self .version ) < StrictVersion (self .REQ_VERSION ):
250255 raise EasyBuildError ("EasyBuild requires %s >= v%s, found v%s" ,
251- self .__class__ . __name__ , self .REQ_VERSION , self .version )
256+ self .NAME , self .REQ_VERSION , self .version )
252257 else :
253- self .log .debug ('Version %s matches requirement >= %s' , self .version , self .REQ_VERSION )
258+ self .log .debug ('%s version %s matches requirement >= %s' , self .NAME , self .version , self .REQ_VERSION )
259+
260+ if self .DEPR_VERSION is not None :
261+ self .log .debug ("Deprecated %s version limit defined: %s" , self .NAME , self .DEPR_VERSION )
262+ if StrictVersion (self .version ) < StrictVersion (self .DEPR_VERSION ):
263+ depr_msg = "Support for %s version < %s is deprecated, " % (self .NAME , self .DEPR_VERSION )
264+ depr_msg += "found version %s" % self .version
265+
266+ silence_deprecation_warnings = build_option ('silence_deprecation_warnings' ) or []
267+
268+ if self .version .startswith ('6' ) and 'Lmod6' in silence_deprecation_warnings :
269+ self .log .warning (depr_msg )
270+ else :
271+ self .log .deprecated (depr_msg , '5.0' )
254272
255273 if self .MAX_VERSION is not None :
256- self .log .debug ("Maximum allowed version defined." )
274+ self .log .debug ("Maximum allowed %s version defined: %s" , self . NAME , self . MAX_VERSION )
257275 if StrictVersion (self .version ) > StrictVersion (self .MAX_VERSION ):
258276 raise EasyBuildError ("EasyBuild requires %s <= v%s, found v%s" ,
259- self .__class__ . __name__ , self .MAX_VERSION , self .version )
277+ self .NAME , self .MAX_VERSION , self .version )
260278 else :
261279 self .log .debug ('Version %s matches requirement <= %s' , self .version , self .MAX_VERSION )
262280 else :
263281 self .log .debug ("Skipping modules tool version '%s' requirements check" , self .version )
264282
265- MODULE_VERSION_CACHE [self .COMMAND ] = self .version
283+ MODULE_VERSION_CACHE [self .cmd ] = self .version
266284
267285 def check_cmd_avail (self ):
268286 """Check whether modules tool command is available."""
269287 cmd_path = which (self .cmd )
270288 if cmd_path is not None :
271289 self .cmd = cmd_path
272- self .log .info ("Full path for module command is %s, so using it" % self .cmd )
290+ self .log .info ("Full path for %s command is %s, so using it" , self . NAME , self .cmd )
273291 else :
274- mod_tool = self .__class__ .__name__
275292 mod_tools = avail_modules_tools ().keys ()
276- error_msg = "%s modules tool can not be used, '%s' command is not available" % (mod_tool , self .cmd )
293+ error_msg = "%s modules tool can not be used, '%s' command is not available" % (self . NAME , self .cmd )
277294 error_msg += "; use --modules-tool to specify a different modules tool to use (%s)" % ', ' .join (mod_tools )
278295 raise EasyBuildError (error_msg )
279296
@@ -292,7 +309,7 @@ def check_module_function(self, allow_mismatch=False, regex=None):
292309 if regex is None :
293310 regex = r".*%s" % os .path .basename (self .cmd )
294311 mod_cmd_re = re .compile (regex , re .M )
295- mod_details = "pattern '%s' (%s)" % (mod_cmd_re .pattern , self .__class__ . __name__ )
312+ mod_details = "pattern '%s' (%s)" % (mod_cmd_re .pattern , self .NAME )
296313
297314 if ec == 0 :
298315 if mod_cmd_re .search (out ):
@@ -671,7 +688,7 @@ def set_path_env_var(self, key, paths):
671688
672689 def check_module_output (self , cmd , stdout , stderr ):
673690 """Check output of 'module' command, see if if is potentially invalid."""
674- self .log .debug ("No checking of module output implemented for %s" , self .__class__ . __name__ )
691+ self .log .debug ("No checking of module output implemented for %s" , self .NAME )
675692
676693 def compose_cmd_list (self , args , opts = None ):
677694 """
@@ -1075,6 +1092,7 @@ def update(self):
10751092
10761093class EnvironmentModulesC (ModulesTool ):
10771094 """Interface to (C) environment modules (modulecmd)."""
1095+ NAME = "Environment Modules v3"
10781096 COMMAND = "modulecmd"
10791097 REQ_VERSION = '3.2.10'
10801098 MAX_VERSION = '3.99'
@@ -1110,6 +1128,7 @@ def update(self):
11101128
11111129class EnvironmentModulesTcl (EnvironmentModulesC ):
11121130 """Interface to (Tcl) environment modules (modulecmd.tcl)."""
1131+ NAME = "ancient Tcl-only Environment Modules"
11131132 # Tcl environment modules have no --terse (yet),
11141133 # -t must be added after the command ('avail', 'list', etc.)
11151134 TERSE_OPTION = (1 , '-t' )
@@ -1182,6 +1201,7 @@ def remove_module_path(self, path, set_mod_paths=True):
11821201
11831202class EnvironmentModules (EnvironmentModulesTcl ):
11841203 """Interface to environment modules 4.0+"""
1204+ NAME = "Environment Modules v4"
11851205 COMMAND = os .path .join (os .getenv ('MODULESHOME' , 'MODULESHOME_NOT_DEFINED' ), 'libexec' , 'modulecmd.tcl' )
11861206 REQ_VERSION = '4.0.0'
11871207 MAX_VERSION = None
@@ -1197,9 +1217,11 @@ def check_module_output(self, cmd, stdout, stderr):
11971217
11981218class Lmod (ModulesTool ):
11991219 """Interface to Lmod."""
1220+ NAME = "Lmod"
12001221 COMMAND = 'lmod'
12011222 COMMAND_ENVIRONMENT = 'LMOD_CMD'
12021223 REQ_VERSION = '6.5.1'
1224+ DEPR_VERSION = '7.0.0'
12031225 REQ_VERSION_DEPENDS_ON = '7.6.1'
12041226 VERSION_REGEXP = r"^Modules\s+based\s+on\s+Lua:\s+Version\s+(?P<version>\d\S*)\s"
12051227 USER_CACHE_DIR = os .path .join (os .path .expanduser ('~' ), '.lmod.d' , '.cache' )
0 commit comments