From 5b08ad78d7a9ef1faf2cbdbc0e11c41aba4af60f Mon Sep 17 00:00:00 2001
From: Rupert Swarbrick <rswarbrick@lowrisc.org>
Date: Thu, 2 Apr 2026 19:10:47 +0100
Subject: [PATCH] refactor: Tidy up the last few Ruff problems in one_shot.py

The biggest change is renaming _gen_results to gen_results_for_cfg.
The motivation is that we call it on subconfig items, so it shouldn't
really have a private name. I've also made its name a bit more
differant from the existing gen_results function.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
---
 src/dvsim/flow/formal.py   |  2 +-
 src/dvsim/flow/lint.py     |  4 ++--
 src/dvsim/flow/one_shot.py | 48 +++++++++++++++++++++++++++-----------
 src/dvsim/flow/syn.py      |  4 ++--
 4 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/src/dvsim/flow/formal.py b/src/dvsim/flow/formal.py
index b7bfb70f..d1b2c18a 100644
--- a/src/dvsim/flow/formal.py
+++ b/src/dvsim/flow/formal.py
@@ -179,7 +179,7 @@ def gen_results_summary(self):
 
         return self.results_summary_md
 
-    def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
+    def gen_results_for_cfg(self, results: Sequence[CompletedJobStatus]) -> None:
         """Generate results.
 
         This function is called after the regression and looks for
diff --git a/src/dvsim/flow/lint.py b/src/dvsim/flow/lint.py
index cdf434c3..35038bd0 100644
--- a/src/dvsim/flow/lint.py
+++ b/src/dvsim/flow/lint.py
@@ -101,7 +101,7 @@ def gen_results_summary(self):
 
     # TODO(#9079): This way of parsing out messages into an intermediate
     # results.hjson file will be replaced by a native parser mechanism.
-    def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
+    def gen_results_for_cfg(self, results: Sequence[CompletedJobStatus]) -> None:
         """Generate results.
 
         The function is called after the regression has completed. It looks
@@ -119,7 +119,7 @@ def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
         config files.
 
         Note that if this is a primary config, the results will
-        be generated using the _gen_results_summary function
+        be generated using the gen_results_summary function
         """
         # Generate results table for runs.
         results_str = f"## {self.results_title}\n\n"
diff --git a/src/dvsim/flow/one_shot.py b/src/dvsim/flow/one_shot.py
index c717eea2..823aa119 100644
--- a/src/dvsim/flow/one_shot.py
+++ b/src/dvsim/flow/one_shot.py
@@ -4,10 +4,12 @@
 
 """Class describing a one-shot build configuration object."""
 
+import argparse
 from abc import abstractmethod
 from collections import OrderedDict
-from collections.abc import Sequence
+from collections.abc import Callable, Mapping, Sequence
 from pathlib import Path
+from typing import Any, ClassVar
 
 from dvsim.flow.base import FlowCfg
 from dvsim.job.data import CompletedJobStatus
@@ -21,9 +23,29 @@
 class OneShotCfg(FlowCfg):
     """Simple one-shot build flow for non-simulation targets like linting, synthesis and FPV."""
 
-    ignored_wildcards = [*FlowCfg.ignored_wildcards, "build_mode", "index", "test"]
+    ignored_wildcards: ClassVar[list[str]] = [
+        *FlowCfg.ignored_wildcards,
+        "build_mode",
+        "index",
+        "test",
+    ]
+
+    def __init__(
+        self,
+        flow_cfg_file: str,
+        hjson_data: Mapping[str, Any],
+        args: argparse.Namespace,
+        mk_config: Callable[[str], FlowCfg],
+    ) -> None:
+        """Initialise OneShotCfg object.
 
-    def __init__(self, flow_cfg_file, hjson_data, args, mk_config) -> None:
+        Args:
+          flow_cfg_file: Path to hjson cfg that was loaded.
+          hjson_data: The parsed hjson from flow_cfg_file.
+          args: Arguments passed to dvsim
+          mk_config: A factory method to allow multi-layer builds.
+
+        """
         # Options set from command line
         self.tool = args.tool
         self.verbose = args.verbose
@@ -76,7 +98,7 @@ def __init__(self, flow_cfg_file, hjson_data, args, mk_config) -> None:
 
         super().__init__(flow_cfg_file, hjson_data, args, mk_config)
 
-    def _merge_hjson(self, hjson_data) -> None:
+    def _merge_hjson(self, hjson_data: Mapping[str, Any]) -> None:
         # If build_unique is set, then add current timestamp to uniquify it
         if self.build_unique:
             self.build_dir += "_" + self.timestamp
@@ -108,7 +130,9 @@ def _expand(self) -> None:
 
     # Purge the output directories. This operates on self.
     def _purge(self) -> None:
-        assert self.scratch_path
+        if not self.scratch_path:
+            raise RuntimeError("Scratch path is '', so cannot purge.")
+
         log.info("Purging scratch path %s", self.scratch_path)
         rm_path(self.scratch_path)
 
@@ -154,11 +178,11 @@ def _create_deploy_objects(self) -> None:
         self._create_dirs()
 
     @abstractmethod
-    def _gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
+    def gen_results_for_cfg(self, results: Sequence[CompletedJobStatus]) -> None:
         """Generate results for this config."""
 
     @abstractmethod
-    def gen_results_summary(self):
+    def gen_results_summary(self) -> str:
         """Gathers the aggregated results from all sub configs."""
 
     def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
@@ -177,24 +201,22 @@ def gen_results(self, results: Sequence[CompletedJobStatus]) -> None:
                 if res.block.name == item.name and res.block.variant == item.variant
             ]
 
-            result = item._gen_results(item_results)
+            result = item.gen_results_for_cfg(item_results)
 
             log.info("[results]: [%s]:\n%s\n", project, result)
             log.info("[scratch_path]: [%s] [%s]", project, item.scratch_path)
 
             # TODO: Implement HTML report using templates
+            #
+            # This was previously implemented by rendering the markdown results for the item.
 
             results_dir = Path(self.results_dir)
             results_dir.mkdir(exist_ok=True, parents=True)
 
-            # (results_dir / self.results_html_name).write_text(
-            #     md_results_to_html(self.results_title, self.css_file, item.results_md)
-            # )
-
             log.verbose("[report]: [%s] [%s/report.html]", project, item.results_dir)
 
             self.errors_seen |= item.errors_seen
 
         if self.is_primary_cfg:
             self.gen_results_summary()
-            # self.write_results(self.results_html_name, self.results_summary_md)
+            # TODO: Write a combined HTML report to self.results_html_name
diff --git a/src/dvsim/flow/syn.py b/src/dvsim/flow/syn.py
index 8c74cbf9..7b842484 100644
--- a/src/dvsim/flow/syn.py
+++ b/src/dvsim/flow/syn.py
@@ -42,7 +42,7 @@ def gen_results_summary(self):
         # Return only the tables
         return self.results_summary_md
 
-    def _gen_results(self, results):
+    def gen_results_for_cfg(self, results):
         """The function is called after the regression has completed.
 
         It looks for a regr_results.hjson file with aggregated results from the
@@ -115,7 +115,7 @@ def _gen_results(self, results):
         }
 
         note that if this is a primary config, the results will
-        be generated using the _gen_results_summary function
+        be generated using the gen_results_summary function
         """
 
         def _create_entry(val, norm=1.0, total=None, perctag="%"):
