Skip to content
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

Testing refactor #612

Draft
wants to merge 50 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
bcf4097
Re-adding pylint test.
mwaxmonsky Oct 26, 2024
340c2f9
Simplifying arg parser.
mwaxmonsky Oct 26, 2024
1285ea9
First pass refactor of tests into integrated stack.
mwaxmonsky Oct 30, 2024
c707b20
Updating MPI cmake find with components.
mwaxmonsky Oct 30, 2024
fd66d0f
Adding mpi library.
mwaxmonsky Oct 30, 2024
278b2bd
Updating mpi library.
mwaxmonsky Oct 30, 2024
9ce27bf
Adding missing cmake.
mwaxmonsky Oct 30, 2024
68f2575
Actually building.
mwaxmonsky Oct 30, 2024
c256bed
Adding pytest dependency.
mwaxmonsky Oct 30, 2024
e7f84f4
Updating pytest binary name.
mwaxmonsky Oct 30, 2024
c886348
Updating pytest install.
mwaxmonsky Oct 30, 2024
20feac2
Updating pytest binary name.
mwaxmonsky Oct 30, 2024
efff984
Updating test binary name in ctest to distinguish between other tests…
mwaxmonsky Oct 30, 2024
84cdd96
Minor CMake cleanup and temporarily removing MPI dependency.
mwaxmonsky Nov 4, 2024
cc43fda
Re-adding MPI for testing.
mwaxmonsky Nov 4, 2024
890ea0e
Resolving merge conflicts merging develop into testing-refactor branch.
mwaxmonsky Nov 11, 2024
cfe3921
Re-adding MPI linking and minor CMake cleanup.
mwaxmonsky Nov 11, 2024
9b66008
Fixing CI job failure.
mwaxmonsky Nov 11, 2024
df44e3a
Removing pylint workflow for different PR.
mwaxmonsky Nov 11, 2024
585405f
Resolving merge conflict merging 'develop' into 'testing-refactor'
mwaxmonsky Jan 30, 2025
afee04c
Removing pfunit fetch content call and only setting additional compil…
mwaxmonsky Jan 30, 2025
8270b07
Fixing whitespace.
mwaxmonsky Jan 30, 2025
96dd11a
Converting MATCHES to STREQUAL for compiler ID checks as not using re…
mwaxmonsky Jan 30, 2025
d4c4fb8
Adding back pfunit find_package.
mwaxmonsky Jan 30, 2025
ad60987
Adding pfunit into workflow instead of cmake.
mwaxmonsky Jan 30, 2025
5346e6a
Converting advection_test to new test setup and associated changes to…
mwaxmonsky Jan 30, 2025
d536aa7
Attempt consolidating of cmake.
mwaxmonsky Jan 31, 2025
eee0f1d
Fix cmake issues.
mwaxmonsky Jan 31, 2025
9f90b8e
Making advection test name unique for ctest.
mwaxmonsky Jan 31, 2025
c0ccfaf
Fix CMake casing.
mwaxmonsky Jan 31, 2025
84a2e3e
Adding advection tests to pytest workflow.
mwaxmonsky Jan 31, 2025
b447039
Removing un-needed gitignore.
mwaxmonsky Jan 31, 2025
d6218a3
CMake cleanup and support for building multiple tests.
mwaxmonsky Jan 31, 2025
6959e43
Make unique pytest targets.
mwaxmonsky Jan 31, 2025
2fe885b
Remove unused set statement.
mwaxmonsky Jan 31, 2025
4b15859
Adding ddt_host tests to cmake build workflow.
mwaxmonsky Jan 31, 2025
cfb1fdb
Adding var_compatibility_test to cmake workflow.
mwaxmonsky Jan 31, 2025
4006597
Remove unused .gitignore
mwaxmonsky Jan 31, 2025
fc79f04
Renaming pytest files to avoid collision.
mwaxmonsky Jan 31, 2025
e802031
adding advection pytests to workflow.
mwaxmonsky Jan 31, 2025
082c332
Adding missing imports.
mwaxmonsky Jan 31, 2025
dfc0ec1
Updating advection pytest.
mwaxmonsky Jan 31, 2025
c0e01f1
Fixing ddthost datatable build file location not being put in ddthost…
mwaxmonsky Feb 1, 2025
b4d3ae1
Re-add pytest version of ddthost tests.
mwaxmonsky Feb 1, 2025
d8a5731
Fixing ddthost missing python test and adding to github workflow.
mwaxmonsky Feb 1, 2025
9f82c57
Adding var_compatibility tests to pytest.
mwaxmonsky Feb 1, 2025
8b5ead1
Moving var_compatibility test filename to avoid collision and adding …
mwaxmonsky Feb 1, 2025
cfe8c54
Fix ddt test name.
mwaxmonsky Feb 1, 2025
a801b9a
Adding missing dependencies check.
mwaxmonsky Feb 1, 2025
ce104f9
Adding missing dependencies test.
mwaxmonsky Feb 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions .github/workflows/capgen_unit_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,20 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: update repos and install dependencies
run: sudo apt-get update && sudo apt-get install -y build-essential ${{matrix.fortran-compiler}} cmake python3 git libxml2-utils
run: sudo apt-get update && sudo apt-get install -y build-essential libopenmpi-dev ${{matrix.fortran-compiler}} cmake python3 git libxml2-utils

- name: Build the framework
run: |
cmake -S. -B./build -DCCPP_FRAMEWORK_ENABLE_TESTS=ON
cd build
make

- name: Run unit tests
run: cd test && ./run_fortran_tests.sh
run: |
cd build
ctest --rerun-failed --output-on-failure . --verbose

- name: Run python tests
run: |
pip install --user pytest
BUILD_DIR=./build pytest test/capgen_test/test_reports.py
28 changes: 0 additions & 28 deletions .travis.yml

This file was deleted.

75 changes: 65 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,80 @@ project(ccpp_framework
VERSION 5.0.0
LANGUAGES Fortran)

enable_language(C CXX)
include(FetchContent)
include(cmake/ccpp_capgen.cmake)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${PROJECT_SOURCE_DIR}/cmake")


#------------------------------------------------------------------------------
# Set package definitions
set(PACKAGE "ccpp-framework")
set(AUTHORS "Dom Heinzeller" "Grant Firl" "Mike Kavulich" "Dustin Swales" "Courtney Peverley")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add more people here? Those who regularly contribute code and are on the CCPP framework dev team (@mwaxmonsky for example???)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AUTHORS seems to be an environment variable that isn't used anywhere in the framework. Do we actually need this here?

If we do want to list the project authors it should probably be in documentation, maybe the top-level README.md?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into this a while ago and I think pre-github days, this was one of the ways to list the authors when packaging a release through one of the CPack functions (or maybe there was an intent to use the variable at some point?) but now that we have a CODEOWNERS file, would it make sense to create a single source for the code authors?

There doesn't seem to be a standard way to manage contributors/authors if we want to list external contributions unfortunately so any solution we come up with will have to be hand built depending on how we want to integrate that capability as well.

string(TIMESTAMP YEAR "%Y")

option(CCPP_FRAMEWORK_BUILD_DOCUMENTATION
"Create and install the HTML documentation (requires Doxygen)" OFF)
option(CCPP_FRAMEWORK_ENABLE_OPENMP "Enable OpenMP support for the framework" OFF)
option(CCPP_FRAMEWORK_ENABLE_TESTS "Enable building/running tests" OFF)
option(BUILD_SHARED_LIBS "Build a static library" OFF)
set(CCPP_VERBOSITY "0" CACHE STRING "Verbosity level of output (default: 0)")

if(CCPP_FRAMEWORK_ENABLE_TESTS)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If CCPP_FRAMEWORK_ENABLE_TESTS is ON, then there needs to be a find_package call for pFUnit with the REQUIRED keyword. pfunit must come from the user-provided software stack. No implicit installs during cmake calls/build steps.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, happy to make that change. I'm actually looking to make a container with all the dependencies/packages already installed so the environment better mimics our development environments to make the cmake call clean as well (we can pass in the pfunit path at configure time but it's clunky without modules).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated so the debug flags are only added for test runs. I would like to create a container with the dependencies and cut down on the turnaround time to run the tests but this will work for now until that gets added.

FetchContent_Declare(
pFUnit
GIT_REPOSITORY https://github.com/Goddard-Fortran-Ecosystem/pFUnit.git
GIT_TAG 26dadb1157819ea1bd9c355c60ed52f42dd36432 # v4.10.0
)
FetchContent_MakeAvailable(pFUnit)
enable_testing()
endif()

# Use rpaths on MacOSX
set(CMAKE_MACOSX_RPATH 1)

ADD_COMPILE_OPTIONS(-O0)
message(STATUS "Compiling Fortran with ${CMAKE_Fortran_COMPILER_ID}")
if(${CMAKE_Fortran_COMPILER_ID} MATCHES "GNU")
ADD_COMPILE_OPTIONS(-fcheck=all)
ADD_COMPILE_OPTIONS(-fbacktrace)
ADD_COMPILE_OPTIONS(-ffpe-trap=zero)
ADD_COMPILE_OPTIONS(-finit-real=nan)
ADD_COMPILE_OPTIONS(-ggdb)
ADD_COMPILE_OPTIONS(-ffree-line-length-none)
ADD_COMPILE_OPTIONS(-cpp)
elseif(${CMAKE_Fortran_COMPILER_ID} MATCHES "IntelLLVM")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ifort will be staying around for quite a while longer, we need this as an option, too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay, I'll add those back in and differentiate between ifort and ifx.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added ifort support back but haven't set up a job to run it yet.

#ADD_COMPILE_OPTIONS(-check all)
ADD_COMPILE_OPTIONS(-fpe0)
ADD_COMPILE_OPTIONS(-warn)
ADD_COMPILE_OPTIONS(-traceback)
ADD_COMPILE_OPTIONS(-debug full)
ADD_COMPILE_OPTIONS(-fpp)
else()
message (WARNING "This program has only been compiled with gfortran and ifx.")
endif()

#------------------------------------------------------------------------------
# Set MPI flags for Fortran with MPI F08 interface
find_package(MPI REQUIRED Fortran)
find_package(MPI REQUIRED COMPONENTS Fortran)
if(NOT MPI_Fortran_HAVE_F08_MODULE)
message(FATAL_ERROR "MPI implementation does not support the Fortran 2008 mpi_f08 interface")
endif()

#------------------------------------------------------------------------------
# Set OpenMP flags for C/C++/Fortran
if (OPENMP)
if (CCPP_FRAMEWORK_ENABLE_OPENMP)
find_package(OpenMP REQUIRED)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}")
endif (OPENMP)
endif (CCPP_FRAMEWORK_ENABLE_OPENMP)

#------------------------------------------------------------------------------
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "Coverage")
endif()

#------------------------------------------------------------------------------
Expand All @@ -39,11 +86,19 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DDEBUG)
endif()

#------------------------------------------------------------------------------
# Request a static build
option(BUILD_SHARED_LIBS "Build a static library" OFF)

#------------------------------------------------------------------------------
# Add the sub-directories
add_subdirectory(src)
add_subdirectory(doc)

if(CCPP_FRAMEWORK_ENABLE_TESTS)
add_subdirectory(test)
endif()

if (CCPP_FRAMEWORK_BUILD_DOCUMENTATION)
find_package(Doxygen REQUIRED)
if(NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif()
add_subdirectory(doc)
endif()

94 changes: 94 additions & 0 deletions cmake/ccpp_capgen.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
function(ccpp_capgen)
set(optionalArgs CAPGEN_DEBUG)
set(oneValueArgs HOSTFILES SCHEMEFILES SUITES HOST_NAME OUTPUT_ROOT VERBOSITY)

cmake_parse_arguments(arg "${optionalArgs}" "${oneValueArgs}" "" ${ARGN})

list(APPEND CCPP_CAPGEN_CMD "${CMAKE_SOURCE_DIR}/scripts/ccpp_capgen.py")

if(DEFINED arg_CAPGEN_DEBUG AND arg_CAPGEN_DEBUG)
list(APPEND CCPP_CAPGEN_CMD "--debug")
endif()

if(DEFINED arg_HOSTFILES)
list(APPEND CCPP_CAPGEN_CMD "--host-files" "${arg_HOSTFILES}")
endif()
if(DEFINED arg_SCHEMEFILES)
list(APPEND CCPP_CAPGEN_CMD "--scheme-files" "${arg_SCHEMEFILES}")
endif()
if(DEFINED arg_SUITES)
list(APPEND CCPP_CAPGEN_CMD "--suites" "${arg_SUITES}")
endif()
if(DEFINED arg_HOST_NAME)
list(APPEND CCPP_CAPGEN_CMD "--host-name" "${arg_HOST_NAME}")
endif()
if(DEFINED arg_OUTPUT_ROOT)
message(STATUS "Creating output directory: ${arg_OUTPUT_ROOT}")
file(MAKE_DIRECTORY "${arg_OUTPUT_ROOT}")
list(APPEND CCPP_CAPGEN_CMD "--output-root" "${arg_OUTPUT_ROOT}")
endif()
if(DEFINED arg_VERBOSITY)
string(REPEAT "--verbose" ${arg_VERBOSITY} VERBOSE_PARAMS_SEPERATED)
separate_arguments(VERBOSE_PARAMS UNIX_COMMAND "${VERBOSE_PARAMS_SEPERATED}")
list(APPEND CCPP_CAPGEN_CMD ${VERBOSE_PARAMS})
endif()

message(STATUS "Running ccpp_capgen from ${CMAKE_CURRENT_SOURCE_DIR}")

string(REPLACE ";" " " CAPGEN_CMD_PARAMS_LIST "${CCPP_CAPGEN_CMD}")
message(STATUS "Running ccpp_capgen: ${CAPGEN_CMD_PARAMS_LIST}")

execute_process(COMMAND ${CCPP_CAPGEN_CMD}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE CAPGEN_OUT
ERROR_VARIABLE CAPGEN_OUT
RESULT_VARIABLE RES)

message(STATUS "ccpp-capgen stdout:" ${CAPGEN_OUT})

if(RES EQUAL 0)
message(STATUS "ccpp-capgen completed successfully")
else()
message(FATAL_ERROR "CCPP cap generation FAILED: result = ${RES}")
endif()
endfunction()



function(ccpp_datafile)
set(oneValueArgs DATATABLE REPORT_NAME CCPP_CAPS_LIB_FILES)
cmake_parse_arguments(arg "" "${oneValueArgs}" "" ${ARGN})

set(CCPP_DATAFILE_CMD "${CMAKE_SOURCE_DIR}/scripts/ccpp_datafile.py")

if(NOT DEFINED arg_DATATABLE)
message(FATAL_ERROR "function(ccpp_datafile): DATATABLE not set. A datatable file must be configured to call ccpp_datafile.")
endif()
list(APPEND CCPP_DATAFILE_CMD "${arg_DATATABLE}")

if(NOT DEFINED arg_REPORT_NAME)
message(FATAL_ERROR "function(ccpp_datafile): REPORT_NAME not set. Must specify the report to generate to run cpp_datafile.py")
endif()
list(APPEND CCPP_DATAFILE_CMD "${arg_REPORT_NAME}")

message(STATUS "${CCPP_DATAFILE_CMD}")
message(STATUS "Running ccpp_datafile from ${CMAKE_CURRENT_SOURCE_DIR}")

string(REPLACE ";" " " CCPP_DATAFILE_CMD_SEPERATED "${CCPP_DATAFILE_CMD}")
message(STATUS "Running ccpp_datafile.py command: ${CCPP_DATAFILE_CMD_SEPERATED}")

execute_process(COMMAND ${CCPP_DATAFILE_CMD}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE CCPP_CAPS
RESULT_VARIABLE RES
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE)
message(STATUS "CCPP_CAPS = ${CCPP_CAPS}")
if(RES EQUAL 0)
message(STATUS "CCPP cap files retrieved")
else()
message(FATAL_ERROR "CCPP cap file retrieval FAILED: result = ${RES}")
endif()
set(CCPP_CAPS "${CCPP_CAPS}" PARENT_SCOPE)
endfunction()

28 changes: 8 additions & 20 deletions doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,16 @@
# Doxygen rules
#
# Add a target to generate API documentation with Doxygen
find_package(Doxygen)
option(BUILD_DOCUMENTATION
"Create and install the HTML documentation (requires Doxygen)"
${DOXYGEN_FOUND})
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

#
if(BUILD_DOCUMENTATION)
if(NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif()

set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

configure_file(${doxyfile_in} ${doxyfile} @ONLY)
configure_file(${doxyfile_in} ${doxyfile} @ONLY)

add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
endif()
add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM)

set(gmtb_sty_in ${CMAKE_CURRENT_SOURCE_DIR}/DevelopersGuide/gmtb.sty)
set(gmtb_sty ${CMAKE_CURRENT_BINARY_DIR}/DevelopersGuide/gmtb.sty)
Expand Down
54 changes: 25 additions & 29 deletions scripts/ccpp_datafile.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,51 +159,49 @@ def _command_line_parser():
the list of optional arguments below.
Note that exactly one action is required.
"""
parser = argparse.ArgumentParser(description=description)
parser = argparse.ArgumentParser(description=description,
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("datatable", type=str,
help="Path to a data table XML file created by capgen")
### Only one action per call
group = parser.add_mutually_exclusive_group(required=True)
for report in _VALID_REPORTS:
rep_type = "--{}".format(report["report"].replace("_", "-"))
report_name = report["report"].replace("_", "-")
report_name_option = f"--{report_name}"
if report["type"] is bool:
group.add_argument(rep_type, action='store_true', default=False,
group.add_argument(report_name_option, action='store_true', default=False,
help=report["help"])
elif report["type"] is str:
if "metavar" in report:
group.add_argument(rep_type, required=False, type=str,
metavar=report["metavar"], default='',
help=report["help"])
report_help = report["help"]
default_str = ''
group.add_argument(report_name_option, required=False, type=str,
default=default_str, help=report_help,
metavar=report["metavar"],)
else:
group.add_argument(rep_type, required=False, type=str,
default='', help=report["help"])
group.add_argument(report_name_option, required=False, type=str,
default=default_str, help=report_help)
# end if
else:
raise ValueError("Unknown report type, '{}'".format(report["type"]))
raise ValueError(f"Unknown report type, '{report['type']}'")
# end if
# end for
###
defval = ","
help_str = "String to separate items in a list (default: '{}')"
parser.add_argument("--separator", type=str, required=False, default=defval,
metavar="SEP", dest="sep", help=help_str.format(defval))
defval = False

parser.add_argument("--separator", type=str, required=False, default=",",
metavar="SEP", dest="sep",
help="String to separate items in a list")

help_str = ("Exclude protected variables (only has an effect if the "
"requested report is returning a list of variables)."
" (default: {})")
"requested report is returning a list of variables).")
parser.add_argument("--exclude-protected", action='store_true',
required=False,
default=defval, help=help_str.format(defval))
defval = -1
help_str = ("Screen width for '--show' line wrapping. -1 means do not "
"wrap. (default: {})")
required=False, default=False, help=help_str)
parser.add_argument("--line-wrap", type=int, required=False,
metavar="LINE_WIDTH", dest="line_wrap",
default=defval, help=help_str.format(defval))
defval = 2
help_str = "Indent depth for '--show' output (default: {})"
default=-1,
help="Screen width for '--show' line wrapping. -1 means do not wrap.")
parser.add_argument("--indent", type=int, required=False, default=2,
help=help_str.format(defval))
help="Indent depth for '--show' output")
return parser

###############################################################################
Expand Down Expand Up @@ -1195,12 +1193,10 @@ def generate_ccpp_datatable(run_env, host_model, api, scheme_headers,
ARG_VARS = vars(PARGS)
_ACTION = None
_ERRMSG = ''
_ESEP = ''
for opt in ARG_VARS:
if (opt in DatatableReport.valid_actions()) and ARG_VARS[opt]:
if _ACTION:
_ERRMSG += _ESEP + "Duplicate action, '{}'".format(opt)
_ESEP = '\n'
_ERRMSG += f"Duplicate action, '{opt}'\n"
else:
_ACTION = DatatableReport(opt, ARG_VARS[opt])
# end if
Expand All @@ -1212,5 +1208,5 @@ def generate_ccpp_datatable(run_env, host_model, api, scheme_headers,
REPORT = datatable_report(PARGS.datatable, _ACTION,
PARGS.sep, PARGS.exclude_protected)
# end if
print("{}".format(REPORT.rstrip()))
print(f"{REPORT.rstrip()}")
sys.exit(0)
Loading
Loading