template-engine-copier skill: initial import
Copier + Jinja template-repository design skill: reference architecture, implementation workflow, validation checklist, and a full worked example template (questionnaire, extensions, resolvers, wrapper-first .scripts). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from copier_templates_extensions import ContextHook
|
||||
|
||||
|
||||
class ContextHookExtension(ContextHook):
|
||||
update = False
|
||||
|
||||
def hook(self, context):
|
||||
_ensure_flat_variables(context)
|
||||
_ensure_resources_instances(context)
|
||||
return context
|
||||
|
||||
|
||||
def _ensure_flat_variables(context):
|
||||
if 'flat' not in context or not isinstance(context.get('flat'), dict):
|
||||
context['flat'] = {}
|
||||
|
||||
metadata = context.get('template_metadata', {}) if isinstance(context, dict) else {}
|
||||
features = context.get('features', {}) if isinstance(context, dict) else {}
|
||||
modules = features.get('modules', {}) if isinstance(features, dict) else {}
|
||||
|
||||
domain_name = metadata.get('domain', '') if isinstance(metadata, dict) else ''
|
||||
project_name = metadata.get('project', '') if isinstance(metadata, dict) else ''
|
||||
|
||||
context['flat']['domain_name'] = domain_name
|
||||
context['flat']['project_name'] = project_name
|
||||
|
||||
instances = modules.get('instances', []) if isinstance(modules, dict) else []
|
||||
is_enabled = bool(modules.get('is_enabled', False)) if isinstance(modules, dict) else False
|
||||
|
||||
names = []
|
||||
for instance in instances if isinstance(instances, list) else []:
|
||||
if isinstance(instance, dict) and instance.get('name'):
|
||||
names.append(f"{domain_name}-{project_name}-{instance['name']}")
|
||||
|
||||
context['flat']['modules_is_enabled'] = is_enabled
|
||||
context['flat']['module_instance_names'] = names
|
||||
|
||||
|
||||
def _ensure_resources_instances(context):
|
||||
"""Expand folders containing [INDEX] into concrete per-instance directories."""
|
||||
base_path = './src'
|
||||
if not os.path.exists(base_path):
|
||||
return
|
||||
|
||||
targets = []
|
||||
for root, dirs, _ in os.walk(base_path):
|
||||
for d in dirs:
|
||||
if '[INDEX]' in d:
|
||||
targets.append(os.path.join(root, d))
|
||||
|
||||
for path in targets:
|
||||
parent = os.path.dirname(path)
|
||||
instances = context.get('flat', {}).get('module_instance_names', [])
|
||||
for idx, name in enumerate(instances):
|
||||
dst = os.path.join(parent, name)
|
||||
if os.path.exists(dst):
|
||||
continue
|
||||
os.makedirs(dst, exist_ok=True)
|
||||
for fn in os.listdir(path):
|
||||
src_file = os.path.join(path, fn)
|
||||
if not os.path.isfile(src_file):
|
||||
continue
|
||||
with open(src_file, 'r', encoding='utf-8') as f:
|
||||
content = f.read().replace('INDEX', str(idx))
|
||||
with open(os.path.join(dst, fn), 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
Reference in New Issue
Block a user