Added shadow option to tree for mig

This commit is contained in:
Kevin Veen-Birkenbach 2025-07-18 19:35:44 +02:00
parent d4fbdb409f
commit 45624037b1
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
9 changed files with 80 additions and 1 deletions

View File

@ -45,6 +45,12 @@ def main():
action='store_true', action='store_true',
help="Preview graphs to console instead of writing files" help="Preview graphs to console instead of writing files"
) )
parser.add_argument(
'-s', '--shadow-folder',
type=str,
default=None,
help="If set, writes tree.json to this shadow folder instead of the role's actual meta/ folder"
)
parser.add_argument( parser.add_argument(
'-v', '--verbose', '-v', '--verbose',
action='store_true', action='store_true',
@ -57,6 +63,7 @@ def main():
print(f"Max depth: {args.depth}") print(f"Max depth: {args.depth}")
print(f"Output format: {args.output}") print(f"Output format: {args.output}")
print(f"Preview mode: {args.preview}") print(f"Preview mode: {args.preview}")
print(f"Shadow folder: {args.shadow_folder}")
for role_name, role_path in find_roles(args.role_dir): for role_name, role_path in find_roles(args.role_dir):
if args.verbose: if args.verbose:
@ -74,7 +81,13 @@ def main():
print(f"Previewing graph '{key}' for role '{role_name}'") print(f"Previewing graph '{key}' for role '{role_name}'")
output_graph(data, 'console', role_name, key) output_graph(data, 'console', role_name, key)
else: else:
tree_file = os.path.join(role_path, 'meta', 'tree.json') # Decide on output folder
if args.shadow_folder:
tree_file = os.path.join(
args.shadow_folder, role_name, 'meta', 'tree.json'
)
else:
tree_file = os.path.join(role_path, 'meta', 'tree.json')
os.makedirs(os.path.dirname(tree_file), exist_ok=True) os.makedirs(os.path.dirname(tree_file), exist_ok=True)
with open(tree_file, 'w') as f: with open(tree_file, 'w') as f:
json.dump(graphs, f, indent=2) json.dump(graphs, f, indent=2)

View File

@ -0,0 +1,66 @@
import os
import sys
import json
import tempfile
import shutil
import unittest
from unittest.mock import patch
# Import the script as a module (assumes the script is named tree.py)
SCRIPT_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), "../../../../cli/build/tree.py")
)
class TestTreeShadowFolder(unittest.TestCase):
def setUp(self):
# Create temp roles dir and a dummy role
self.roles_dir = tempfile.mkdtemp()
self.role_name = "dummyrole"
self.role_path = os.path.join(self.roles_dir, self.role_name)
os.makedirs(os.path.join(self.role_path, "meta"))
# Prepare shadow dir
self.shadow_dir = tempfile.mkdtemp()
# Patch sys.argv for the script
self.orig_argv = sys.argv[:]
sys.argv = [
SCRIPT_PATH,
"-d", self.roles_dir,
"-s", self.shadow_dir,
"-o", "json"
]
def tearDown(self):
sys.argv = self.orig_argv
shutil.rmtree(self.roles_dir)
shutil.rmtree(self.shadow_dir)
@patch("cli.build.tree.build_mappings")
@patch("cli.build.tree.output_graph")
def test_tree_json_written_to_shadow_folder(self, mock_output_graph, mock_build_mappings):
# Prepare dummy graph
dummy_graph = {"dummy": {"test": 42}}
mock_build_mappings.return_value = dummy_graph
# Run the script (as __main__)
import runpy
runpy.run_path(SCRIPT_PATH, run_name="__main__")
# Check file in shadow folder
expected_tree_path = os.path.join(
self.shadow_dir, self.role_name, "meta", "tree.json"
)
self.assertTrue(os.path.isfile(expected_tree_path), "tree.json not found in shadow folder")
# Check contents
with open(expected_tree_path) as f:
data = json.load(f)
self.assertEqual(data, dummy_graph, "tree.json content mismatch")
# Ensure nothing was written to original meta/
original_tree_path = os.path.join(self.role_path, "meta", "tree.json")
self.assertFalse(os.path.isfile(original_tree_path), "tree.json should NOT be in role's meta/")
if __name__ == "__main__":
unittest.main()