| @@ -4,6 +4,7 @@ This script automates the process of building and deploying the website. |
| 4 | It handles tasks such as: |
4 | It handles tasks such as: |
| 5 | |
5 | |
| 6 | - Running orgo to generate site content. |
6 | - Running orgo to generate site content. |
| |
7 | - Rewriting the footer's orgo version to match the orgo that built the site. |
| 7 | - Rewriting image URLs for the onion service (production only). |
8 | - Rewriting image URLs for the onion service (production only). |
| 8 | - Optionally deploying the built site to a remote server. |
9 | - Optionally deploying the built site to a remote server. |
| 9 | - Starting a local development server for previewing changes. |
10 | - Starting a local development server for previewing changes. |
| @@ -77,6 +78,64 @@ def rewrite_img_urls(build_dir=".build"): |
| 77 | print(f"Rewrote {count} img.cleberg.net references to /img/") |
78 | print(f"Rewrote {count} img.cleberg.net references to /img/") |
| 78 | |
79 | |
| 79 | |
80 | |
| |
81 | # The footer's "Powered by orgo <version>" note. Anchored on the whole phrase rather |
| |
82 | # than on a placeholder token, so the template stays valid HTML on its own and a page |
| |
83 | # already carrying a version is rewritten the same way as a freshly rendered one — and |
| |
84 | # so prose that happens to end a paragraph with a link to orgo is left alone. |
| |
85 | ORGO_NOTE = re.compile( |
| |
86 | r'(Powered by <a href="https://gitbay\.org/krz/orgo">orgo</a> )[^<]*(</p>)' |
| |
87 | ) |
| |
88 | |
| |
89 | |
| |
90 | def orgo_version(): |
| |
91 | """The version reported by the orgo on PATH, e.g. "0.22.0".""" |
| |
92 | result = subprocess.run( |
| |
93 | ["orgo", "--version"], capture_output=True, text=True, check=False |
| |
94 | ) |
| |
95 | if result.returncode != 0: |
| |
96 | print("Could not read the orgo version:", file=sys.stderr) |
| |
97 | print(result.stderr, file=sys.stderr) |
| |
98 | sys.exit(1) |
| |
99 | # `orgo --version` prints "orgo X.Y.Z". Anything else means the output format |
| |
100 | # changed, and guessing at it would ship a wrong version to every page. |
| |
101 | parts = result.stdout.split() |
| |
102 | if len(parts) != 2 or parts[0] != "orgo": |
| |
103 | print(f"Unexpected `orgo --version` output: {result.stdout!r}", file=sys.stderr) |
| |
104 | sys.exit(1) |
| |
105 | return parts[1] |
| |
106 | |
| |
107 | |
| |
108 | def rewrite_orgo_version(build_dir): |
| |
109 | """Point the footer's orgo version at the orgo that just built the site. |
| |
110 | |
| |
111 | Runs over every page rather than only the re-rendered ones, because the build cache |
| |
112 | keys on a cache *format* version and not on orgo's release version: after a version |
| |
113 | bump that leaves the format alone, the pages carried over from the previous build |
| |
114 | would otherwise keep printing the old one. |
| |
115 | |
| |
116 | The whole point of this is that the note cannot go stale, so a footer that no longer |
| |
117 | matches is a failure and not a no-op — matching nothing anywhere means the note was |
| |
118 | removed or its markup changed, and a silent pass would leave the site claiming |
| |
119 | whatever the template last hardcoded. |
| |
120 | """ |
| |
121 | version = orgo_version() |
| |
122 | count = 0 |
| |
123 | for html in Path(build_dir).rglob("*.html"): |
| |
124 | text = html.read_text(encoding="utf-8") |
| |
125 | new_text, n = ORGO_NOTE.subn(rf"\g<1>{version}\g<2>", text) |
| |
126 | if n and new_text != text: |
| |
127 | html.write_text(new_text, encoding="utf-8") |
| |
128 | count += n |
| |
129 | if count == 0: |
| |
130 | print( |
| |
131 | "No 'Powered by orgo' note found in the build — the footer in " |
| |
132 | "content/templates/base.html no longer matches ORGO_NOTE", |
| |
133 | file=sys.stderr, |
| |
134 | ) |
| |
135 | sys.exit(1) |
| |
136 | print(f"Set the footer orgo version to {version} on {count} pages") |
| |
137 | |
| |
138 | |
| 80 | def run_orgo_build(build_dir): |
139 | def run_orgo_build(build_dir): |
| 81 | """ |
140 | """ |
| 82 | Build the site with orgo. |
141 | Build the site with orgo. |
| @@ -164,6 +223,9 @@ def main(): |
| 164 | |
223 | |
| 165 | if os.environ.get("BUILD", "").casefold() == "true": |
224 | if os.environ.get("BUILD", "").casefold() == "true": |
| 166 | run_orgo_build(build_dir) |
225 | run_orgo_build(build_dir) |
| |
226 | # Both environments: a dev preview showing a stale version is the same defect |
| |
227 | # as a deployed page showing one. |
| |
228 | rewrite_orgo_version(build_dir) |
| 167 | # The onion needs same-origin images; dev previews keep the absolute URLs. |
229 | # The onion needs same-origin images; dev previews keep the absolute URLs. |
| 168 | # Runs over every page, not just the re-rendered ones, so a page carried over |
230 | # Runs over every page, not just the re-rendered ones, so a page carried over |
| 169 | # from an earlier build is rewritten too. |
231 | # from an earlier build is rewritten too. |