Browse Source

Process template files on validation

nosoop 10 months ago
parent
commit
8d2fe39fc5
1 changed files with 37 additions and 4 deletions
  1. 37 4
      src/smgdc/app.py

+ 37 - 4
src/smgdc/app.py

@@ -5,6 +5,7 @@ import configparser
 import dataclasses
 import os
 import pathlib
+import string
 
 from . import validate
 from .validate import LinuxBinary, PlatformBinary, WindowsBinary
@@ -23,6 +24,12 @@ class BinaryMountSpec:
         )
 
 
+class BracedTemplate(string.Template):
+    # simple pattern that takes ${var} only
+    idpattern = None  # type: ignore[assignment]
+    braceidpattern = "[^}]*?"
+
+
 def main() -> None:
     parser = argparse.ArgumentParser()
 
@@ -30,6 +37,7 @@ def main() -> None:
     parser.add_argument(
         "--add-binary", dest="bin_mounts", type=BinaryMountSpec, action="append"
     )
+    parser.add_argument("-o", "--output-directory", type=pathlib.Path)
     parser.add_argument("--match", dest="matches", type=str, action="append")
 
     args = parser.parse_args()
@@ -53,12 +61,14 @@ def main() -> None:
         candidate_targets.append(loaded_bin)
 
     for validation_file in sorted(validation_files):
-        header = validation_file.name
+        output_partial_path = args.validation_path.relative_to(args.validation_path.parent)
         if args.validation_path.is_dir():
-            header = str(
-                pathlib.PurePosixPath(validation_file.relative_to(args.validation_path))
+            output_partial_path = pathlib.PurePosixPath(
+                validation_file.relative_to(args.validation_path)
             )
 
+        header = str(pathlib.PurePosixPath(output_partial_path))
+
         if args.matches and not any(match in header for match in args.matches):
             continue
 
@@ -69,15 +79,38 @@ def main() -> None:
 
         entries = validate.read_config(config)
 
+        failed = False
+        result_values = {}
         for name, entry in entries.items():
             target = entry.get_target_match(candidate_targets)
             try:
                 assert target, f"No binary match for {entry.target}"
                 for key, result in entry.process(target).items():
                     print("- [OK]", key.substitute(name=name), "=", result)
+                    result_values[key.substitute(name=name)] = result
             except Exception as e:
+                failed = True
                 print("- [FAIL]", name, f"({type(e).__name__}):", e)
-                # traceback.print_exception(e)
+
+        if args.output_directory:
+            if failed:
+                print("- One or more validations failed; skipping file write")
+                continue
+            output_file = args.output_directory / output_partial_path.with_suffix(".txt")
+
+            template_file = validation_file.with_suffix(".template.txt")
+            if not template_file.exists():
+                print("- Template file missing; skipping file write")
+                continue
+            output_file.parent.mkdir(parents=True, exist_ok=True)
+
+            try:
+                t = BracedTemplate(template_file.read_text())
+                output = t.substitute(result_values)
+                output_file.write_text(output)
+                print("- All checks passed; wrote output file")
+            except Exception as e:
+                print(f"- Error writing output file; skipped ({type(e).__name__}):", e)
 
 
 if __name__ == "__main__":