From e03a8ce2567d4e5feb20e17e7c1fd78f0a45da02 Mon Sep 17 00:00:00 2001
From: Robin De Schepper <robin.deschepper93@gmail.com>
Date: Thu, 7 Oct 2021 13:48:13 +0200
Subject: [PATCH] Added a debug mode to `build-catalogue` (#1686)

A `--debug` flag is added so that users can inspect the out-of-tree generated C++ code of their catalogue builds.
---
 scripts/build-catalogue.in | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/scripts/build-catalogue.in b/scripts/build-catalogue.in
index d352a2ed..5c7ed2ba 100755
--- a/scripts/build-catalogue.in
+++ b/scripts/build-catalogue.in
@@ -2,7 +2,7 @@
 
 import subprocess as sp
 import sys
-from tempfile import TemporaryDirectory
+from tempfile import mkdtemp, TemporaryDirectory
 import os
 from pathlib import Path
 import shutil
@@ -52,10 +52,19 @@ def parse_arguments():
                         action='store_true',
                         help='Less output.')
 
+    parser.add_argument('-d', '--debug',
+                        nargs="?",
+                        metavar="path",
+                        const=True,
+                        default=False,
+                        help='Don\'t clean up the generated temp cpp code.'
+                        + ' Can be a target path for the generated code.')
+
     parser.add_argument('-h', '--help',
                         action='help',
                         help='Display this help and exit.')
 
+
     return vars(parser.parse_args())
 
 args    = parse_arguments()
@@ -68,6 +77,7 @@ mod_dir = pwd / Path(args['modpfx'])
 mods    = [ f[:-4] for f in os.listdir(mod_dir) if f.endswith('.mod') ]
 verbose = args['verbose'] and not args['quiet']
 quiet   = args['quiet']
+debug   = args['debug']
 
 cmake = f"""
 cmake_minimum_required(VERSION 3.9)
@@ -96,9 +106,33 @@ make_catalogue(
 
 if not quiet:
     print(f"Building catalogue '{name}' from mechanisms in {mod_dir}")
+    if debug:
+        print("Debug mode enabled.")
     for m in mods:
         print(" *", m)
 
+if debug:
+    # Overwrite the local reference to `TemporaryDirectory` with a context
+    # manager that doesn't clean up the build folder so that the generated cpp
+    # code can be debugged
+    class TemporaryDirectory:
+        def __enter__(*args, **kwargs):
+            if isinstance(debug, str):
+                path = os.path.abspath(debug)
+                try:
+                    os.makedirs(path, exist_ok=False)
+                except FileExistsError:
+                    sys.stderr.write(f"Error: Debug destination '{path}' already exists.\n")
+                    sys.stderr.flush()
+                    exit(1)
+            else:
+                path = mkdtemp()
+            print(f"Building debug code in '{path}'.")
+            return path
+
+        def __exit__(*args, **kwargs):
+            pass
+
 with TemporaryDirectory() as tmp:
     tmp = Path(tmp)
     shutil.copytree(mod_dir, tmp / 'mod')
-- 
GitLab