wrd 0.1.2__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wrd/__init__.py +39 -0
- wrd/__main__.py +999 -0
- wrd/__version__.py +7 -0
- wrd/cli.py +312 -0
- wrd/py.typed +0 -0
- wrd/template_manager.py +163 -0
- wrd/templates/__init__.py +4 -0
- wrd/templates/__pycache__/__init__.cpython-312.pyc +0 -0
- wrd/templates/python/README.md.j2 +33 -0
- wrd/templates/python/gitignore.j2 +51 -0
- wrd/templates/python/project.yml +39 -0
- wrd/templates/python/pyproject.toml.j2 +35 -0
- wrd-0.1.2.dist-info/METADATA +751 -0
- wrd-0.1.2.dist-info/RECORD +18 -0
- wrd-0.1.2.dist-info/WHEEL +6 -0
- wrd-0.1.2.dist-info/entry_points.txt +2 -0
- wrd-0.1.2.dist-info/licenses/LICENSE +201 -0
- wrd-0.1.2.dist-info/top_level.txt +1 -0
wrd/__version__.py
ADDED
wrd/cli.py
ADDED
@@ -0,0 +1,312 @@
|
|
1
|
+
"""WRD Command Line Interface."""
|
2
|
+
|
3
|
+
import os
|
4
|
+
import sys
|
5
|
+
import yaml
|
6
|
+
from pathlib import Path
|
7
|
+
from typing import Dict, Any, Optional, List
|
8
|
+
from rich.console import Console
|
9
|
+
from rich.prompt import Prompt, Confirm, IntPrompt
|
10
|
+
from rich.panel import Panel
|
11
|
+
from rich.table import Table
|
12
|
+
from rich.progress import track
|
13
|
+
import subprocess
|
14
|
+
import shutil
|
15
|
+
|
16
|
+
console = Console()
|
17
|
+
|
18
|
+
class WRDConfig:
|
19
|
+
"""Manage WRD configuration."""
|
20
|
+
|
21
|
+
def __init__(self):
|
22
|
+
self.config_dir = Path.home() / ".wrd"
|
23
|
+
self.config_file = self.config_dir / "config.yaml"
|
24
|
+
self.templates_dir = self.config_dir / "templates"
|
25
|
+
self.ensure_directories()
|
26
|
+
self.config = self.load_config()
|
27
|
+
|
28
|
+
def ensure_directories(self):
|
29
|
+
"""Ensure configuration directories exist."""
|
30
|
+
self.config_dir.mkdir(exist_ok=True)
|
31
|
+
self.templates_dir.mkdir(exist_ok=True)
|
32
|
+
|
33
|
+
def load_config(self) -> Dict[str, Any]:
|
34
|
+
"""Load configuration from YAML file."""
|
35
|
+
if not self.config_file.exists():
|
36
|
+
return {
|
37
|
+
"projects_dir": str(Path.home() / "projects"),
|
38
|
+
"editor": os.environ.get("EDITOR", "code"),
|
39
|
+
"default_language": "python",
|
40
|
+
"templates": {}
|
41
|
+
}
|
42
|
+
|
43
|
+
with open(self.config_file, 'r') as f:
|
44
|
+
return yaml.safe_load(f) or {}
|
45
|
+
|
46
|
+
def save_config(self):
|
47
|
+
"""Save configuration to YAML file."""
|
48
|
+
with open(self.config_file, 'w') as f:
|
49
|
+
yaml.dump(self.config, f, default_flow_style=False)
|
50
|
+
|
51
|
+
class WRDShell:
|
52
|
+
"""Interactive WRD shell."""
|
53
|
+
|
54
|
+
def __init__(self):
|
55
|
+
self.config = WRDConfig()
|
56
|
+
self.current_project = None
|
57
|
+
self.console = Console()
|
58
|
+
|
59
|
+
def print_banner(self):
|
60
|
+
"""Print WRD banner."""
|
61
|
+
banner = """
|
62
|
+
██╗ ██╗██████╗ ██████╗
|
63
|
+
██║ ██║██╔══██╗██╔══██╗
|
64
|
+
██║ █╗ ██║██████╔╝██║ ██║
|
65
|
+
██║███╗██║██╔══██╗██║ ██║
|
66
|
+
╚███╔███╔╝██║ ██║██████╔╝
|
67
|
+
╚══╝╚══╝ ╚═╝ ╚═╝╚═════╝
|
68
|
+
WRD - WRonai Development Tool
|
69
|
+
"""
|
70
|
+
self.console.print(Panel.fit(banner, style="bold blue"))
|
71
|
+
|
72
|
+
def get_menu_choice(self, title: str, options: List[Dict[str, str]], timeout: int = 10) -> str:
|
73
|
+
"""Display a menu and get user choice."""
|
74
|
+
table = Table(title=title, show_header=False, show_lines=True)
|
75
|
+
table.add_column("Option", style="cyan")
|
76
|
+
table.add_column("Description")
|
77
|
+
|
78
|
+
for i, option in enumerate(options, 1):
|
79
|
+
table.add_row(str(i), option['description'])
|
80
|
+
|
81
|
+
self.console.print(table)
|
82
|
+
|
83
|
+
try:
|
84
|
+
choice = IntPrompt.ask(
|
85
|
+
"\nEnter your choice",
|
86
|
+
choices=[str(i) for i in range(1, len(options) + 1)],
|
87
|
+
timeout=timeout
|
88
|
+
)
|
89
|
+
return options[int(choice) - 1]['command']
|
90
|
+
except Exception:
|
91
|
+
self.console.print("\n[bold red]Timeout reached. Using default option.[/]")
|
92
|
+
return options[0]['command']
|
93
|
+
|
94
|
+
def init_project(self, project_path: Optional[str] = None):
|
95
|
+
"""Initialize a new project."""
|
96
|
+
if project_path is None:
|
97
|
+
project_path = Prompt.ask("Enter project path", default=str(Path.cwd()))
|
98
|
+
|
99
|
+
project_path = Path(project_path).absolute()
|
100
|
+
|
101
|
+
if project_path.exists() and any(project_path.iterdir()):
|
102
|
+
self.console.print(f"[yellow]Directory {project_path} is not empty.[/]")
|
103
|
+
if not Confirm.ask("Do you want to initialize a project here anyway?"):
|
104
|
+
return
|
105
|
+
|
106
|
+
# Get project details
|
107
|
+
project_name = project_path.name
|
108
|
+
language = Prompt.ask("Project language", default=self.config.config.get('default_language', 'python'))
|
109
|
+
description = Prompt.ask("Project description", default="")
|
110
|
+
|
111
|
+
# Create project structure
|
112
|
+
project_path.mkdir(parents=True, exist_ok=True)
|
113
|
+
|
114
|
+
# Initialize project based on language
|
115
|
+
if language == 'python':
|
116
|
+
self._init_python_project(project_path, project_name, description)
|
117
|
+
# Add more language support here
|
118
|
+
|
119
|
+
self.console.print(f"[green]✓ Project {project_name} initialized successfully![/]")
|
120
|
+
|
121
|
+
def _init_python_project(self, project_path: Path, name: str, description: str):
|
122
|
+
"""Initialize a Python project."""
|
123
|
+
# Create basic Python project structure
|
124
|
+
(project_path / 'src' / name.replace('-', '_')).mkdir(parents=True, exist_ok=True)
|
125
|
+
(project_path / 'tests').mkdir(exist_ok=True)
|
126
|
+
|
127
|
+
# Create pyproject.toml
|
128
|
+
pyproject = f"""[build-system]
|
129
|
+
requires = ["setuptools>=42.0"]
|
130
|
+
build-backend = "setuptools.build_meta"
|
131
|
+
|
132
|
+
[project]
|
133
|
+
name = "{name}"
|
134
|
+
version = "0.1.0"
|
135
|
+
description = "{description}"
|
136
|
+
authors = [
|
137
|
+
{{ name = "Your Name", email = "your.email@example.com" }}
|
138
|
+
]
|
139
|
+
readme = "README.md"
|
140
|
+
requires-python = ">=3.8"
|
141
|
+
|
142
|
+
[project.optional-dependencies]
|
143
|
+
dev = [
|
144
|
+
"pytest>=6.0",
|
145
|
+
"black>=21.12b0",
|
146
|
+
"isort>=5.10.1",
|
147
|
+
"mypy>=0.910",
|
148
|
+
"pytest-cov>=2.0"
|
149
|
+
]
|
150
|
+
"""
|
151
|
+
(project_path / 'pyproject.toml').write_text(pyproject)
|
152
|
+
|
153
|
+
# Create README.md
|
154
|
+
readme = f"""# {name}
|
155
|
+
|
156
|
+
{description}
|
157
|
+
|
158
|
+
## Installation
|
159
|
+
|
160
|
+
```bash
|
161
|
+
pip install -e .
|
162
|
+
```
|
163
|
+
|
164
|
+
## Development
|
165
|
+
|
166
|
+
Install development dependencies:
|
167
|
+
|
168
|
+
```bash
|
169
|
+
pip install -e ".[dev]"
|
170
|
+
```
|
171
|
+
|
172
|
+
Run tests:
|
173
|
+
|
174
|
+
```bash
|
175
|
+
pytest
|
176
|
+
```
|
177
|
+
"""
|
178
|
+
(project_path / 'README.md').write_text(readme)
|
179
|
+
|
180
|
+
# Create .gitignore
|
181
|
+
gitignore = """# Python
|
182
|
+
__pycache__/
|
183
|
+
*.py[cod]
|
184
|
+
*$py.class
|
185
|
+
*.so
|
186
|
+
.Python
|
187
|
+
build/
|
188
|
+
develop-eggs/
|
189
|
+
dist/
|
190
|
+
downloads/
|
191
|
+
eggs/
|
192
|
+
.eggs/
|
193
|
+
lib/
|
194
|
+
lib64/
|
195
|
+
parts/
|
196
|
+
sdist/
|
197
|
+
var/
|
198
|
+
wheels/
|
199
|
+
*.egg-info/
|
200
|
+
.installed.cfg
|
201
|
+
*.egg
|
202
|
+
|
203
|
+
# Virtual Environment
|
204
|
+
venv/
|
205
|
+
env/
|
206
|
+
|
207
|
+
# IDE
|
208
|
+
.idea/
|
209
|
+
.vscode/
|
210
|
+
*.swp
|
211
|
+
*.swo
|
212
|
+
|
213
|
+
# Testing
|
214
|
+
.coverage
|
215
|
+
htmlcov/
|
216
|
+
.pytest_cache/
|
217
|
+
"""
|
218
|
+
(project_path / '.gitignore').write_text(gitignore)
|
219
|
+
|
220
|
+
# Initialize git repository
|
221
|
+
try:
|
222
|
+
subprocess.run(['git', 'init'], cwd=project_path, check=True)
|
223
|
+
subprocess.run(['git', 'add', '.'], cwd=project_path, check=True)
|
224
|
+
subprocess.run(['git', 'commit', '-m', 'Initial commit'], cwd=project_path, check=True)
|
225
|
+
except Exception as e:
|
226
|
+
self.console.print(f"[yellow]Warning: Failed to initialize git repository: {e}[/]")
|
227
|
+
|
228
|
+
def shell(self):
|
229
|
+
"""Start interactive shell."""
|
230
|
+
self.print_banner()
|
231
|
+
|
232
|
+
while True:
|
233
|
+
try:
|
234
|
+
options = [
|
235
|
+
{'command': 'init', 'description': 'Initialize a new project'},
|
236
|
+
{'command': 'list', 'description': 'List all projects'},
|
237
|
+
{'command': 'config', 'description': 'Configure WRD'},
|
238
|
+
{'command': 'exit', 'description': 'Exit WRD shell'}
|
239
|
+
]
|
240
|
+
|
241
|
+
choice = self.get_menu_choice("WRD - Main Menu", options, timeout=60)
|
242
|
+
|
243
|
+
if choice == 'init':
|
244
|
+
self.init_project()
|
245
|
+
elif choice == 'list':
|
246
|
+
self.list_projects()
|
247
|
+
elif choice == 'config':
|
248
|
+
self.configure()
|
249
|
+
elif choice == 'exit':
|
250
|
+
self.console.print("[green]Goodbye![/]")
|
251
|
+
break
|
252
|
+
|
253
|
+
except KeyboardInterrupt:
|
254
|
+
self.console.print("\n[red]Operation cancelled.[/]")
|
255
|
+
except Exception as e:
|
256
|
+
self.console.print(f"[red]Error: {e}[/]")
|
257
|
+
|
258
|
+
def list_projects(self):
|
259
|
+
"""List all projects in the projects directory."""
|
260
|
+
projects_dir = Path(self.config.config.get('projects_dir', Path.home() / 'projects'))
|
261
|
+
|
262
|
+
if not projects_dir.exists():
|
263
|
+
self.console.print("[yellow]No projects directory found.[/]")
|
264
|
+
return
|
265
|
+
|
266
|
+
table = Table(title="Projects")
|
267
|
+
table.add_column("Name", style="cyan")
|
268
|
+
table.add_column("Path")
|
269
|
+
table.add_column("Modified")
|
270
|
+
|
271
|
+
for project_dir in projects_dir.iterdir():
|
272
|
+
if project_dir.is_dir():
|
273
|
+
modified = datetime.fromtimestamp(project_dir.stat().st_mtime).strftime('%Y-%m-%d %H:%M')
|
274
|
+
table.add_row(project_dir.name, str(project_dir), modified)
|
275
|
+
|
276
|
+
self.console.print(table)
|
277
|
+
|
278
|
+
def configure(self):
|
279
|
+
"""Configure WRD settings."""
|
280
|
+
self.console.print("[bold]Current Configuration:[/]")
|
281
|
+
for key, value in self.config.config.items():
|
282
|
+
self.console.print(f" [cyan]{key}:[/] {value}")
|
283
|
+
|
284
|
+
if Confirm.ask("\nDo you want to change any settings?"):
|
285
|
+
setting = Prompt.ask("Enter setting name")
|
286
|
+
if setting in self.config.config:
|
287
|
+
if isinstance(self.config.config[setting], bool):
|
288
|
+
new_value = Confirm.ask(f"New value for {setting}")
|
289
|
+
else:
|
290
|
+
new_value = Prompt.ask(f"New value for {setting}")
|
291
|
+
self.config.config[setting] = new_value
|
292
|
+
self.config.save_config()
|
293
|
+
self.console.print("[green]✓ Configuration updated.[/]")
|
294
|
+
else:
|
295
|
+
self.console.print("[red]Invalid setting name.[/]")
|
296
|
+
|
297
|
+
def main():
|
298
|
+
"""Entry point for the WRD CLI."""
|
299
|
+
if len(sys.argv) > 1 and sys.argv[1] == 'shell':
|
300
|
+
WRDShell().shell()
|
301
|
+
elif len(sys.argv) > 1 and sys.argv[1] == 'init':
|
302
|
+
WRDShell().init_project(sys.argv[2] if len(sys.argv) > 2 else None)
|
303
|
+
else:
|
304
|
+
console = Console()
|
305
|
+
console.print("WRD - WRonai Development Tool")
|
306
|
+
console.print("\nUsage:")
|
307
|
+
console.print(" wrd shell - Start interactive shell")
|
308
|
+
console.print(" wrd init [path] - Initialize a new project")
|
309
|
+
console.print(" wrd --help - Show this help")
|
310
|
+
|
311
|
+
if __name__ == "__main__":
|
312
|
+
main()
|
wrd/py.typed
ADDED
File without changes
|
wrd/template_manager.py
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
"""Template manager for WRD."""
|
2
|
+
|
3
|
+
import os
|
4
|
+
import shutil
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Dict, Any, Optional, List
|
7
|
+
import yaml
|
8
|
+
import jinja2
|
9
|
+
import importlib.resources as pkg_resources
|
10
|
+
from . import templates
|
11
|
+
|
12
|
+
class TemplateManager:
|
13
|
+
"""Manages project templates for different languages and project types."""
|
14
|
+
|
15
|
+
def __init__(self):
|
16
|
+
self.templates_dir = Path(pkg_resources.files(templates))
|
17
|
+
self.available_templates = self._discover_templates()
|
18
|
+
|
19
|
+
def _discover_templates(self) -> Dict[str, Dict[str, Any]]:
|
20
|
+
"""Discover all available templates in the templates directory."""
|
21
|
+
templates = {}
|
22
|
+
|
23
|
+
if not self.templates_dir.exists():
|
24
|
+
return {}
|
25
|
+
|
26
|
+
for template_dir in self.templates_dir.iterdir():
|
27
|
+
if template_dir.is_dir() and (template_dir / 'project.yml').exists():
|
28
|
+
try:
|
29
|
+
with open(template_dir / 'project.yml', 'r') as f:
|
30
|
+
config = yaml.safe_load(f)
|
31
|
+
templates[config['name']] = {
|
32
|
+
'config': config,
|
33
|
+
'path': template_dir
|
34
|
+
}
|
35
|
+
except (yaml.YAMLError, KeyError) as e:
|
36
|
+
print(f"Error loading template {template_dir.name}: {e}")
|
37
|
+
|
38
|
+
return templates
|
39
|
+
|
40
|
+
def get_template(self, name: str) -> Optional[Dict[str, Any]]:
|
41
|
+
"""Get a template by name."""
|
42
|
+
return self.available_templates.get(name)
|
43
|
+
|
44
|
+
def list_templates(self) -> List[str]:
|
45
|
+
"""List all available template names."""
|
46
|
+
return list(self.available_templates.keys())
|
47
|
+
|
48
|
+
def create_project(
|
49
|
+
self,
|
50
|
+
template_name: str,
|
51
|
+
project_path: Path,
|
52
|
+
context: Dict[str, Any],
|
53
|
+
overwrite: bool = False
|
54
|
+
) -> bool:
|
55
|
+
"""Create a new project from a template.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
template_name: Name of the template to use
|
59
|
+
project_path: Path where the project should be created
|
60
|
+
context: Dictionary with template variables
|
61
|
+
overwrite: Whether to overwrite existing files
|
62
|
+
|
63
|
+
Returns:
|
64
|
+
bool: True if project was created successfully, False otherwise
|
65
|
+
"""
|
66
|
+
template = self.get_template(template_name)
|
67
|
+
if not template:
|
68
|
+
print(f"Error: Template '{template_name}' not found")
|
69
|
+
return False
|
70
|
+
|
71
|
+
project_path = project_path.absolute()
|
72
|
+
|
73
|
+
# Create project directory if it doesn't exist
|
74
|
+
project_path.mkdir(parents=True, exist_ok=True)
|
75
|
+
|
76
|
+
# Check if directory is empty or overwrite is allowed
|
77
|
+
if any(project_path.iterdir()) and not overwrite:
|
78
|
+
print(f"Error: Directory {project_path} is not empty. Use --overwrite to ignore.")
|
79
|
+
return False
|
80
|
+
|
81
|
+
# Process template files
|
82
|
+
config = template['config']
|
83
|
+
template_dir = template['path']
|
84
|
+
|
85
|
+
# Create directories
|
86
|
+
for dir_path in config.get('directories', []):
|
87
|
+
dir_path = project_path / self._render_template(dir_path, context)
|
88
|
+
dir_path.mkdir(parents=True, exist_ok=True)
|
89
|
+
|
90
|
+
# Create files
|
91
|
+
for file_spec in config.get('files', []):
|
92
|
+
if isinstance(file_spec, dict):
|
93
|
+
file_path = file_spec['path']
|
94
|
+
content = file_spec.get('content')
|
95
|
+
template_file = file_spec.get('template')
|
96
|
+
else:
|
97
|
+
file_path = file_spec
|
98
|
+
content = None
|
99
|
+
template_file = None
|
100
|
+
|
101
|
+
# Render the file path
|
102
|
+
file_path = self._render_template(file_path, context)
|
103
|
+
dest_path = project_path / file_path
|
104
|
+
|
105
|
+
# Create parent directories if they don't exist
|
106
|
+
dest_path.parent.mkdir(parents=True, exist_ok=True)
|
107
|
+
|
108
|
+
# Write file content
|
109
|
+
if content is not None:
|
110
|
+
# Use direct content
|
111
|
+
dest_path.write_text(self._render_template(content, context))
|
112
|
+
elif template_file is not None:
|
113
|
+
# Use template file
|
114
|
+
template_path = template_dir / template_file
|
115
|
+
if template_path.exists():
|
116
|
+
template_content = template_path.read_text()
|
117
|
+
rendered = self._render_template(template_content, context)
|
118
|
+
dest_path.write_text(rendered)
|
119
|
+
else:
|
120
|
+
# Create empty file
|
121
|
+
dest_path.touch()
|
122
|
+
|
123
|
+
# Run post-create commands
|
124
|
+
for cmd in config.get('post_create_commands', []):
|
125
|
+
cmd = self._render_template(cmd, context)
|
126
|
+
os.system(f"cd {project_path} && {cmd}")
|
127
|
+
|
128
|
+
return True
|
129
|
+
|
130
|
+
def _render_template(self, template_str: str, context: Dict[str, Any]) -> str:
|
131
|
+
"""Render a template string with the given context."""
|
132
|
+
return jinja2.Template(template_str).render(**context)
|
133
|
+
|
134
|
+
def get_template_variables(self, template_name: str) -> Dict[str, Any]:
|
135
|
+
"""Get the required variables for a template."""
|
136
|
+
template = self.get_template(template_name)
|
137
|
+
if not template:
|
138
|
+
return {}
|
139
|
+
|
140
|
+
# Extract variables from template files
|
141
|
+
variables = set()
|
142
|
+
|
143
|
+
# Check config files
|
144
|
+
for file_spec in template['config'].get('files', []):
|
145
|
+
if isinstance(file_spec, dict):
|
146
|
+
content = file_spec.get('content', '')
|
147
|
+
template_file = file_spec.get('template')
|
148
|
+
|
149
|
+
if template_file:
|
150
|
+
template_path = template['path'] / template_file
|
151
|
+
if template_path.exists():
|
152
|
+
content = template_path.read_text()
|
153
|
+
|
154
|
+
# Simple variable extraction ({{ variable }})
|
155
|
+
import re
|
156
|
+
variables.update(re.findall(r'\{\{\s*([^\s}]+)\s*\}\}', content))
|
157
|
+
|
158
|
+
return {var: "" for var in variables}
|
159
|
+
|
160
|
+
|
161
|
+
def get_template_manager() -> TemplateManager:
|
162
|
+
"""Get a template manager instance."""
|
163
|
+
return TemplateManager()
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# {{ project_name }}
|
2
|
+
|
3
|
+
{{ description }}
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
```bash
|
8
|
+
pip install -e .
|
9
|
+
```
|
10
|
+
|
11
|
+
## Development
|
12
|
+
|
13
|
+
Install development dependencies:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
pip install -e ".[dev]"
|
17
|
+
```
|
18
|
+
|
19
|
+
## Running Tests
|
20
|
+
|
21
|
+
```bash
|
22
|
+
pytest
|
23
|
+
```
|
24
|
+
|
25
|
+
## Building the Package
|
26
|
+
|
27
|
+
```bash
|
28
|
+
python -m build
|
29
|
+
```
|
30
|
+
|
31
|
+
## License
|
32
|
+
|
33
|
+
This project is licensed under the {{ license }} License - see the [LICENSE](LICENSE) file for details.
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Python
|
2
|
+
__pycache__/
|
3
|
+
*.py[cod]
|
4
|
+
*$py.class
|
5
|
+
*.so
|
6
|
+
.Python
|
7
|
+
build/
|
8
|
+
develop-eggs/
|
9
|
+
dist/
|
10
|
+
downloads/
|
11
|
+
eggs/
|
12
|
+
.eggs/
|
13
|
+
lib/
|
14
|
+
lib64/
|
15
|
+
parts/
|
16
|
+
sdist/
|
17
|
+
var/
|
18
|
+
wheels/
|
19
|
+
*.egg-info/
|
20
|
+
.installed.cfg
|
21
|
+
*.egg
|
22
|
+
|
23
|
+
# Virtual Environment
|
24
|
+
venv/
|
25
|
+
env/
|
26
|
+
|
27
|
+
# IDE
|
28
|
+
.idea/
|
29
|
+
.vscode/
|
30
|
+
*.swp
|
31
|
+
*.swo
|
32
|
+
|
33
|
+
# Testing
|
34
|
+
.coverage
|
35
|
+
htmlcov/
|
36
|
+
.pytest_cache/
|
37
|
+
|
38
|
+
# Distribution
|
39
|
+
*.whl
|
40
|
+
*.tar.gz
|
41
|
+
|
42
|
+
# Local development
|
43
|
+
.env
|
44
|
+
.env.local
|
45
|
+
|
46
|
+
# Logs
|
47
|
+
*.log
|
48
|
+
|
49
|
+
# OS specific
|
50
|
+
.DS_Store
|
51
|
+
Thumbs.db
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Python project template configuration
|
2
|
+
name: python
|
3
|
+
version: 1.0.0
|
4
|
+
description: A Python project template for WRD
|
5
|
+
|
6
|
+
# Files to create with their content templates
|
7
|
+
files:
|
8
|
+
- path: pyproject.toml
|
9
|
+
template: pyproject.toml.j2
|
10
|
+
- path: README.md
|
11
|
+
template: README.md.j2
|
12
|
+
- path: .gitignore
|
13
|
+
template: gitignore.j2
|
14
|
+
- path: src/{{ package_name }}/__init__.py
|
15
|
+
content: |
|
16
|
+
"""{{ project_name }} - {{ description }}"""
|
17
|
+
|
18
|
+
__version__ = "0.1.0"
|
19
|
+
- path: tests/__init__.py
|
20
|
+
content: "# Test package"
|
21
|
+
- path: tests/test_basic.py
|
22
|
+
content: |
|
23
|
+
"""Basic tests for {{ project_name }}."""
|
24
|
+
|
25
|
+
def test_import():
|
26
|
+
"""Test that the package can be imported."""
|
27
|
+
import {{ package_name }}
|
28
|
+
assert {{ package_name }} is not None
|
29
|
+
|
30
|
+
# Directories to create
|
31
|
+
directories:
|
32
|
+
- src/{{ package_name }}
|
33
|
+
- tests
|
34
|
+
|
35
|
+
# Commands to run after project creation
|
36
|
+
post_create_commands:
|
37
|
+
- git init
|
38
|
+
- git add .
|
39
|
+
- git commit -m "Initial commit"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=42.0"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "{{ package_name }}"
|
7
|
+
version = "0.1.0"
|
8
|
+
description = "{{ description }}"
|
9
|
+
authors = [
|
10
|
+
{ name = "{{ author_name }}", email = "{{ author_email }}" }
|
11
|
+
]
|
12
|
+
readme = "README.md"
|
13
|
+
requires-python = ">=3.8"
|
14
|
+
license = { text = "{{ license }}" }
|
15
|
+
|
16
|
+
[project.optional-dependencies]
|
17
|
+
dev = [
|
18
|
+
"pytest>=6.0",
|
19
|
+
"black>=21.12b0",
|
20
|
+
"isort>=5.10.1",
|
21
|
+
"mypy>=0.910",
|
22
|
+
"pytest-cov>=2.0"
|
23
|
+
]
|
24
|
+
|
25
|
+
[tool.black]
|
26
|
+
line-length = 88
|
27
|
+
target-version = ["py38"]
|
28
|
+
|
29
|
+
[tool.isort]
|
30
|
+
profile = "black"
|
31
|
+
line_length = 88
|
32
|
+
|
33
|
+
[tool.pytest.ini_options]
|
34
|
+
testpaths = ["tests"]
|
35
|
+
python_files = "test_*.py"
|