From c89c52500b83164420e15d2c59e78b7abcf779fe Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Thu, 6 Mar 2025 14:05:40 -0300 Subject: [PATCH 1/2] Add non-interactive mode support to GenerateCommand and TemplateRenderer --- struct_module/commands/generate.py | 5 +++++ struct_module/file_item.py | 7 ++++++- struct_module/template_renderer.py | 6 ++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/struct_module/commands/generate.py b/struct_module/commands/generate.py index 32103a6..66a7d74 100644 --- a/struct_module/commands/generate.py +++ b/struct_module/commands/generate.py @@ -19,6 +19,7 @@ def __init__(self, parser): parser.add_argument('-b', '--backup', type=str, help='Path to the backup folder') parser.add_argument('-f', '--file-strategy', type=str, choices=['overwrite', 'skip', 'append', 'rename', 'backup'], default='overwrite', help='Strategy for handling existing files').completer = file_strategy_completer parser.add_argument('-p', '--global-system-prompt', type=str, help='Global system prompt for OpenAI') + parser.add_argument('--non-interactive', action='store_true', help='Run the command in non-interactive mode') parser.set_defaults(func=self.execute) def execute(self, args): @@ -71,6 +72,7 @@ def _create_structure(self, args): content["global_system_prompt"] = args.global_system_prompt content["config_variables"] = config_variables content["input_store"] = args.input_store + content["non_interactive"] = args.non_interactive file_item = FileItem(content) file_item.fetch_content() elif isinstance(content, str): @@ -80,6 +82,7 @@ def _create_structure(self, args): "content": content, "config_variables": config_variables, "input_store": args.input_store, + "non_interactive": args.non_interactive, } ) @@ -131,6 +134,7 @@ def _create_structure(self, args): 'file_strategy': args.file_strategy, 'global_system_prompt': args.global_system_prompt, 'input_store': args.input_store, + 'non_interactive': args.non_interactive, }) elif isinstance(content['struct'], list): for struct in content['struct']: @@ -144,6 +148,7 @@ def _create_structure(self, args): 'file_strategy': args.file_strategy, 'global_system_prompt': args.global_system_prompt, 'input_store': args.input_store, + 'non_interactive': args.non_interactive, }) else: self.logger.warning(f"Unsupported content in folder: {folder}") diff --git a/struct_module/file_item.py b/struct_module/file_item.py index fc0c4ea..d6106c4 100644 --- a/struct_module/file_item.py +++ b/struct_module/file_item.py @@ -24,6 +24,7 @@ def __init__(self, properties): self.content_location = properties.get("file") self.permissions = properties.get("permissions") self.input_store = properties.get("input_store") + self.non_interactive = properties.get("non_interactive") self.skip = properties.get("skip", False) self.skip_if_exists = properties.get("skip_if_exists", False) @@ -36,7 +37,11 @@ def __init__(self, properties): if openai_api_key: self._configure_openai() - self.template_renderer = TemplateRenderer(self.config_variables, self.input_store) + self.template_renderer = TemplateRenderer( + self.config_variables, + self.input_store, + self.non_interactive + ) def _configure_openai(self): self.openai_client = OpenAI(api_key=openai_api_key) diff --git a/struct_module/template_renderer.py b/struct_module/template_renderer.py index 41e7f36..6495cba 100644 --- a/struct_module/template_renderer.py +++ b/struct_module/template_renderer.py @@ -8,8 +8,10 @@ from struct_module.utils import get_current_repo class TemplateRenderer: - def __init__(self, config_variables, input_store): + def __init__(self, config_variables, input_store, non_interactive): self.config_variables = config_variables + self.non_interactive = non_interactive + self.env = Environment( trim_blocks=True, block_start_string='{%@', @@ -80,7 +82,7 @@ def prompt_for_missing_vars(self, content, vars): for var in undeclared_variables: if var not in vars: default = self.input_data.get(var, default_values.get(var, "")) - if not sys.stdin.isatty(): + if self.non_interactive: user_input = default if default else "NEEDS_TO_BE_SET" else: user_input = input(f"Enter value for {var} [{default}]: ") or default From a7918d166f3753084c4e704b23dd378b38ea377f Mon Sep 17 00:00:00 2001 From: Kenneth Belitzky Date: Fri, 7 Mar 2025 19:14:01 -0300 Subject: [PATCH 2/2] Add non-interactive mode parameter to TemplateRenderer in tests --- tests/test_template_renderer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_template_renderer.py b/tests/test_template_renderer.py index 06d7374..0d1c03b 100644 --- a/tests/test_template_renderer.py +++ b/tests/test_template_renderer.py @@ -9,7 +9,8 @@ def renderer(): {"var2": {"type": "string", "default": "default2"}} ] input_store = "/tmp/input.json" - return TemplateRenderer(config_variables, input_store) + non_interactive = False + return TemplateRenderer(config_variables, input_store, non_interactive) def test_render_template(renderer): content = "Hello, {{@ var1 @}}!"