|
| 1 | +import os |
| 2 | +import re |
| 3 | +import subprocess |
| 4 | + |
| 5 | +PAGES_DIR = "src/content/pages" |
| 6 | +PERMALINK_REGEX = re.compile(r'^(\s*permalink\s*:\s*)(.+?)(\s*)$', re.IGNORECASE) |
| 7 | + |
| 8 | +def run(cmd): |
| 9 | + try: |
| 10 | + return subprocess.check_output(cmd, stderr=subprocess.DEVNULL).decode().strip() |
| 11 | + except Exception: |
| 12 | + return "" |
| 13 | + |
| 14 | +def safe_filename(text: str) -> str: |
| 15 | + return text.strip().replace(" ", "-") |
| 16 | + |
| 17 | +# ------------------------------------------------- |
| 18 | +# ✅ Determine correct git diff base (PR vs push) |
| 19 | +# ------------------------------------------------- |
| 20 | +BASE_REF = os.environ.get("GITHUB_BASE_REF") |
| 21 | + |
| 22 | +if BASE_REF: |
| 23 | + diff_base = f"origin/{BASE_REF}" |
| 24 | +else: |
| 25 | + diff_base = "HEAD~1" |
| 26 | + |
| 27 | +# ------------------------------------------------- |
| 28 | +# ✅ Get changed files INCLUDING renames |
| 29 | +# ------------------------------------------------- |
| 30 | +diff_output = run([ |
| 31 | + "git", "diff", "--name-status", diff_base |
| 32 | +]).splitlines() |
| 33 | + |
| 34 | +changes = [] |
| 35 | + |
| 36 | +for line in diff_output: |
| 37 | + if not line: |
| 38 | + continue |
| 39 | + |
| 40 | + parts = line.split("\t") |
| 41 | + status = parts[0] |
| 42 | + |
| 43 | + if status.startswith("R"): # Rename detected |
| 44 | + old_path = parts[1] |
| 45 | + new_path = parts[2] |
| 46 | + changes.append(("rename", old_path, new_path)) |
| 47 | + elif status == "M": |
| 48 | + changes.append(("modify", parts[1])) |
| 49 | + |
| 50 | +# ------------------------------------------------- |
| 51 | +# ✅ HANDLE FILE RENAMES → UPDATE PERMALINK |
| 52 | +# ------------------------------------------------- |
| 53 | +for change in changes: |
| 54 | + if change[0] != "rename": |
| 55 | + continue |
| 56 | + |
| 57 | + old_path, new_path = change[1], change[2] |
| 58 | + |
| 59 | + if not new_path.startswith(PAGES_DIR) or not new_path.endswith(".yaml"): |
| 60 | + continue |
| 61 | + |
| 62 | + filename = os.path.basename(new_path) |
| 63 | + filename_without_ext = os.path.splitext(filename)[0] |
| 64 | + inferred_permalink = safe_filename(filename_without_ext) |
| 65 | + |
| 66 | + try: |
| 67 | + with open(new_path, "r", encoding="utf-8") as f: |
| 68 | + lines = f.readlines() |
| 69 | + except Exception: |
| 70 | + continue |
| 71 | + |
| 72 | + updated = False |
| 73 | + |
| 74 | + for i, line in enumerate(lines): |
| 75 | + match = PERMALINK_REGEX.match(line) |
| 76 | + if match: |
| 77 | + prefix, _, suffix = match.groups() |
| 78 | + lines[i] = f"{prefix}{inferred_permalink}{suffix}\n" |
| 79 | + updated = True |
| 80 | + break |
| 81 | + |
| 82 | + if not updated: |
| 83 | + if lines: |
| 84 | + lines.insert(1, f"permalink: {inferred_permalink}\n") |
| 85 | + else: |
| 86 | + lines.append(f"permalink: {inferred_permalink}\n") |
| 87 | + |
| 88 | + try: |
| 89 | + with open(new_path, "w", encoding="utf-8") as f: |
| 90 | + f.writelines(lines) |
| 91 | + print(f"✅ Updated permalink from filename: {new_path} → {inferred_permalink}") |
| 92 | + except Exception: |
| 93 | + pass |
| 94 | + |
| 95 | +# ------------------------------------------------- |
| 96 | +# ✅ HANDLE PERMALINK CHANGES → RENAME FILE |
| 97 | +# ------------------------------------------------- |
| 98 | +for change in changes: |
| 99 | + if change[0] != "modify": |
| 100 | + continue |
| 101 | + |
| 102 | + file_path = change[1] |
| 103 | + |
| 104 | + if not file_path.startswith(PAGES_DIR) or not file_path.endswith(".yaml"): |
| 105 | + continue |
| 106 | + |
| 107 | + filename = os.path.basename(file_path) |
| 108 | + root = os.path.dirname(file_path) |
| 109 | + |
| 110 | + try: |
| 111 | + new_content = run(["git", "show", f"HEAD:{file_path}"]) |
| 112 | + old_content = run(["git", "show", f"{diff_base}:{file_path}"]) |
| 113 | + except Exception: |
| 114 | + continue |
| 115 | + |
| 116 | + old_permalink = None |
| 117 | + new_permalink = None |
| 118 | + |
| 119 | + for line in old_content.splitlines(): |
| 120 | + match = PERMALINK_REGEX.match(line) |
| 121 | + if match: |
| 122 | + old_permalink = match.group(2).strip().strip('"\'') |
| 123 | + break |
| 124 | + |
| 125 | + for line in new_content.splitlines(): |
| 126 | + match = PERMALINK_REGEX.match(line) |
| 127 | + if match: |
| 128 | + new_permalink = match.group(2).strip().strip('"\'') |
| 129 | + break |
| 130 | + |
| 131 | + # ✅ Only act when permalink actually changed |
| 132 | + if new_permalink and new_permalink != old_permalink: |
| 133 | + expected_filename = f"{safe_filename(new_permalink)}.yaml" |
| 134 | + expected_path = os.path.join(root, expected_filename) |
| 135 | + |
| 136 | + if os.path.basename(file_path) != expected_filename: |
| 137 | + if not os.path.exists(expected_path): |
| 138 | + try: |
| 139 | + os.rename(file_path, expected_path) |
| 140 | + print(f"✅ Renamed from permalink: {file_path} → {expected_path}") |
| 141 | + except Exception: |
| 142 | + pass |
0 commit comments