@@ -323,9 +323,13 @@ def get_checksum_for(self, checksums, filename=None, index=None):
323323 Obtain checksum for given filename.
324324
325325 :param checksums: a list or tuple of checksums (or None)
326- :param filename: name of the file to obtain checksum for
326+ :param filename: name of the file to obtain checksum for (Deprecated)
327327 :param index: index of file in list
328328 """
329+ # Filename has never been used; flag it as deprecated
330+ if filename :
331+ self .log .deprecated ("Filename argument to get_checksum_for() is deprecated" , '5.0' )
332+
329333 # if checksums are provided as a dict, lookup by source filename as key
330334 if isinstance (checksums , (list , tuple )):
331335 if index is not None and index < len (checksums ) and (index >= 0 or abs (index ) <= len (checksums )):
@@ -337,6 +341,59 @@ def get_checksum_for(self, checksums, filename=None, index=None):
337341 else :
338342 raise EasyBuildError ("Invalid type for checksums (%s), should be list, tuple or None." , type (checksums ))
339343
344+ def fetch_source (self , source , checksum = None , extension = False ):
345+ """
346+ Get a specific source (tarball, iso, url)
347+ Will be tested for existence or can be located
348+
349+ :param source: source to be found (single dictionary in 'sources' list, or filename)
350+ :param checksum: checksum corresponding to source
351+ :param extension: flag if being called from fetch_extension_sources()
352+ """
353+ filename , download_filename , extract_cmd , source_urls , git_config = None , None , None , None , None
354+
355+ if source is None :
356+ raise EasyBuildError ("fetch_source called with empty 'source' argument" )
357+ elif isinstance (source , string_type ):
358+ filename = source
359+ elif isinstance (source , dict ):
360+ # Making a copy to avoid modifying the object with pops
361+ source = source .copy ()
362+ filename = source .pop ('filename' , None )
363+ extract_cmd = source .pop ('extract_cmd' , None )
364+ download_filename = source .pop ('download_filename' , None )
365+ source_urls = source .pop ('source_urls' , None )
366+ git_config = source .pop ('git_config' , None )
367+ if source :
368+ raise EasyBuildError ("Found one or more unexpected keys in 'sources' specification: %s" , source )
369+
370+ elif isinstance (source , (list , tuple )) and len (source ) == 2 :
371+ self .log .deprecated ("Using a 2-element list/tuple to specify sources is deprecated, "
372+ "use a dictionary with 'filename', 'extract_cmd' keys instead" , '4.0' )
373+ filename , extract_cmd = source
374+ else :
375+ raise EasyBuildError ("Unexpected source spec, not a string or dict: %s" , source )
376+
377+ # check if the sources can be located
378+ force_download = build_option ('force_download' ) in [FORCE_DOWNLOAD_ALL , FORCE_DOWNLOAD_SOURCES ]
379+ path = self .obtain_file (filename , extension = extension , download_filename = download_filename ,
380+ force_download = force_download , urls = source_urls , git_config = git_config )
381+ if path is None :
382+ raise EasyBuildError ('No file found for source %s' , filename )
383+
384+ self .log .debug ('File %s found for source %s' % (path , filename ))
385+
386+ src = {
387+ 'name' : filename ,
388+ 'path' : path ,
389+ 'cmd' : extract_cmd ,
390+ 'checksum' : checksum ,
391+ # always set a finalpath
392+ 'finalpath' : self .builddir ,
393+ }
394+
395+ return src
396+
340397 def fetch_sources (self , sources = None , checksums = None ):
341398 """
342399 Add a list of source files (can be tarballs, isos, urls).
@@ -350,46 +407,22 @@ def fetch_sources(self, sources=None, checksums=None):
350407 if checksums is None :
351408 checksums = self .cfg ['checksums' ]
352409
410+ # Single source should be re-wrapped as a list, and checksums with it
411+ if isinstance (sources , dict ):
412+ sources = [sources ]
413+ if isinstance (checksums , string_type ):
414+ checksums = [checksums ]
415+
416+ # Loop over the list of sources; list of checksums must match >= in size
353417 for index , source in enumerate (sources ):
354- extract_cmd , download_filename , source_urls , git_config = None , None , None , None
355-
356- if isinstance (source , string_type ):
357- filename = source
358-
359- elif isinstance (source , dict ):
360- # Making a copy to avoid modifying the object with pops
361- source = source .copy ()
362- filename = source .pop ('filename' , None )
363- extract_cmd = source .pop ('extract_cmd' , None )
364- download_filename = source .pop ('download_filename' , None )
365- source_urls = source .pop ('source_urls' , None )
366- git_config = source .pop ('git_config' , None )
367- if source :
368- raise EasyBuildError ("Found one or more unexpected keys in 'sources' specification: %s" , source )
369-
370- elif isinstance (source , (list , tuple )) and len (source ) == 2 :
371- self .log .deprecated ("Using a 2-element list/tuple to specify sources is deprecated, "
372- "use a dictionary with 'filename', 'extract_cmd' keys instead" , '4.0' )
373- filename , extract_cmd = source
374- else :
375- raise EasyBuildError ("Unexpected source spec, not a string or dict: %s" , source )
418+ if source is None :
419+ raise EasyBuildError ("Empty source in sources list at index %d" , index )
376420
377- # check if the sources can be located
378- force_download = build_option ('force_download' ) in [FORCE_DOWNLOAD_ALL , FORCE_DOWNLOAD_SOURCES ]
379- path = self .obtain_file (filename , download_filename = download_filename , force_download = force_download ,
380- urls = source_urls , git_config = git_config )
381- if path :
382- self .log .debug ('File %s found for source %s' % (path , filename ))
383- self .src .append ({
384- 'name' : filename ,
385- 'path' : path ,
386- 'cmd' : extract_cmd ,
387- 'checksum' : self .get_checksum_for (checksums , filename = filename , index = index ),
388- # always set a finalpath
389- 'finalpath' : self .builddir ,
390- })
421+ src_spec = self .fetch_source (source , self .get_checksum_for (checksums = checksums , index = index ))
422+ if src_spec :
423+ self .src .append (src_spec )
391424 else :
392- raise EasyBuildError ('No file found for source %s' , filename )
425+ raise EasyBuildError ("Unable to retrieve source %s" , source )
393426
394427 self .log .info ("Added sources: %s" , self .src )
395428
@@ -436,7 +469,7 @@ def fetch_patches(self, patch_specs=None, extension=False, checksums=None):
436469 patchspec = {
437470 'name' : patch_file ,
438471 'path' : path ,
439- 'checksum' : self .get_checksum_for (checksums , filename = patch_file , index = index ),
472+ 'checksum' : self .get_checksum_for (checksums , index = index ),
440473 }
441474 if suff :
442475 if copy_file :
@@ -514,9 +547,27 @@ def fetch_extension_sources(self, skip_checksums=False):
514547
515548 if ext_options .get ('nosource' , None ):
516549 exts_sources .append (ext_src )
550+
551+ elif ext_options .get ('sources' , None ):
552+ sources = ext_options ['sources' ]
553+
554+ if isinstance (sources , list ):
555+ if len (sources ) == 1 :
556+ source = sources [0 ]
557+ else :
558+ error_msg = "'sources' spec for %s in exts_list must be single element list"
559+ raise EasyBuildError (error_msg , ext_name , sources )
560+ else :
561+ source = sources
562+
563+ src = self .fetch_source (source , checksums , extension = True )
564+ # Copy 'path' entry to 'src' for use with extensions
565+ ext_src .update ({'src' : src ['path' ]})
566+ exts_sources .append (ext_src )
517567 else :
518568 source_urls = ext_options .get ('source_urls' , [])
519569 force_download = build_option ('force_download' ) in [FORCE_DOWNLOAD_ALL , FORCE_DOWNLOAD_SOURCES ]
570+
520571 src_fn = self .obtain_file (fn , extension = True , urls = source_urls , force_download = force_download )
521572
522573 if src_fn :
@@ -530,7 +581,7 @@ def fetch_extension_sources(self, skip_checksums=False):
530581
531582 # verify checksum (if provided)
532583 self .log .debug ('Verifying checksums for extension source...' )
533- fn_checksum = self .get_checksum_for (checksums , filename = src_fn , index = 0 )
584+ fn_checksum = self .get_checksum_for (checksums , index = 0 )
534585 if verify_checksum (src_fn , fn_checksum ):
535586 self .log .info ('Checksum for extension source %s verified' , fn )
536587 elif build_option ('ignore_checksums' ):
@@ -556,7 +607,7 @@ def fetch_extension_sources(self, skip_checksums=False):
556607 self .log .debug ('Verifying checksums for extension patches...' )
557608 for idx , patch in enumerate (ext_patches ):
558609 patch = patch ['path' ]
559- checksum = self .get_checksum_for (checksums [1 :], filename = patch , index = idx )
610+ checksum = self .get_checksum_for (checksums [1 :], index = idx )
560611 if verify_checksum (patch , checksum ):
561612 self .log .info ('Checksum for extension patch %s verified' , patch )
562613 elif build_option ('ignore_checksums' ):
0 commit comments