<filename>scripts/metadata2html.py
#!/usr/bin/env python3

import argparse
import logging
import importlib
import os
import sys

# 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 MetadataTable, parse_metadata_file
from framework_env import CCPPFrameworkEnv

###############################################################################
# Set up the command line argument parser and other global variables          #
###############################################################################

parser = argparse.ArgumentParser()
method = parser.add_mutually_exclusive_group(required=True)
method.add_argument('--config', '-c', action='store',
                    help='path to CCPP prebuild configuration file')
method.add_argument('--metafile', '-m', action='store',
                    help='name of metadata file to convert (requires -o)')
parser.add_argument('--outputdir', '-o', action='store',
                    help='directory where to write the html files',
                    required='--metafile' in sys.argv or '-m' in sys.argv)

# List and order of variable attributes to output to HTML
ATTRIBUTES = [ 'local_name', 'standard_name', 'long_name', 'units',
               'type', 'dimensions', 'kind', 'intent' ]

###############################################################################
# Functions and subroutines                                                   #
###############################################################################

def parse_arguments():
    """Parse command line arguments."""
    args = parser.parse_args()
    config = args.config
    filename = args.metafile
    outdir = args.outputdir
    return (config, filename, outdir)

def import_config(configfile, logger):
    """Import the configuration from a given configuration file"""

    if not os.path.isfile(configfile):
        raise Exception("Configuration file {0} not found".format(configfile))

    # Import the host-model specific CCPP prebuild config;
    # split into path and module name for import
    configpath = os.path.abspath(os.path.dirname(configfile))
    configmodule = os.path.splitext(os.path.basename(configfile))[0]
    sys.path.append(configpath)
    ccpp_prebuild_config = importlib.import_module(configmodule)

    # 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())
    logger.info('Relative path to CCPP directory from  CCPP prebuild config: {}'.format(
                                                ccpp_prebuild_config.DEFAULT_BUILD_DIR))

    config = {}
    # Definitions in host-model dependent CCPP prebuild config script
    config['variable_definition_files'] = ccpp_prebuild_config.VARIABLE_DEFINITION_FILES
    config['scheme_files']              = ccpp_prebuild_config.SCHEME_FILES
    # Add model-independent, CCPP-internal variable definition files
    config['variable_definition_files'].append(CCPP_INTERNAL_VARIABLE_DEFINITON_FILE)
    # Output directory for converted metadata tables
    config['metadata_html_output_dir'] = ccpp_prebuild_config.METADATA_HTML_OUTPUT_DIR.format(build_dir=basedir)

    return config

def get_metadata_files_from_config(config, logger):
    """Create a list of metadata filenames for a CCPP prebuild configuration"""
    filenames = []
    for sourcefile in config['variable_definition_files'] + config['scheme_files']:
        metafile = os.path.splitext(sourcefile)[0]+'.meta'
        if os.path.isfile(metafile):
            filenames.append(metafile)
        else:
            # DH* Warn for now, raise exception later when
            # old metadata format is no longer supported
            logger.warn("Metadata file {} for source file {} not found, assuming old metadata format".format(
                                                                                       metafile, sourcefile))
    return filenames

def get_output_directory_from_config(config, logger):
    """Return the html output directory for a CCPP prebuild configuration"""
    outdir = config['metadata_html_output_dir']
    if not os.path.isdir(outdir):
        raise Exception("Output directory {} for converted metadata tables does not exist".format(outdir))
    return outdir

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 = parse_metadata_file(filename_in,
                                           known_ddts=registered_fortran_ddt_names(),
                                           run_env=run_env)
    for metadata_header in metadata_headers:
        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:
        config = import_config(configfile, logger)
        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, run_env)
    else:
        convert_to_html(filename, outdir, logger, run_env)

if __name__ == '__main__':
    main()

<filename>scripts/metadata2html.py
#!/usr/bin/env python3

import argparse
import logging
import importlib
import os
import sys

# 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 MetadataTable, parse_metadata_file
from framework_env import CCPPFrameworkEnv

###############################################################################
# Set up the command line argument parser and other global variables          #
###############################################################################

parser = argparse.ArgumentParser()
method = parser.add_mutually_exclusive_group(required=True)
method.add_argument('--config', '-c', action='store',
                    help='path to CCPP prebuild configuration file')
method.add_argument('--metafile', '-m', action='store',
                    help='name of metadata file to convert (requires -o)')
parser.add_argument('--outputdir', '-o', action='store',
                    help='directory where to write the html files',
                    required='--metafile' in sys.argv or '-m' in sys.argv)

# List and order of variable attributes to output to HTML
ATTRIBUTES = [ 'local_name', 'standard_name', 'long_name', 'units',
               'type', 'dimensions', 'kind', 'intent' ]

###############################################################################
# Functions and subroutines                                                   #
###############################################################################

def parse_arguments():
    """Parse command line arguments."""
    args = parser.parse_args()
    config = args.config
    filename = args.metafile
    outdir = args.outputdir
    return (config, filename, outdir)

def import_config(configfile, logger):
    """Import the configuration from a given configuration file"""

    if not os.path.isfile(configfile):
        raise Exception("Configuration file {0} not found".format(configfile))

    # Import the host-model specific CCPP prebuild config;
    # split into path and module name for import
    configpath = os.path.abspath(os.path.dirname(configfile))
    configmodule = os.path.splitext(os.path.basename(configfile))[0]
    sys.path.append(configpath)
    ccpp_prebuild_config = importlib.import_module(configmodule)

    # 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())
    logger.info('Relative path to CCPP directory from  CCPP prebuild config: {}'.format(
                                                ccpp_prebuild_config.DEFAULT_BUILD_DIR))

    config = {}
    # Definitions in host-model dependent CCPP prebuild config script
    config['variable_definition_files'] = ccpp_prebuild_config.VARIABLE_DEFINITION_FILES
    config['scheme_files']              = ccpp_prebuild_config.SCHEME_FILES
    # Add model-independent, CCPP-internal variable definition files
    config['variable_definition_files'].append(CCPP_INTERNAL_VARIABLE_DEFINITON_FILE)
    # Output directory for converted metadata tables
    config['metadata_html_output_dir'] = ccpp_prebuild_config.METADATA_HTML_OUTPUT_DIR.format(build_dir=basedir)

    return config

def get_metadata_files_from_config(config, logger):
    """Create a list of metadata filenames for a CCPP prebuild configuration"""
    filenames = []
    for sourcefile in config['variable_definition_files'] + config['scheme_files']:
        metafile = os.path.splitext(sourcefile)[0]+'.meta'
        if os.path.isfile(metafile):
            filenames.append(metafile)
        else:
            # DH* Warn for now, raise exception later when
            # old metadata format is no longer supported
            logger.warn("Metadata file {} for source file {} not found, assuming old metadata format".format(
                                                                                       metafile, sourcefile))
    return filenames

def get_output_directory_from_config(config, logger):
    """Return the html output directory for a CCPP prebuild configuration"""
    outdir = config['metadata_html_output_dir']
    if not os.path.isdir(outdir):
        raise Exception("Output directory {} for converted metadata tables does not exist".format(outdir))
    return outdir

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 = parse_metadata_file(filename_in,
                                           known_ddts=registered_fortran_ddt_names(),
                                           run_env=run_env)
    for metadata_header in metadata_headers:
        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:
        config = import_config(configfile, logger)
        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, run_env)
    else:
        convert_to_html(filename, outdir, logger, run_env)

if __name__ == '__main__':
    main()

#!/usr/bin/env python3 # CCPP framework imports ############################################################################### # Set up the command line argument parser and other global variables          # ############################################################################### # List and order of variable attributes to output to HTML ############################################################################### # Functions and subroutines                                                   # ############################################################################### Parse command line arguments. Import the configuration from a given configuration file # Import the host-model specific CCPP prebuild config; # split into path and module name for import # Get the base directory for running metadata2html.py from # the default build directory value in the CCPP prebuild config # Definitions in host-model dependent CCPP prebuild config script # Add model-independent, CCPP-internal variable definition files # Output directory for converted metadata tables Create a list of metadata filenames for a CCPP prebuild configuration # DH* Warn for now, raise exception later when # old metadata format is no longer supported Return the html output directory for a CCPP prebuild configuration Convert a metadata file into html (one html file for each table) # Initialize logging # Convert metadata file