204 lines
3.8 KiB
Python
204 lines
3.8 KiB
Python
"""Gitignore generator for Project Scaffold CLI."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Dict, Optional, Set
|
|
|
|
|
|
class GitignoreGenerator:
|
|
"""Generate language-specific .gitignore files."""
|
|
|
|
SUPPORTED_LANGUAGES = ["python", "nodejs", "go", "rust"]
|
|
|
|
GITIGNORE_TEMPLATES = {
|
|
"python": """__pycache__/
|
|
*.py[cod]
|
|
*$py.class
|
|
*.so
|
|
.Python
|
|
build/
|
|
develop-eggs/
|
|
dist/
|
|
downloads/
|
|
eggs/
|
|
.eggs/
|
|
lib/
|
|
lib64/
|
|
parts/
|
|
sdist/
|
|
var/
|
|
wheels/
|
|
*.egg-info/
|
|
.installed.cfg
|
|
*.egg
|
|
venv/
|
|
ENV/
|
|
env/
|
|
.venv/
|
|
.pytest_cache/
|
|
.coverage
|
|
.coverage.*
|
|
htmlcov/
|
|
.tox/
|
|
.nox/
|
|
*.manifest
|
|
*.spec
|
|
""",
|
|
"nodejs": """node_modules/
|
|
npm-debug.log*
|
|
yarn-debug.log*
|
|
yarn-error.log*
|
|
*.log
|
|
.DS_Store
|
|
dist/
|
|
build/
|
|
.nyc_output/
|
|
coverage/
|
|
*.suo
|
|
*.ntvs*
|
|
*.njsproj
|
|
*.sln
|
|
*.sw?
|
|
""",
|
|
"go": """# Binaries
|
|
*.exe
|
|
*.exe~
|
|
*.dll
|
|
*.so
|
|
*.dylib
|
|
|
|
# Test binary
|
|
*.test
|
|
|
|
# Output of go coverage
|
|
*.out
|
|
|
|
# Go workspace
|
|
go.work
|
|
|
|
# Vendor directory
|
|
vendor/
|
|
|
|
# IDE
|
|
.idea/
|
|
.vscode/
|
|
*.swp
|
|
*.swo
|
|
""",
|
|
"rust": """# Cargo
|
|
target/
|
|
Cargo.lock
|
|
|
|
# IDE
|
|
.idea/
|
|
.vscode/
|
|
*.swp
|
|
*.swo
|
|
|
|
# Backup files
|
|
*~
|
|
#*#
|
|
#*
|
|
.backup
|
|
|
|
# Build artifacts
|
|
*.rlib
|
|
*.dylib
|
|
*.dll
|
|
|
|
# IDE
|
|
.vscode/
|
|
.idea/
|
|
""",
|
|
}
|
|
|
|
ADDITIONAL_PATTERNS = {
|
|
"python": """*.pyc
|
|
*.pyo
|
|
.env
|
|
.env.local
|
|
.vscode/
|
|
.idea/
|
|
""",
|
|
"nodejs": """package-lock.json
|
|
yarn.lock
|
|
.env
|
|
.env.local
|
|
""",
|
|
"go": """*.out
|
|
*.test
|
|
coverage.txt
|
|
""",
|
|
"rust": """**/*.rs.bk
|
|
Cargo.lock
|
|
""",
|
|
}
|
|
|
|
def __init__(self):
|
|
self.templates_dir = self._get_templates_dir()
|
|
|
|
def _get_templates_dir(self) -> Path:
|
|
"""Get the directory containing gitignore templates."""
|
|
return Path(__file__).parent / "templates" / "gitignore"
|
|
|
|
def generate(
|
|
self, language: str, output_path: Path, extra_patterns: Optional[Set[str]] = None
|
|
) -> None:
|
|
"""Generate a .gitignore file for the specified language."""
|
|
if language not in self.SUPPORTED_LANGUAGES:
|
|
raise ValueError(
|
|
f"Unsupported language: {language}. "
|
|
f"Supported: {', '.join(self.SUPPORTED_LANGUAGES)}"
|
|
)
|
|
|
|
content = self.GITIGNORE_TEMPLATES.get(language, "")
|
|
|
|
extra = self.ADDITIONAL_PATTERNS.get(language, "")
|
|
if extra:
|
|
content += extra
|
|
|
|
if extra_patterns:
|
|
content += "\n".join(sorted(extra_patterns)) + "\n"
|
|
|
|
content += "\n# Editor directories\n.idea/\n.vscode/\n*.swp\n*.swo\n*~\n"
|
|
|
|
output_path.write_text(content)
|
|
|
|
def generate_from_template(self, template_name: str, output_path: Path) -> None:
|
|
"""Generate .gitignore from a template file."""
|
|
template_path = self.templates_dir / template_name
|
|
if not template_path.exists():
|
|
raise FileNotFoundError(
|
|
f"Gitignore template not found: {template_path}"
|
|
)
|
|
|
|
content = template_path.read_text()
|
|
output_path.write_text(content)
|
|
|
|
def list_available_templates(self) -> list[str]:
|
|
"""List available gitignore templates."""
|
|
if not self.templates_dir.exists():
|
|
return []
|
|
|
|
return [
|
|
f.stem
|
|
for f in self.templates_dir.iterdir()
|
|
if f.is_file() and f.suffix in (".gitignore", ".txt", "")
|
|
]
|
|
|
|
def get_template_content(self, language: str) -> str:
|
|
"""Get the raw template content for a language."""
|
|
return self.GITIGNORE_TEMPLATES.get(language, "")
|
|
|
|
def append_patterns(self, gitignore_path: Path, patterns: Set[str]) -> None:
|
|
"""Append additional patterns to an existing .gitignore file."""
|
|
if gitignore_path.exists():
|
|
content = gitignore_path.read_text()
|
|
if not content.endswith("\n"):
|
|
content += "\n"
|
|
else:
|
|
content = ""
|
|
|
|
content += "\n" + "\n".join(sorted(patterns)) + "\n"
|
|
gitignore_path.write_text(content)
|