|
| 1 | +# VIBE-CODED |
1 | 2 | import shutil |
2 | 3 | from pathlib import Path |
3 | 4 |
|
4 | 5 | import click |
5 | 6 |
|
6 | 7 | import afterpython as ap |
7 | 8 |
|
| 9 | +# Workflow names supported by `create_workflow` / `update_workflow_file`. |
| 10 | +# "dependabot" is included even though it lives at .github/dependabot.yml |
| 11 | +# (not under workflows/) so a single CLI surface can refresh all GH templates. |
| 12 | +VALID_WORKFLOWS = ("deploy", "ci", "release", "dependabot") |
8 | 13 |
|
9 | | -def _copy_github_template(template_name: str, target_path: Path): |
10 | | - """Helper to copy GitHub-related templates""" |
11 | | - if target_path.exists(): |
12 | | - click.echo(f"{target_path} already exists") |
13 | | - return |
14 | 14 |
|
15 | | - # Create parent directory if it doesn't exist |
16 | | - target_path.parent.mkdir(parents=True, exist_ok=True) |
| 15 | +def _resolve_workflow_target(name: str) -> tuple[Path, Path]: |
| 16 | + """Return (target_path, template_path) for a workflow name.""" |
| 17 | + if name not in VALID_WORKFLOWS: |
| 18 | + raise ValueError( |
| 19 | + f"Unknown workflow '{name}'. Valid: {', '.join(VALID_WORKFLOWS)}" |
| 20 | + ) |
| 21 | + user_path = ap.paths.user_path |
| 22 | + templates_path = ap.paths.templates_path |
| 23 | + if name == "dependabot": |
| 24 | + target = user_path / ".github" / "dependabot.yml" |
| 25 | + template = templates_path / "dependabot-template.yml" |
| 26 | + else: |
| 27 | + target = user_path / ".github" / "workflows" / f"{name}.yml" |
| 28 | + template = templates_path / f"{name}-workflow-template.yml" |
| 29 | + return target, template |
17 | 30 |
|
18 | | - # Copy template from package |
19 | | - template_path = ap.paths.templates_path / template_name |
| 31 | + |
| 32 | +def _copy_github_template(template_path: Path, target_path: Path): |
| 33 | + """Copy a template file into the project, creating parent dirs as needed.""" |
20 | 34 | if not template_path.exists(): |
21 | 35 | raise FileNotFoundError( |
22 | 36 | f"Template file not found: {template_path}\n" |
23 | 37 | "This might indicate a corrupted installation. Please reinstall afterpython." |
24 | 38 | ) |
25 | | - |
| 39 | + target_path.parent.mkdir(parents=True, exist_ok=True) |
26 | 40 | shutil.copy(template_path, target_path) |
27 | | - print(f"Created {target_path}") |
28 | 41 |
|
29 | 42 |
|
30 | 43 | def create_workflow(workflow_name: str): |
31 | | - """Create a GitHub Actions workflow from template""" |
| 44 | + """Create a GitHub Actions workflow from template (no-op if it exists).""" |
32 | 45 | if ".yml" in workflow_name: |
33 | 46 | workflow_name = workflow_name.replace(".yml", "") |
34 | 47 |
|
35 | | - user_path = ap.paths.user_path |
36 | | - workflow_path = user_path / ".github" / "workflows" / f"{workflow_name}.yml" |
37 | | - template_name = f"{workflow_name}-workflow-template.yml" |
38 | | - |
39 | | - _copy_github_template(template_name, workflow_path) |
| 48 | + target_path, template_path = _resolve_workflow_target(workflow_name) |
| 49 | + if target_path.exists(): |
| 50 | + click.echo(f"{target_path} already exists") |
| 51 | + return |
| 52 | + _copy_github_template(template_path, target_path) |
| 53 | + click.echo(f"Created {target_path}") |
40 | 54 |
|
41 | 55 |
|
42 | 56 | def create_dependabot(): |
43 | | - """Create Dependabot configuration for GitHub Actions updates""" |
44 | | - user_path = ap.paths.user_path |
45 | | - dependabot_path = user_path / ".github" / "dependabot.yml" |
46 | | - template_name = "dependabot-template.yml" |
| 57 | + """Create Dependabot configuration for GitHub Actions updates.""" |
| 58 | + target_path, template_path = _resolve_workflow_target("dependabot") |
| 59 | + if target_path.exists(): |
| 60 | + click.echo(f"{target_path} already exists") |
| 61 | + return |
| 62 | + _copy_github_template(template_path, target_path) |
| 63 | + click.echo(f"Created {target_path}") |
| 64 | + |
47 | 65 |
|
48 | | - _copy_github_template(template_name, dependabot_path) |
| 66 | +def update_workflow_file(name: str, backup: bool = True): |
| 67 | + """Overwrite a workflow file with the latest template. |
| 68 | +
|
| 69 | + If the target already exists and ``backup`` is True, the existing file is |
| 70 | + copied to ``<file>.backup`` first so user customizations aren't lost. |
| 71 | + """ |
| 72 | + target_path, template_path = _resolve_workflow_target(name) |
| 73 | + if target_path.exists(): |
| 74 | + if backup: |
| 75 | + backup_path = Path(str(target_path) + ".backup") |
| 76 | + shutil.copy(target_path, backup_path) |
| 77 | + click.echo(f"Backed up {target_path} → {backup_path}") |
| 78 | + _copy_github_template(template_path, target_path) |
| 79 | + click.echo(f"Updated {target_path}") |
| 80 | + else: |
| 81 | + _copy_github_template(template_path, target_path) |
| 82 | + click.echo(f"Created {target_path}") |
0 commit comments