feat(cms): U4 one-command site build + local preview
Add tools/build_site.py: runs the full pipeline in dependency order (build_content -> build_listings -> seo_inject --all --sitemap -> build_botlinks -> build_search_index), each as a subprocess so a failing step aborts the build before anything downstream runs (no partial deploy). --check verifies non-destructively; --images also runs optimize_images. This is what CI will run in U5. Fix a build_content idempotence bug found via U4: the hero and article-header regions were emitted with leading indentation while the regex left the template's pre-tag whitespace in place, so indentation compounded (+16 spaces) on every rebuild. First line is now unindented; the full build is verified idempotent (identical git tree across two runs). Added a fixpoint test (re-rendering a page's own output is byte-identical) so this can't regress. docs/local-preview.md: build + serve on :8000 in all three languages. tools/README.md: document build_site + build_content. 26 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8ff968739a
commit
2d535db7d5
5 files changed
+175
-2
No files matched your search
@@ -42,6 +42,20 @@ class ReproducesEverySite(unittest.TestCase):
|
||||
self.assertEqual(mismatches, [], f"pages diverged from the live site: {mismatches}")
|
||||
|
||||
|
||||
class RenderIsIdempotent(unittest.TestCase):
|
||||
def test_rendering_output_again_is_a_fixpoint(self):
|
||||
"""Re-rendering a page using its own rendered output as the template
|
||||
must be byte-identical — otherwise the full build churns every run
|
||||
(e.g. compounding indentation)."""
|
||||
drift = []
|
||||
for meta, body, _path in bc.iter_entries():
|
||||
r1 = bc.build_entry(meta, body, bc._template_html(meta))
|
||||
r2 = bc.build_entry(meta, body, r1)
|
||||
if r1 != r2:
|
||||
drift.append(bc.output_path(meta).replace(os.sep, "/"))
|
||||
self.assertEqual(drift, [], f"non-idempotent renders: {drift}")
|
||||
|
||||
|
||||
class TitleSuffixFaithful(unittest.TestCase):
|
||||
def test_cyrillic_suffix_preserved(self):
|
||||
# MK pages use ' - МСОС' (Cyrillic); it must survive, not be dropped.
|
||||
|
||||
Reference in new issue
Block a user