-
Notifications
You must be signed in to change notification settings - Fork 67
Add script to check fortran vs metadata without a host model #558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -312,17 +312,30 @@ def compare_fheader_to_mheader(meta_header, fort_header, logger): | |
| # end if | ||
| for mind, mvar in enumerate(mlist): | ||
| lname = mvar.get_prop_value('local_name') | ||
| mname = mvar.get_prop_value('standard_name') | ||
| arrayref = is_arrayspec(lname) | ||
| fvar, find = find_var_in_list(lname, flist) | ||
| # Check for consistency between optional variables in metadata and | ||
| # optional variables in fortran. Error if optional attribute is | ||
| # missing from fortran declaration. | ||
| # first check: if metadata says the variable is optional, does the fortran match? | ||
| mopt = mvar.get_prop_value('optional') | ||
| if find and mopt: | ||
| fopt = fvar.get_prop_value('optional') | ||
| if (not fopt): | ||
| errmsg = 'Missing optional attribute in fortran declaration for variable {}, in file {}' | ||
| errors_found = add_error(errors_found, errmsg.format(mname,title)) | ||
| errmsg = f'Missing "optional" attribute in fortran declaration for variable {mname}, ' \ | ||
| 'for {title}' | ||
| errors_found = add_error(errors_found, errmsg) | ||
| # end if | ||
| # end if | ||
| # now check: if fortran says the variable is optional, does the metadata match? | ||
| if fvar: | ||
| fopt = fvar.get_prop_value('optional') | ||
| mopt = mvar.get_prop_value('optional') | ||
| if (fopt and not mopt): | ||
| errmsg = f'Missing "optional" metadata property for variable {mname}, ' \ | ||
| 'for {title}' | ||
| errors_found = add_error(errors_found, errmsg) | ||
| # end if | ||
| # end if | ||
| if mind >= flen: | ||
|
|
@@ -511,7 +524,7 @@ def parse_host_model_files(host_filenames, host_name, run_env): | |
| return host_model | ||
|
|
||
| ############################################################################### | ||
| def parse_scheme_files(scheme_filenames, run_env): | ||
| def parse_scheme_files(scheme_filenames, run_env, skip_ddt_check=False): | ||
| ############################################################################### | ||
| """ | ||
| Gather information from scheme files (e.g., init, run, and finalize | ||
|
|
@@ -520,11 +533,13 @@ def parse_scheme_files(scheme_filenames, run_env): | |
| table_dict = {} # Duplicate check and for dependencies processing | ||
| header_dict = {} # To check for duplicates | ||
| known_ddts = list() | ||
| # end if | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. orphan put out of his misery. (removed) |
||
| logger = run_env.logger | ||
| for filename in scheme_filenames: | ||
| logger.info('Reading CCPP schemes from {}'.format(filename)) | ||
| # parse metadata file | ||
| mtables = parse_metadata_file(filename, known_ddts, run_env) | ||
| mtables = parse_metadata_file(filename, known_ddts, run_env, | ||
| skip_ddt_check=skip_ddt_check) | ||
| fort_file = find_associated_fortran_file(filename) | ||
| ftables = parse_fortran_file(fort_file, run_env) | ||
| # Check Fortran against metadata (will raise an exception on error) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| #!/usr/bin/env python3 | ||
|
gold2718 marked this conversation as resolved.
|
||
|
|
||
| """ | ||
| Recursively compare all fortran and metadata files in user-supplied directory, and report any problems | ||
| USAGE: | ||
| ./offline_check_fortran_vs_metadata.py --directory <full path to directory with scheme files> (--debug) | ||
| """ | ||
|
|
||
|
|
||
| import sys | ||
| import os | ||
| import glob | ||
| import logging | ||
| import argparse | ||
| import site | ||
| # Enable imports from parent directory | ||
| site.addsitedir(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | ||
|
|
||
| # CCPP framework imports | ||
|
gold2718 marked this conversation as resolved.
|
||
| from framework_env import CCPPFrameworkEnv | ||
| from fortran_tools import parse_fortran_file | ||
| from metadata_table import parse_metadata_file | ||
| from ccpp_capgen import find_associated_fortran_file | ||
| from ccpp_capgen import check_fortran_against_metadata, parse_scheme_files | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You aren't using check_fortran_against_metadata.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed! |
||
| from parse_tools import init_log, set_log_level | ||
| from parse_tools import register_fortran_ddt_name | ||
| from parse_tools import CCPPError, ParseInternalError | ||
|
|
||
| _LOGGER = init_log(os.path.basename(__file__)) | ||
| _DUMMY_RUN_ENV = CCPPFrameworkEnv(_LOGGER, ndict={'host_files':'', | ||
| 'scheme_files':'', | ||
| 'suites':''}) | ||
|
|
||
| def find_files_to_compare(directory): | ||
| metadata_files = [] | ||
| for file in glob.glob(os.path.join(directory,'**','*.meta'), recursive=True): | ||
| metadata_files.append(file) | ||
| # end for | ||
| return metadata_files | ||
|
|
||
| def compare_fortran_and_metadata(scheme_directory, run_env): | ||
| ## Check for files | ||
| metadata_files = find_files_to_compare(scheme_directory) | ||
| # Perform checks | ||
| parse_scheme_files(metadata_files, run_env, skip_ddt_check=True) | ||
|
|
||
| def parse_command_line(arguments, description): | ||
| """Parse command-line arguments""" | ||
| parser = argparse.ArgumentParser(description=description, | ||
| formatter_class=argparse.RawTextHelpFormatter) | ||
| parser.add_argument("--directory", type=str, required=True, | ||
| metavar='top-level directory to analyze - REQUIRED', | ||
| help="""Full path to scheme directory""") | ||
| parser.add_argument("--debug", action='store_true', default=False, | ||
| help="""turn on debug mode for additional verbosity""") | ||
| pargs = parser.parse_args(arguments) | ||
| return pargs | ||
|
|
||
| def _main_func(): | ||
| """Parse command line, then parse indicated host, scheme, and suite files. | ||
| Finally, generate code to allow host model to run indicated CCPP suites.""" | ||
| pargs = parse_command_line(sys.argv[1:], __doc__) | ||
| logger = _LOGGER | ||
| if pargs.debug: | ||
| set_log_level(logger, logging.DEBUG) | ||
| else: | ||
| set_log_level(logger, logging.INFO) | ||
| # end if | ||
| compare_fortran_and_metadata(pargs.directory, _DUMMY_RUN_ENV) | ||
| print('All checks passed!') | ||
|
|
||
| ############################################################################### | ||
|
|
||
| if __name__ == "__main__": | ||
| try: | ||
| _main_func() | ||
| sys.exit(0) | ||
| except ParseInternalError as pie: | ||
| _LOGGER.exception(pie) | ||
| sys.exit(-1) | ||
| except CCPPError as ccpp_err: | ||
| if _LOGGER.getEffectiveLevel() <= logging.DEBUG: | ||
| _LOGGER.exception(ccpp_err) | ||
| else: | ||
| _LOGGER.error(ccpp_err) | ||
| # end if | ||
| sys.exit(1) | ||
| finally: | ||
| logging.shutdown() | ||
| # end try | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for threading this new input all the way down. It might come in handy elsewhere as that requirement and check have caused problems in other situations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harmless, but the line is not needed with line 322.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch - removed!