2025-03-20 00:23:35 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""
|
2025-07-08 17:16:57 +02:00
|
|
|
main.py - Proxy to Makefile targets for managing the Portfolio CMS Docker application.
|
|
|
|
|
Automatically generates CLI commands based on the Makefile definitions.
|
2025-03-20 00:23:35 +01:00
|
|
|
"""
|
2026-03-29 23:03:09 +02:00
|
|
|
|
2025-03-20 00:23:35 +01:00
|
|
|
import argparse
|
2026-03-29 23:03:09 +02:00
|
|
|
import re
|
2025-03-20 00:23:35 +01:00
|
|
|
import subprocess
|
|
|
|
|
import sys
|
2025-07-05 10:12:49 +02:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
2025-07-08 17:16:57 +02:00
|
|
|
MAKEFILE_PATH = Path(__file__).resolve().parent / "Makefile"
|
|
|
|
|
|
2025-07-05 10:12:49 +02:00
|
|
|
|
2025-07-08 17:16:57 +02:00
|
|
|
def load_targets(makefile_path):
|
|
|
|
|
"""
|
|
|
|
|
Parse the Makefile to extract targets and their help comments.
|
|
|
|
|
Assumes each target is defined as 'name:' and the following line that starts
|
|
|
|
|
with '\t#' provides its help text.
|
|
|
|
|
"""
|
|
|
|
|
targets = []
|
|
|
|
|
pattern = re.compile(r"^([A-Za-z0-9_\-]+):")
|
2026-03-29 23:03:09 +02:00
|
|
|
with open(makefile_path, "r", encoding="utf-8") as handle:
|
|
|
|
|
lines = handle.readlines()
|
2025-07-08 17:16:57 +02:00
|
|
|
for idx, line in enumerate(lines):
|
|
|
|
|
m = pattern.match(line)
|
|
|
|
|
if m:
|
|
|
|
|
name = m.group(1)
|
2026-03-29 23:03:09 +02:00
|
|
|
help_text = ""
|
|
|
|
|
if idx + 1 < len(lines):
|
|
|
|
|
next_line = lines[idx + 1].lstrip()
|
|
|
|
|
if next_line.startswith("#"):
|
|
|
|
|
help_text = next_line.lstrip("# ").strip()
|
2025-07-08 17:16:57 +02:00
|
|
|
targets.append((name, help_text))
|
|
|
|
|
return targets
|
2025-03-20 00:23:35 +01:00
|
|
|
|
2025-07-08 17:16:57 +02:00
|
|
|
|
|
|
|
|
def run_command(command, dry_run=False):
|
|
|
|
|
"""Utility to run shell commands."""
|
2025-03-20 00:23:35 +01:00
|
|
|
print(f"Executing: {' '.join(command)}")
|
|
|
|
|
if dry_run:
|
|
|
|
|
print("Dry run enabled: command not executed.")
|
|
|
|
|
return
|
|
|
|
|
try:
|
2025-07-08 17:16:57 +02:00
|
|
|
subprocess.check_call(command)
|
2025-03-20 00:23:35 +01:00
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
|
print(f"Error: Command failed with exit code {e.returncode}")
|
|
|
|
|
sys.exit(e.returncode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
parser = argparse.ArgumentParser(
|
2025-07-08 17:16:57 +02:00
|
|
|
description="CLI proxy to Makefile targets for Portfolio CMS Docker app"
|
2025-03-20 00:23:35 +01:00
|
|
|
)
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"--dry-run",
|
|
|
|
|
action="store_true",
|
2026-03-29 23:03:09 +02:00
|
|
|
help="Print the generated Make command without executing it.",
|
2025-03-21 18:36:00 +01:00
|
|
|
)
|
2025-07-08 17:16:57 +02:00
|
|
|
|
2025-03-20 00:23:35 +01:00
|
|
|
subparsers = parser.add_subparsers(
|
2025-07-08 17:16:57 +02:00
|
|
|
title="Available commands",
|
|
|
|
|
dest="command",
|
2026-03-29 23:03:09 +02:00
|
|
|
required=True,
|
2025-03-20 00:23:35 +01:00
|
|
|
)
|
2025-03-21 18:36:00 +01:00
|
|
|
|
2025-07-08 17:16:57 +02:00
|
|
|
targets = load_targets(MAKEFILE_PATH)
|
|
|
|
|
for name, help_text in targets:
|
|
|
|
|
sp = subparsers.add_parser(name, help=help_text)
|
|
|
|
|
sp.set_defaults(target=name)
|
2025-03-21 18:36:00 +01:00
|
|
|
|
2025-03-20 00:23:35 +01:00
|
|
|
args = parser.parse_args()
|
2025-07-08 17:16:57 +02:00
|
|
|
cmd = ["make", args.target]
|
|
|
|
|
run_command(cmd, dry_run=args.dry_run)
|
|
|
|
|
|
2025-03-20 00:23:35 +01:00
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2026-03-29 23:03:09 +02:00
|
|
|
main()
|