Initial upload: gitignore-generator-cli v1.0.0 with CI/CD workflow
This commit is contained in:
179
gitignore_generator/generator.py
Normal file
179
gitignore_generator/generator.py
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
"""Generator for combining gitignore patterns."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from .api import get_patterns_batch
|
||||||
|
from .cache import CacheManager
|
||||||
|
|
||||||
|
|
||||||
|
class GitignoreGenerator:
|
||||||
|
"""Generates combined .gitignore files from multiple tech stacks."""
|
||||||
|
|
||||||
|
def __init__(self, custom_patterns_file: Optional[str] = None):
|
||||||
|
"""Initialize generator.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
custom_patterns_file: Path to custom patterns file
|
||||||
|
"""
|
||||||
|
self.cache = CacheManager()
|
||||||
|
self.custom_patterns_file = custom_patterns_file
|
||||||
|
|
||||||
|
def load_custom_patterns(self) -> list[str]:
|
||||||
|
"""Load custom patterns from file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of custom patterns
|
||||||
|
"""
|
||||||
|
if self.custom_patterns_file:
|
||||||
|
path = Path(self.custom_patterns_file)
|
||||||
|
if path.exists():
|
||||||
|
return path.read_text().splitlines()
|
||||||
|
return []
|
||||||
|
|
||||||
|
def combine_patterns(
|
||||||
|
self,
|
||||||
|
techs: list[str],
|
||||||
|
add_patterns: Optional[list[str]] = None,
|
||||||
|
force_refresh: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""Combine gitignore patterns from multiple technologies.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
techs: List of technology names
|
||||||
|
add_patterns: Additional patterns to add
|
||||||
|
force_refresh: Force refresh from API
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Combined gitignore content
|
||||||
|
"""
|
||||||
|
patterns = get_patterns_batch(techs, force_refresh)
|
||||||
|
|
||||||
|
output_lines = []
|
||||||
|
seen_patterns = set()
|
||||||
|
|
||||||
|
for tech in techs:
|
||||||
|
pattern_content = patterns.get(tech, '').strip()
|
||||||
|
if pattern_content:
|
||||||
|
output_lines.append(f"# --- {tech.upper()} ---")
|
||||||
|
for line in pattern_content.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('#'):
|
||||||
|
if line not in seen_patterns:
|
||||||
|
seen_patterns.add(line)
|
||||||
|
output_lines.append(line)
|
||||||
|
output_lines.append("")
|
||||||
|
|
||||||
|
custom_patterns = self.load_custom_patterns()
|
||||||
|
if add_patterns:
|
||||||
|
custom_patterns.extend(add_patterns)
|
||||||
|
|
||||||
|
if custom_patterns:
|
||||||
|
output_lines.append("# --- CUSTOM ---")
|
||||||
|
for pattern in custom_patterns:
|
||||||
|
pattern = pattern.strip()
|
||||||
|
if pattern and not pattern.startswith('#'):
|
||||||
|
if pattern not in seen_patterns:
|
||||||
|
seen_patterns.add(pattern)
|
||||||
|
output_lines.append(pattern)
|
||||||
|
output_lines.append("")
|
||||||
|
|
||||||
|
return '\n'.join(output_lines).strip()
|
||||||
|
|
||||||
|
def generate_file(
|
||||||
|
self,
|
||||||
|
techs: list[str],
|
||||||
|
output_path: Optional[str] = None,
|
||||||
|
preview: bool = False,
|
||||||
|
add_patterns: Optional[list[str]] = None,
|
||||||
|
force_refresh: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""Generate gitignore file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
techs: List of technology names
|
||||||
|
output_path: Path to write file (None for stdout)
|
||||||
|
preview: If True, return content without writing
|
||||||
|
add_patterns: Additional patterns to add
|
||||||
|
force_refresh: Force refresh from API
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Generated gitignore content
|
||||||
|
"""
|
||||||
|
content = self.combine_patterns(techs, add_patterns, force_refresh)
|
||||||
|
|
||||||
|
if preview or output_path is None:
|
||||||
|
return content
|
||||||
|
|
||||||
|
output_file = Path(output_path)
|
||||||
|
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
output_file.write_text(content + '\n')
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def merge_with_existing(
|
||||||
|
self,
|
||||||
|
existing_path: str,
|
||||||
|
techs: list[str],
|
||||||
|
add_patterns: Optional[list[str]] = None,
|
||||||
|
force_refresh: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""Merge generated patterns with existing .gitignore.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
existing_path: Path to existing .gitignore
|
||||||
|
techs: List of technology names
|
||||||
|
add_patterns: Additional patterns to add
|
||||||
|
force_refresh: Force refresh from API
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Merged gitignore content
|
||||||
|
"""
|
||||||
|
existing_content = ""
|
||||||
|
existing_file = Path(existing_path)
|
||||||
|
if existing_file.exists():
|
||||||
|
existing_content = existing_file.read_text()
|
||||||
|
|
||||||
|
existing_lines = set()
|
||||||
|
for line in existing_content.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('#'):
|
||||||
|
existing_lines.add(line)
|
||||||
|
|
||||||
|
new_content = self.combine_patterns(techs, add_patterns, force_refresh)
|
||||||
|
|
||||||
|
output_lines = []
|
||||||
|
if existing_content.strip():
|
||||||
|
output_lines.append("# --- EXISTING ---")
|
||||||
|
output_lines.append(existing_content.strip())
|
||||||
|
output_lines.append("")
|
||||||
|
|
||||||
|
output_lines.append("# --- GENERATED ---")
|
||||||
|
output_lines.append(new_content)
|
||||||
|
|
||||||
|
return '\n'.join(output_lines).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_gitignore(
|
||||||
|
techs: list[str],
|
||||||
|
output_path: Optional[str] = None,
|
||||||
|
preview: bool = False,
|
||||||
|
add_patterns: Optional[list[str]] = None,
|
||||||
|
force_refresh: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""Convenience function to generate gitignore.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
techs: List of technology names
|
||||||
|
output_path: Path to write file (None for stdout)
|
||||||
|
preview: If True, return content without writing
|
||||||
|
add_patterns: Additional patterns to add
|
||||||
|
force_refresh: Force refresh from API
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Generated gitignore content
|
||||||
|
"""
|
||||||
|
generator = GitignoreGenerator()
|
||||||
|
return generator.generate_file(
|
||||||
|
techs, output_path, preview, add_patterns, force_refresh
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user