From 3a359dad2fa00c18c4e944f3e339b13f09cf354d Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Sat, 26 Mar 2022 20:33:34 -0600 Subject: [PATCH 1/2] Restore capability to export metadata sections (previously headers) to html --- scripts/metadata2html.py | 29 +++++++++++++++++--------- scripts/metadata_table.py | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 10 deletions(-) mode change 100644 => 100755 scripts/metadata_table.py diff --git a/scripts/metadata2html.py b/scripts/metadata2html.py index f9e8e8ab..7e4a540d 100755 --- a/scripts/metadata2html.py +++ b/scripts/metadata2html.py @@ -8,8 +8,10 @@ # CCPP framework imports from common import CCPP_INTERNAL_VARIABLE_DEFINITON_FILE +from parse_checkers import registered_fortran_ddt_names from parse_tools import init_log, set_log_level -from metadata_table import MetadataHeader +from metadata_table import MetadataTable, parse_metadata_file +from framework_env import CCPPFrameworkEnv ############################################################################### # Set up the command line argument parser and other global variables # @@ -27,7 +29,7 @@ # List and order of variable attributes to output to HTML ATTRIBUTES = [ 'local_name', 'standard_name', 'long_name', 'units', - 'type', 'dimensions', 'kind', 'intent', 'optional' ] + 'type', 'dimensions', 'kind', 'intent' ] ############################################################################### # Functions and subroutines # @@ -56,7 +58,7 @@ def import_config(configfile, logger): # Get the base directory for running metadata2html.py from # the default build directory value in the CCPP prebuild config - basedir = os.path.join(os.getcwd(), ccpp_prebuild_config.DEFAULT_BUILD_DIR) + basedir = os.path.join(os.getcwd()) logger.info('Relative path to CCPP directory from CCPP prebuild config: {}'.format( ccpp_prebuild_config.DEFAULT_BUILD_DIR)) @@ -92,21 +94,28 @@ def get_output_directory_from_config(config, logger): raise Exception("Output directory {} for converted metadata tables does not exist".format(outdir)) return outdir -def convert_to_html(filename_in, outdir, logger): +def convert_to_html(filename_in, outdir, logger, run_env): """Convert a metadata file into html (one html file for each table)""" if not os.path.isfile(filename_in): raise Exception("Metadata file {} not found".format(filename_in)) logger.info("Converting file {} to HTML".format(filename_in)) - metadata_headers = MetadataHeader.parse_metadata_file(filename_in) + metadata_headers = parse_metadata_file(filename_in, + known_ddts=registered_fortran_ddt_names(), + run_env=run_env) for metadata_header in metadata_headers: - filename_out = metadata_header.to_html(outdir, ATTRIBUTES) - if filename_out: - logger.info(" ... wrote {}".format(filename_out)) + for metadata_section in metadata_header.sections(): + filename_out = metadata_section.to_html(outdir, ATTRIBUTES) + if filename_out: + logger.info(" ... wrote {}".format(filename_out)) def main(): # Initialize logging logger = init_log('metadata2html') set_log_level(logger, logging.INFO) + run_env = CCPPFrameworkEnv(logger, ndict={'host_files':'', + 'scheme_files':'', + 'suites':''}) + # Convert metadata file (configfile, filename, outdir) = parse_arguments() if configfile: @@ -114,9 +123,9 @@ def main(): filenames = get_metadata_files_from_config(config, logger) outdir = get_output_directory_from_config(config, logger) for filename in filenames: - convert_to_html(filename, outdir, logger) + convert_to_html(filename, outdir, logger, run_env) else: - convert_to_html(filename, outdir, logger) + convert_to_html(filename, outdir, logger, run_env) if __name__ == '__main__': main() diff --git a/scripts/metadata_table.py b/scripts/metadata_table.py old mode 100644 new mode 100755 index 17e8dfdb..8af52e47 --- a/scripts/metadata_table.py +++ b/scripts/metadata_table.py @@ -604,6 +604,19 @@ class MetadataSection(ParseSource): __vref_start = re.compile(r"^\[\s*"+FORTRAN_SCALAR_REF+r"\s*\]$") + __html_template__ = """ + + +{title} + + + + +{header}{contents}
+ + +""" + def __init__(self, table_name, table_type, run_env, parse_object=None, title=None, type_in=None, module=None, process_type=None, var_dict=None, known_ddts=None): @@ -1266,6 +1279,36 @@ def is_scalar_reference(test_val): """Return True iff refers to a Fortran scalar.""" return check_fortran_ref(test_val, None, False) is not None + def to_html(self, outdir, props): + """Write html file for metadata section and return filename. + Skip metadata sections without variables""" + if not self.__variables.variable_list(): + return None + # Write table header + header = "" + for prop in props: + header += "{}".format(prop) + header += "\n" + # Write table contents, one row per variable + contents = "" + for var in self.__variables.variable_list(): + row = "" + for prop in props: + value = var.get_prop_value(prop) + # Pretty-print for dimensions + if prop == 'dimensions': + value = '(' + ', '.join(value) + ')' + elif value is None: + value = "n/a" + row += "{}".format(value) + row += "\n" + contents += row + filename = os.path.join(outdir, self.title + '.html') + with open(filename,"w") as f: + f.writelines(self.__html_template__.format(title=self.title + ' argument table', + header=header, contents=contents)) + return filename + ######################################################################## if __name__ == "__main__": From 301c6fbdd92f8b99fcf7dc3889ee878c74e44b7c Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 30 Mar 2022 20:35:43 -0600 Subject: [PATCH 2/2] Adress reviewer comments: use f-strings, move to_html up near other write routines --- scripts/metadata_table.py | 60 +++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/scripts/metadata_table.py b/scripts/metadata_table.py index 8af52e47..2ed71c2e 100755 --- a/scripts/metadata_table.py +++ b/scripts/metadata_table.py @@ -1196,6 +1196,36 @@ def write_to_file(self, filename, append=False): # end for # end with + def to_html(self, outdir, props): + """Write html file for metadata section and return filename. + Skip metadata sections without variables""" + if not self.__variables.variable_list(): + return None + # Write table header + header = f"" + for prop in props: + header += f"{prop}".format(prop=prop) + header += f"\n" + # Write table contents, one row per variable + contents = "" + for var in self.__variables.variable_list(): + row = f"" + for prop in props: + value = var.get_prop_value(prop) + # Pretty-print for dimensions + if prop == 'dimensions': + value = '(' + ', '.join(value) + ')' + elif value is None: + value = f"n/a" + row += f"{value}".format(value=value) + row += f"\n" + contents += row + filename = os.path.join(outdir, self.title + '.html') + with open(filename,"w") as f: + f.writelines(self.__html_template__.format(title=self.title + ' argument table', + header=header, contents=contents)) + return filename + def __repr__(self): base = super().__repr__() pind = base.find(' object ') @@ -1279,36 +1309,6 @@ def is_scalar_reference(test_val): """Return True iff refers to a Fortran scalar.""" return check_fortran_ref(test_val, None, False) is not None - def to_html(self, outdir, props): - """Write html file for metadata section and return filename. - Skip metadata sections without variables""" - if not self.__variables.variable_list(): - return None - # Write table header - header = "" - for prop in props: - header += "{}".format(prop) - header += "\n" - # Write table contents, one row per variable - contents = "" - for var in self.__variables.variable_list(): - row = "" - for prop in props: - value = var.get_prop_value(prop) - # Pretty-print for dimensions - if prop == 'dimensions': - value = '(' + ', '.join(value) + ')' - elif value is None: - value = "n/a" - row += "{}".format(value) - row += "\n" - contents += row - filename = os.path.join(outdir, self.title + '.html') - with open(filename,"w") as f: - f.writelines(self.__html_template__.format(title=self.title + ' argument table', - header=header, contents=contents)) - return filename - ######################################################################## if __name__ == "__main__":