128 lines
4.5 KiB
Python
Executable File
128 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Project scaffolding tool - creates project structures for different types.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
|
|
WORKSPACE = Path("/home/wdjones/.openclaw/workspace")
|
|
PROJECTS = WORKSPACE / "projects"
|
|
|
|
TEMPLATES = {
|
|
'python': {
|
|
'files': {
|
|
'README.md': '# {name}\n\n{description}\n\n## Setup\n\n```bash\npython -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\n```\n\n## Usage\n\n```bash\npython main.py\n```\n',
|
|
'main.py': '#!/usr/bin/env python3\n"""\n{name} - {description}\n"""\n\ndef main():\n print("Hello from {name}")\n\nif __name__ == "__main__":\n main()\n',
|
|
'requirements.txt': '# Add dependencies here\n',
|
|
'.gitignore': 'venv/\n__pycache__/\n*.pyc\n.env\n*.egg-info/\ndist/\nbuild/\n',
|
|
},
|
|
'dirs': ['src', 'tests'],
|
|
},
|
|
'node': {
|
|
'files': {
|
|
'README.md': '# {name}\n\n{description}\n\n## Setup\n\n```bash\npnpm install\n```\n\n## Usage\n\n```bash\npnpm start\n```\n',
|
|
'package.json': '{{\n "name": "{name}",\n "version": "0.1.0",\n "description": "{description}",\n "main": "index.js",\n "scripts": {{\n "start": "node index.js"\n }}\n}}\n',
|
|
'index.js': '// {name}\n// {description}\n\nconsole.log("Hello from {name}");\n',
|
|
'.gitignore': 'node_modules/\n.env\ndist/\n',
|
|
},
|
|
'dirs': ['src', 'lib'],
|
|
},
|
|
'script': {
|
|
'files': {
|
|
'README.md': '# {name}\n\n{description}\n\n## Usage\n\n```bash\n./script.sh\n```\n',
|
|
'script.sh': '#!/bin/bash\n# {name} - {description}\n\nset -euo pipefail\n\necho "Running {name}"\n',
|
|
},
|
|
'dirs': [],
|
|
},
|
|
'docs': {
|
|
'files': {
|
|
'README.md': '# {name}\n\n{description}\n\n## Contents\n\n- [Overview](overview.md)\n',
|
|
'overview.md': '# Overview\n\nAdd documentation here.\n',
|
|
},
|
|
'dirs': ['images', 'guides'],
|
|
},
|
|
'experiment': {
|
|
'files': {
|
|
'README.md': '# {name}\n\n**Experiment started:** {date}\n\n## Hypothesis\n\n{description}\n\n## Method\n\n\n## Results\n\n\n## Conclusion\n\n',
|
|
'notes.md': '# Experiment Notes\n\n## {date}\n\n- Started experiment\n',
|
|
},
|
|
'dirs': ['data', 'output'],
|
|
},
|
|
}
|
|
|
|
def scaffold(name: str, template: str = 'python', description: str = ''):
|
|
"""Create a new project from template."""
|
|
if template not in TEMPLATES:
|
|
print(f"Unknown template: {template}")
|
|
print(f"Available: {', '.join(TEMPLATES.keys())}")
|
|
return False
|
|
|
|
project_dir = PROJECTS / name
|
|
if project_dir.exists():
|
|
print(f"Project already exists: {name}")
|
|
return False
|
|
|
|
tmpl = TEMPLATES[template]
|
|
date = datetime.now().strftime("%Y-%m-%d")
|
|
|
|
# Create directories
|
|
project_dir.mkdir(parents=True)
|
|
for d in tmpl['dirs']:
|
|
(project_dir / d).mkdir()
|
|
|
|
# Create files
|
|
for fname, content in tmpl['files'].items():
|
|
fpath = project_dir / fname
|
|
formatted = content.format(name=name, description=description or 'No description', date=date)
|
|
fpath.write_text(formatted)
|
|
|
|
# Make scripts executable
|
|
for f in project_dir.glob('*.sh'):
|
|
os.chmod(f, 0o755)
|
|
for f in project_dir.glob('*.py'):
|
|
if f.read_text().startswith('#!/'):
|
|
os.chmod(f, 0o755)
|
|
|
|
print(f"✓ Created {template} project: {name}")
|
|
print(f" Location: {project_dir}")
|
|
print(f" Files: {len(tmpl['files'])}")
|
|
if tmpl['dirs']:
|
|
print(f" Dirs: {', '.join(tmpl['dirs'])}")
|
|
|
|
return True
|
|
|
|
def list_templates():
|
|
"""List available templates."""
|
|
print("Available templates:\n")
|
|
for name, tmpl in TEMPLATES.items():
|
|
files = ', '.join(tmpl['files'].keys())
|
|
print(f" {name}:")
|
|
print(f" Files: {files}")
|
|
if tmpl['dirs']:
|
|
print(f" Dirs: {', '.join(tmpl['dirs'])}")
|
|
print()
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("Usage:")
|
|
print(" scaffold.py <name> [template] [description]")
|
|
print(" scaffold.py --list")
|
|
print("\nTemplates: python, node, script, docs, experiment")
|
|
sys.exit(1)
|
|
|
|
if sys.argv[1] == '--list':
|
|
list_templates()
|
|
return
|
|
|
|
name = sys.argv[1]
|
|
template = sys.argv[2] if len(sys.argv) > 2 else 'python'
|
|
description = ' '.join(sys.argv[3:]) if len(sys.argv) > 3 else ''
|
|
|
|
scaffold(name, template, description)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|