Initial upload: Project Scaffold CLI with multi-language templates and CI/CD
This commit is contained in:
203
project_scaffold_cli/gitignore.py
Normal file
203
project_scaffold_cli/gitignore.py
Normal file
@@ -0,0 +1,203 @@
|
||||
"""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)
|
||||
Reference in New Issue
Block a user