4646import easybuild .tools .environment as env
4747from easybuild .tools .build_log import EasyBuildError
4848from easybuild .tools .config import build_option , get_module_naming_scheme
49- from easybuild .tools .filetools import decode_class_name , encode_class_name , read_file
49+ from easybuild .tools .filetools import decode_class_name , encode_class_name , read_file , write_file
5050from easybuild .tools .module_naming_scheme import DEVEL_MODULE_SUFFIX
5151from easybuild .tools .module_naming_scheme .utilities import avail_module_naming_schemes , det_full_ec_version
5252from easybuild .tools .module_naming_scheme .utilities import det_hidden_modname , is_valid_module_name
7878# values for these keys will not be templated in dump()
7979EXCLUDED_KEYS_REPLACE_TEMPLATES = ['easyblock' , 'name' , 'version' , 'description' , 'homepage' , 'toolchain' ]
8080
81+
82+ # ordered groups of keys to obtain a nice looking easyconfig file
83+ GROUPED_PARAMS = [
84+ ['easyblock' ],
85+ ['name' , 'version' , 'versionprefix' , 'versionsuffix' ],
86+ ['homepage' , 'description' ],
87+ ['toolchain' , 'toolchainopts' ],
88+ ['sources' , 'source_urls' ],
89+ ['patches' ],
90+ ['builddependencies' , 'dependencies' , 'hiddendependencies' ],
91+ ['osdependencies' ],
92+ ['preconfigopts' , 'configopts' ],
93+ ['prebuildopts' , 'buildopts' ],
94+ ['preinstallopts' , 'installopts' ],
95+ ['parallel' , 'maxparallel' ],
96+ ]
97+ LAST_PARAMS = ['sanity_check_paths' , 'moduleclass' ]
98+
8199_easyconfig_files_cache = {}
82100_easyconfigs_cache = {}
83101
@@ -246,6 +264,8 @@ def parse(self):
246264 local_vars = parser .get_config_dict ()
247265 self .log .debug ("Parsed easyconfig as a dictionary: %s" % local_vars )
248266
267+ self .comments = parser .get_comments ()
268+
249269 # make sure all mandatory parameters are defined
250270 # this includes both generic mandatory parameters and software-specific parameters defined via extra_options
251271 missing_mandatory_keys = [key for key in self .mandatory if key not in local_vars ]
@@ -475,25 +495,6 @@ def dump(self, fp):
475495 """
476496 Dump this easyconfig to file, with the given filename.
477497 """
478- eb_file = file (fp , 'w' )
479-
480- # ordered groups of keys to obtain a nice looking easyconfig file
481- grouped_keys = [
482- ['easyblock' ],
483- ['name' , 'version' , 'versionprefix' , 'versionsuffix' ],
484- ['homepage' , 'description' ],
485- ['toolchain' , 'toolchainopts' ],
486- ['sources' , 'source_urls' ],
487- ['patches' ],
488- ['builddependencies' , 'dependencies' , 'hiddendependencies' ],
489- ['osdependencies' ],
490- ['preconfigopts' , 'configopts' ],
491- ['prebuildopts' , 'buildopts' ],
492- ['preinstallopts' , 'installopts' ],
493- ['parallel' , 'maxparallel' ],
494- ]
495-
496- last_keys = ['sanity_check_paths' , 'moduleclass' ]
497498
498499 orig_enable_templating = self .enable_templating
499500 self .enable_templating = False # templated values should be dumped unresolved
@@ -509,6 +510,17 @@ def dump(self, fp):
509510 keys = sorted (self .template_values , key = lambda k : len (self .template_values [k ]), reverse = True )
510511 templ_val = OrderedDict ([(self .template_values [k ], k ) for k in keys if len (self .template_values [k ]) > 2 ])
511512
513+ def add_key_and_comments (key , val ):
514+ """
515+ Add key + value and comments (if any) to txt to be dumped.
516+ """
517+ if key in self .comments ['inline' ]:
518+ ebtxt .append ("%s = %s %s" % (key , val , self .comments ['inline' ][key ]))
519+ else :
520+ if key in self .comments ['above' ]:
521+ ebtxt .extend (self .comments ['above' ][key ])
522+ ebtxt .append ("%s = %s" % (key , val ))
523+
512524 def include_defined_parameters (keyset ):
513525 """
514526 Internal function to include parameters in the dumped easyconfig file which have a non-default value.
@@ -537,29 +549,33 @@ def include_defined_parameters(keyset):
537549 else :
538550 val = newval
539551
540- ebtxt .append ("%s = %s" % (key , val ))
552+ add_key_and_comments (key , val )
553+
541554 printed_keys .append (key )
542555 printed = True
543556 if printed :
544557 ebtxt .append ('' )
545558
546- # print easyconfig parameters ordered and in groups specified above
547559 ebtxt = []
548560 printed_keys = []
549- include_defined_parameters (grouped_keys )
561+
562+ # add header comments
563+ ebtxt .extend (self .comments ['header' ])
564+
565+ # print easyconfig parameters ordered and in groups specified above
566+ include_defined_parameters (GROUPED_PARAMS )
550567
551568 # print other easyconfig parameters at the end
552- keys_to_ignore = printed_keys + last_keys
569+ keys_to_ignore = printed_keys + LAST_PARAMS
553570 for key in default_values :
554571 if key not in keys_to_ignore and self [key ] != default_values [key ]:
555- ebtxt . append ( "%s = %s" % ( key , quote_py_str (self [key ]) ))
572+ add_key_and_comments ( key , quote_py_str (self [key ]))
556573 ebtxt .append ('' )
557574
558- # print last two parameters
559- include_defined_parameters ([[k ] for k in last_keys ])
575+ # print last parameters
576+ include_defined_parameters ([[k ] for k in LAST_PARAMS ])
560577
561- eb_file .write (('\n ' .join (ebtxt )).strip ()) # strip for newlines at the end
562- eb_file .close ()
578+ write_file (fp , ('\n ' .join (ebtxt )).strip ()) # strip for newlines at the end
563579
564580 self .enable_templating = orig_enable_templating
565581
0 commit comments