diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1e79a1045..9a8006ef3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -11,4 +11,5 @@ | stevemullerworth | Steve Mullerworth | Met Office | 2026-01-08 | | harry-shepherd | Harry Shepherd | Met Office | 2026-01-08 | | EdHone | Ed Hone | Met Office | 2026-01-09 | +| mo-lucy-gordon | Lucy Gordon | Met Office | 2026-01-14 | diff --git a/infrastructure/fortitude.toml b/infrastructure/fortitude.toml new file mode 100644 index 000000000..2019891b4 --- /dev/null +++ b/infrastructure/fortitude.toml @@ -0,0 +1,14 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + +[check] + +file-extensions= ["f90", "F90", "X90", "x90"] #check these file types + + +select = ["C121"] + +output-format = "grouped" #group results by file diff --git a/rose-stem/app/check_fortitude_linter/file/fortitude.toml b/rose-stem/app/check_fortitude_linter/file/fortitude.toml new file mode 100644 index 000000000..577dcd310 --- /dev/null +++ b/rose-stem/app/check_fortitude_linter/file/fortitude.toml @@ -0,0 +1,15 @@ +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + +[check] + +file-extensions= ["f90", "F90", "X90", "x90"] #check these file types + + +select = ["C121"] + + +output-format = "grouped" #group results by file diff --git a/rose-stem/app/check_fortitude_linter/rose-app.conf b/rose-stem/app/check_fortitude_linter/rose-app.conf new file mode 100644 index 000000000..e20cad3bb --- /dev/null +++ b/rose-stem/app/check_fortitude_linter/rose-app.conf @@ -0,0 +1,2 @@ +[command] +default=$CYLC_WORKFLOW_RUN_DIR/bin/fortitude_launcher.py -s $SOURCE_ROOT/lfric_core diff --git a/rose-stem/bin/fortitude_launcher.py b/rose-stem/bin/fortitude_launcher.py new file mode 100755 index 000000000..d39729af3 --- /dev/null +++ b/rose-stem/bin/fortitude_launcher.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +############################################################################## +# (c) Crown copyright Met Office. All rights reserved. +# The file LICENCE, distributed with this code, contains details of the terms +# under which the code may be used. +############################################################################## + +""" +Launch fortitude on list of directories. Run on all and print outputs. Fail if +any style changes required. +""" + +import argparse +import os +import subprocess +import sys + + +def launch_fortitude(config_path, app_path): + """ + Launch fortitude as a subprocess command and check the output + """ + + command = f"fortitude --config-file {config_path} check {app_path}" + result = subprocess.run(command.split(), capture_output=True, text=True) + + print(result.stdout) + return result + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Run fortitude on all applications. If " + "application/fortitude.toml exists use that file, otherwise " + "use one in rose-stem/app/check_fortitude_linter/file. " + "Print output, raise error if any changes required." + ) + parser.add_argument( + "-s", + "--source", + help="The top level of lfric_core directory.", + required=True, + ) + args = parser.parse_args() + + failed_apps = {} + + candidates = [ + "infrastructure", + "mesh_tools", + "components/coupling", + "components/driver", + "components/science", + "components/inventory", + "components/lfric-xios", + "applications/skeleton", + "applications/simple_diffusion", + "applications/io_demo", + ] + for app in candidates: + print(f"Running on {app}\n") + app_path = os.path.join(args.source, app) + config_path = os.path.join(app_path, "fortitude.toml") + if not os.path.exists(os.path.join(config_path)): + print("Using universal config (toml) file." + " (Some apps use their own config file.)") + config_path = os.path.join( + args.source, + "rose-stem", + "app", + "check_fortitude_linter", + "file", + "fortitude.toml", + ) + + result = launch_fortitude(config_path, app_path) + if result.returncode: + # prints the app run on if there are errors of any kind + print(f"Checking: {app} \n", file=sys.stderr) + if not result.stderr: + # prints if no other/config errors are found + print("Found lint errors:", file=sys.stderr) + # prints the lint errors + print(result.stdout, file=sys.stderr) + if result.stderr: + # prints if there are other/config errors + print("Found non-lint errors: \n", file=sys.stderr) + # prints the other/config error + print(result.stderr, "\n\n\n", file=sys.stderr) + failed_apps[app] = result.stderr + + if failed_apps: + error_message = "" + print("\n\n\nSummary: Fortitude found errors in" + " the following repositories:\n", file=sys.stderr) + for failed in failed_apps: + error_message += f"{failed}\n" + sys.exit(error_message) diff --git a/rose-stem/site/meto/groups.cylc b/rose-stem/site/meto/groups.cylc index 2452ddd76..62646ad80 100644 --- a/rose-stem/site/meto/groups.cylc +++ b/rose-stem/site/meto/groups.cylc @@ -9,6 +9,7 @@ "scripts": [ "config_dump_checker", "style_checker", + "fortitude_linter", "site_validator", "validate_rose_meta", "rose-stem_lint_checker", diff --git a/rose-stem/templates/graph/populate_graph_scripts.cylc b/rose-stem/templates/graph/populate_graph_scripts.cylc index 25e0eeda1..2aa328729 100644 --- a/rose-stem/templates/graph/populate_graph_scripts.cylc +++ b/rose-stem/templates/graph/populate_graph_scripts.cylc @@ -51,6 +51,7 @@ {# * config_dump_checker #} {# * style_checker #} {# * site_validator #} + {# * fortitude_linter #} {# * rose-stem_lint_checker #} {# * validate_rose_meta #} {# * global_variables_checker #} diff --git a/rose-stem/templates/runtime/generate_runtime_scripts.cylc b/rose-stem/templates/runtime/generate_runtime_scripts.cylc index 02faaf7b2..3c501f06f 100644 --- a/rose-stem/templates/runtime/generate_runtime_scripts.cylc +++ b/rose-stem/templates/runtime/generate_runtime_scripts.cylc @@ -36,6 +36,11 @@ inherit={{inherit.str|upper}} script="rose task-run --app-key=check_style" +{% elif "fortitude_linter" in task %} + + inherit={{inherit.str|upper}} + script="rose task-run --app-key=check_fortitude_linter" + {% elif "extract_checker" in task %} inherit={{inherit.str|upper}}