Files
gitignore-generator/gitignore_generator/template_loader.py
7000pctAUTO 28531e11f1
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
fix: resolve CI test failures by simplifying workflow and fixing template loading
2026-02-02 16:53:04 +00:00

179 lines
6.2 KiB
Python

"""Template loader for gitignore-generator."""
import json
from pathlib import Path
from typing import Dict, List, Optional, Set
from gitignore_generator.config import config
class TemplateLoader:
"""Load and manage gitignore templates."""
def __init__(self):
"""Initialize template loader."""
self._templates_index: Optional[Dict] = None
self._custom_templates: Dict[str, str] = {}
def _load_templates_index(self) -> Dict:
"""Load the templates index file."""
if self._templates_index is None:
index_path = config.template_dir / "templates.json"
if index_path.exists():
with open(index_path, "r") as f:
self._templates_index = json.load(f)
else:
self._templates_index = {"languages": [], "ides": [], "custom": []}
assert self._templates_index is not None
return self._templates_index
def _save_templates_index(self) -> None:
"""Save the templates index file."""
index_path = config.template_dir / "templates.json"
with open(index_path, "w") as f:
json.dump(self._templates_index, f, indent=2)
def get_available_templates(self, category: Optional[str] = None) -> List[str]:
"""Get list of available templates."""
index = self._load_templates_index()
self._load_custom_templates()
if category:
templates = index.get(category, [])
if category == "languages":
templates = templates + list(self._custom_templates.keys())
return sorted(set(templates))
else:
all_templates = []
for cat in ["languages", "ides"]:
all_templates.extend(index.get(cat, []))
all_templates = all_templates + list(self._custom_templates.keys())
return sorted(set(all_templates))
def get_templates_by_category(self) -> Dict[str, List[str]]:
"""Get all templates organized by category."""
index = self._load_templates_index()
self._load_custom_templates()
result = {
"languages": index.get("languages", []),
"ides": index.get("ides", []),
"custom": list(self._custom_templates.keys())
}
return result
def _load_custom_templates(self) -> None:
"""Load custom templates from user config directory."""
if self._custom_templates:
return
custom_dir = config.custom_templates_dir
if custom_dir.exists():
for template_file in custom_dir.glob("*.gitignore"):
self._custom_templates[template_file.stem] = str(template_file)
def load_template(self, template_name: str, category: Optional[str] = None) -> Optional[str]:
"""Load a template by name."""
self._load_custom_templates()
if template_name in self._custom_templates:
custom_path = Path(self._custom_templates[template_name])
if custom_path.exists():
with open(custom_path, "r") as f:
return f.read()
del self._custom_templates[template_name]
if category:
categories = [category]
else:
categories = ["languages", "ides"]
for cat in categories:
template_path = config.template_dir / cat / f"{template_name}.gitignore"
if template_path.exists():
with open(template_path, "r") as f:
return f.read()
return None
def get_template_content(self, template_name: str) -> Optional[str]:
"""Get template content by name (searches all categories)."""
return self.load_template(template_name)
def save_custom_template(self, name: str, content: str) -> bool:
"""Save a custom template."""
custom_dir = config.custom_templates_dir
try:
custom_dir.mkdir(parents=True, exist_ok=True)
except OSError:
return False
template_path = custom_dir / f"{name}.gitignore"
try:
with open(template_path, "w") as f:
f.write(content)
self._custom_templates[name] = str(template_path)
return True
except OSError:
return False
def delete_custom_template(self, name: str) -> bool:
"""Delete a custom template."""
if name not in self._custom_templates:
return False
template_path = Path(self._custom_templates[name])
try:
if template_path.exists():
template_path.unlink()
del self._custom_templates[name]
return True
except OSError:
return False
def template_exists(self, template_name: str) -> bool:
"""Check if a template exists."""
self._load_custom_templates()
if template_name in self._custom_templates:
return True
for cat in ["languages", "ides"]:
template_path = config.template_dir / cat / f"{template_name}.gitignore"
if template_path.exists():
return True
return False
def search_templates(self, query: str) -> List[str]:
"""Search for templates matching query."""
query = query.lower()
results = []
for template_name in self.get_available_templates():
if query in template_name.lower():
results.append(template_name)
return results
def merge_templates(self, template_names: List[str]) -> str:
"""Merge multiple templates into one."""
lines_seen: Set[str] = set()
merged_lines = []
for template_name in template_names:
content = self.get_template_content(template_name)
if content:
for line in content.splitlines():
line = line.strip()
if line and not line.startswith("#"):
normalized = line.rstrip("/")
if normalized not in lines_seen:
lines_seen.add(normalized)
merged_lines.append(line)
return "\n".join(sorted(set(merged_lines)))
template_loader = TemplateLoader()