Skip to content

Commit 646a2dd

Browse files
authored
Add InputStore and Enhance Template Renderer with Input Support (#14)
**Overview:** This PR introduces several changes, primarily aimed at improving input management during template generation and adding test coverage enhancements. **Changes:** - Added a new `InputStore` class to manage input data storage in JSON format. - Updated the `TemplateRenderer` class to integrate with `InputStore` for loading and saving user inputs. - Enhanced the `generate.py` module by adding the `--input-store` argument, enabling users to specify a file path for input storage. - Refined argument handling in `generate.py` and improved the file creation process with the new `input_store` field. - Minor changes to the `FileItem` class to support `input_store` integration. - Added `pytest-cov` to the `requirements.dev.txt` for improved test coverage. **Justification:** These updates are part of an effort to streamline the input handling process for the structure generation tool. By using `InputStore`, the system can persistently manage user-provided inputs across sessions, reducing redundant data entry. Additionally, the integration with `TemplateRenderer` allows for smoother processing of template variables. **Impact:** - Enhanced user experience by minimizing repetitive input prompts. - Improved maintainability and flexibility in handling structured data. - Additional test coverage through the inclusion of `pytest-cov`.
1 parent fa7c0b8 commit 646a2dd

5 files changed

Lines changed: 55 additions & 6 deletions

File tree

requirements.dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pytest
22
flake8
33
pytest-md-report
44
pre-commit
5+
pytest-cov

struct_module/commands/generate.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(self, parser):
1313
parser.add_argument('structure_definition', type=str, help='Path to the YAML configuration file')
1414
parser.add_argument('base_path', type=str, help='Base path where the structure will be created')
1515
parser.add_argument('-s', '--structures-path', type=str, help='Path to structure definitions')
16+
parser.add_argument('-n', '--input-store', type=str, help='Path to the input store', default='/tmp/struct/input.json')
1617
parser.add_argument('-d', '--dry-run', action='store_true', help='Perform a dry run without creating any files or directories')
1718
parser.add_argument('-v', '--vars', type=str, help='Template variables in the format KEY1=value1,KEY2=value2')
1819
parser.add_argument('-b', '--backup', type=str, help='Path to the backup folder')
@@ -65,13 +66,16 @@ def _create_structure(self, args):
6566
content["name"] = name
6667
content["global_system_prompt"] = args.global_system_prompt
6768
content["config_variables"] = config_variables
69+
content["input_store"] = args.input_store
6870
file_item = FileItem(content)
6971
file_item.fetch_content()
7072
elif isinstance(content, str):
7173
file_item = FileItem(
72-
{"name": name,
73-
"content": content,
74-
"config_variables": config_variables,
74+
{
75+
"name": name,
76+
"content": content,
77+
"config_variables": config_variables,
78+
"input_store": args.input_store,
7579
}
7680
)
7781

@@ -108,6 +112,7 @@ def _create_structure(self, args):
108112
'backup': args.backup,
109113
'file_strategy': args.file_strategy,
110114
'global_system_prompt': args.global_system_prompt,
115+
'input_store': args.input_store,
111116
})
112117
elif isinstance(content['struct'], list):
113118
for struct in content['struct']:
@@ -120,6 +125,7 @@ def _create_structure(self, args):
120125
'backup': args.backup,
121126
'file_strategy': args.file_strategy,
122127
'global_system_prompt': args.global_system_prompt,
128+
'input_store': args.input_store,
123129
})
124130
else:
125131
self.logger.warning(f"Unsupported content in folder: {folder}")

struct_module/file_item.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __init__(self, properties):
2222
self.config_variables = properties.get("config_variables")
2323
self.content_location = properties.get("file")
2424
self.permissions = properties.get("permissions")
25+
self.input_store = properties.get("input_store")
2526

2627
self.system_prompt = properties.get("system_prompt") or properties.get("global_system_prompt")
2728
self.user_prompt = properties.get("user_prompt")
@@ -30,7 +31,7 @@ def __init__(self, properties):
3031
if openai_api_key:
3132
self._configure_openai()
3233

33-
self.template_renderer = TemplateRenderer(self.config_variables)
34+
self.template_renderer = TemplateRenderer(self.config_variables, self.input_store)
3435

3536
def _configure_openai(self):
3637
self.openai_client = OpenAI(api_key=openai_api_key)

struct_module/input_store.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import json
2+
import os
3+
4+
class InputStore:
5+
6+
def __init__(self, input_file):
7+
self.input_file = input_file
8+
self.data = None
9+
10+
# create directory if it doesn't exist
11+
directory = os.path.dirname(input_file)
12+
if not os.path.exists(directory):
13+
os.makedirs(directory)
14+
15+
# create file if it doesn't exist
16+
if not os.path.exists(input_file):
17+
with open(input_file, 'w') as f:
18+
json.dump({}, f)
19+
20+
def load(self):
21+
with open(self.input_file, 'r') as f:
22+
self.data = json.load(f)
23+
24+
def get_data(self):
25+
return self.data
26+
27+
def get_value(self, key):
28+
return self.data[key]
29+
30+
def set_value(self, key, value):
31+
self.data[key] = value
32+
33+
def save(self):
34+
with open(self.input_file, 'w') as f:
35+
json.dump(self.data, f, indent=2)

struct_module/template_renderer.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import logging
33
from jinja2 import Environment, meta
44
from struct_module.filters import get_latest_release, slugify
5+
from struct_module.input_store import InputStore
56

67
class TemplateRenderer:
7-
def __init__(self, config_variables):
8+
def __init__(self, config_variables, input_store):
89
self.config_variables = config_variables
910
self.env = Environment(
1011
trim_blocks=True,
@@ -22,6 +23,9 @@ def __init__(self, config_variables):
2223
}
2324
self.env.filters.update(custom_filters)
2425
self.logger = logging.getLogger(__name__)
26+
self.input_store = InputStore(input_store)
27+
self.input_store.load()
28+
self.input_data = self.input_store.get_data()
2529

2630
# Get the config variables from the list and create a dictionary that has
2731
# variable name and their default value
@@ -64,9 +68,11 @@ def prompt_for_missing_vars(self, content, vars):
6468

6569
for var in undeclared_variables:
6670
if var not in vars:
67-
default = default_values.get(var, "")
71+
default = self.input_data.get(var, default_values.get(var, ""))
6872
user_input = input(f"Enter value for {var} [{default}]: ")
6973
if not user_input:
7074
user_input = default
75+
self.input_store.set_value(var, user_input)
7176
vars[var] = user_input
77+
self.input_store.save()
7278
return vars

0 commit comments

Comments
 (0)