diff options
| author | EuAndreh <eu@euandre.org> | 2026-05-26 09:43:44 -0300 |
|---|---|---|
| committer | EuAndreh <eu@euandre.org> | 2026-05-26 09:43:44 -0300 |
| commit | 94bef68330c09ffb052c7bd881e5d9cd7ba04d32 (patch) | |
| tree | 828f718271de83bc6d4fbafe9806ef56c204c924 | |
| parent | meta.capim: Add with :dependencies key (diff) | |
| download | mkwb-94bef68330c09ffb052c7bd881e5d9cd7ba04d32.tar.gz mkwb-94bef68330c09ffb052c7bd881e5d9cd7ba04d32.tar.xz | |
Extract canonical site rules into share/mkwb/site.mk
Sites used to copy-paste ~340 lines of suffix rules, derived-asset
lists, and recipes (global.conf assembly, sitemap, security.txt,
gpg-derived fingerprint/expiry, check-unit-*) into every Makefile.
Move all of it into share/mkwb/site.mk, shipped at install time.
Add src/rules.in -> `mkwb rules`: prints the absolute path of the
shipped site.mk so a site's mkdeps.sh can append it as the last
`include` line of deps.mk. The site's own Makefile then needs
only an `all:` anchor (to keep it as the default target ahead of
deps.mk's first rule) and `include deps.mk`.
Also adds tests/resources/{site,expected}/ and tests/integration.sh
exercising mkwb htmlbody / links / snippets / sortdata against
golden files, with sortdata covering >1 collection and >1 entry
per collection to verify per-collection chronological ordering.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
23 files changed, 695 insertions, 3 deletions
@@ -1 +1,2 @@ /src/mkwb +/src/rules @@ -27,7 +27,8 @@ LDLIBS = .in: sed \ - 's:@LIBEXECDIR@:$(LIBEXECDIR):g' \ + -e 's:@LIBEXECDIR@:$(LIBEXECDIR):g' \ + -e 's:@SHAREDIR@:$(SHAREDIR):g' \ < $< > $@ if [ -x $< ]; then chmod +x $@; fi @@ -39,10 +40,14 @@ include deps.mk sources = \ $(libexec.sh) \ src/$(NAME).in \ + src/rules.in \ +share-files = \ + share/$(NAME)/site.mk \ derived-assets = \ src/$(NAME) \ + src/rules \ side-assets = \ @@ -57,7 +62,8 @@ all: $(derived-assets) check-unit: -check-integration: +check-integration: src/$(NAME) + ./tests/integration.sh ## Run all tests. Each test suite is isolated, so that a parallel @@ -79,10 +85,12 @@ install: all mkdir -p \ '$(DESTDIR)$(BINDIR)' \ '$(DESTDIR)$(LIBEXECDIR)' \ + '$(DESTDIR)$(SHAREDIR)/$(NAME)' \ '$(DESTDIR)$(SRCDIR)' \ cp src/$(NAME) '$(DESTDIR)$(BINDIR)' - cp $(libexec.sh) '$(DESTDIR)$(LIBEXECDIR)' + cp $(libexec.sh) src/rules '$(DESTDIR)$(LIBEXECDIR)' + cp $(share-files) '$(DESTDIR)$(SHAREDIR)/$(NAME)' cp $(sources) '$(DESTDIR)$(SRCDIR)' @@ -93,6 +101,7 @@ uninstall: rm -rf \ '$(DESTDIR)$(BINDIR)'/$(NAME) \ '$(DESTDIR)$(LIBEXECDIR)' \ + '$(DESTDIR)$(SHAREDIR)/$(NAME)' \ '$(DESTDIR)$(SRCDIR)' \ diff --git a/share/mkwb/site.mk b/share/mkwb/site.mk new file mode 100644 index 0000000..76e9e51 --- /dev/null +++ b/share/mkwb/site.mk @@ -0,0 +1,466 @@ +## mkwb canonical site rules. Sites consume this transitively +## via deps.mk: mkdeps.sh emits `include <mkwb rules path>` as +## the last line of deps.mk, so the site Makefile only needs an +## `all:` anchor followed by `include deps.mk`. Order matters: +## `all:` must come first (otherwise deps.mk's first target +## becomes the default), and the site.mk include must come AFTER +## deps.mk's variable assignments so that this file's +## `all: $(derived-assets)` line can resolve its prereq list at +## parse time. +## +## The including Makefile is expected to define at minimum: +## +## NAME -- site name (used for SRCDIR/HTMLDIR install paths) +## VERSION +## DATE +## +## To override any of PREFIX / BINDIR / SHAREDIR / SRCDIR / +## HTMLDIR / PUBURL / BASEURL / FFMFLAGS, set them AFTER the +## include (plain `=`, POSIX -- no `?=` conditional assignment), +## or pass `-e` to make to let env vars take precedence. + + + +## Default values. Sites override AFTER the include or via env. +PREFIX = /usr +BINDIR = $(PREFIX)/bin +LIBDIR = $(PREFIX)/lib +INCLUDEDIR = $(PREFIX)/include +SHAREDIR = $(PREFIX)/share +LOCALEDIR = $(SHAREDIR)/locale +MANDIR = $(SHAREDIR)/man +DOCDIR = $(SHAREDIR)/doc/$(NAME) +HTMLDIR = $(SHAREDIR)/html/$(NAME) +SRCDIR = $(PREFIX)/src/$(NAME) +DESTDIR = +PUBURL = public.asc.txt +BASEURL = / +FFMFLAGS = -y -hide_banner -loglevel warning + + + +.SUFFIXES: +.SUFFIXES: .adoc .conf .snippets .indexentry .feedentry .mapentry .sortdata .xml +.SUFFIXES: .htmlbody .htmlheader .htmlfooter .htmllisting .html .links .caslinks +.SUFFIXES: .txt .categorydata .gz .torrent .flac .ogg .ps .pdf .sentinel + +.adoc.conf: + mkwb conf src/global.conf $< > $@ + +.adoc.htmlbody: + mkwb htmlbody $< > $@ + +.htmlbody.html: + mkwb html $< > $@ + +.conf.htmlheader: + mkwb html -H $< > $@ + +.conf.htmlfooter: + mkwb html -F $< > $@ + +.adoc.snippets: + mkwb snippets $< > $@ + +.conf.indexentry: + mkwb indexentry $< > $@ + +.htmlbody.feedentry: + mkwb feedentry $< > $@ + +.conf.mapentry: + mkwb mapentry $< > $@ + +.conf.sortdata: + mkwb sortdata $< > $@ + +.conf.categorydata: + mkwb categorydata $< > $@ + +.adoc.links: + mkwb links $< > $@ + +.links.caslinks: + grep -Ev '^(link|image):' $< | xargs -I_ sh -c '\ + printf "%s\n" "_" | sha256sum | \ + printf "%s\t%s\n" "`cut -d" " -f1`" "_"' > $@ + +.flac.ogg: + ffmpeg $(FFMFLAGS) -i $< -ar 48000 -vn -c:a libvorbis -b:a 320k $@ + +.adoc.ps: + eslaides < $< > $@ + +.ps.pdf: + ps2pdf - < $< > $@ + + + +## Derived file lists from auto-generated source lists in deps.mk. +listings.adoc = $(categories.adoc) $(indexes.adoc) +sources.adoc = $(articles.adoc) $(listings.adoc) $(pages.adoc) +sources.htmlbody = $(sources.adoc:.adoc=.htmlbody) +sources.html = $(sources.adoc:.adoc=.html) +sources.snippets = $(sources.adoc:.adoc=.snippets) +sources.snippets.gz = $(sources.adoc:.adoc=.snippets.gz) +sources.conf = $(sources.adoc:.adoc=.conf) +sources.links = $(sources.adoc:.adoc=.links) +sources.caslinks = $(sources.adoc:.adoc=.caslinks) +sources.mapentry = $(sources.adoc:.adoc=.mapentry) +articles.indexentry = $(articles.adoc:.adoc=.indexentry) +articles.feedentry = $(articles.adoc:.adoc=.feedentry) +articles.sortdata = $(articles.adoc:.adoc=.sortdata) +articles.categorydata = $(articles.adoc:.adoc=.categorydata) +listings.htmlheader = $(listings.adoc:.adoc=.htmlheader) +listings.htmlfooter = $(listings.adoc:.adoc=.htmlfooter) +listings.html = $(listings.adoc:.adoc=.html) +indexes.htmllisting = $(indexes.adoc:.adoc=.htmllisting) +categories.htmllisting = $(categories.adoc:.adoc=.htmllisting) +categories.txt = $(categories.adoc:.adoc=.txt) +categories.xml = $(categories.adoc:.adoc=.xml) +categories.xml.gz = $(categories.adoc:.adoc=.xml.gz) +sources.media.torrent = $(sources.media:=.torrent) +slides.ps = $(slides.adoc:.adoc=.ps) +slides.pdf = $(slides.adoc:.adoc=.pdf) + +sources = \ + $(sources.adoc) \ + $(sources.extras) \ + $(images.svg) \ + src/content/favicon.ico \ + src/content/favicon.png \ + src/content/style.css \ + src/content/$(PUBURL) \ + +dynamic-contents = \ + $(sources.html) \ + $(slides.pdf) \ + $(feeds.xml) \ + $(sources.media.torrent) \ + src/content/sitemap.xml \ + +static-contents = \ + $(sources.extras) \ + $(images.svg) \ + src/content/favicon.ico \ + src/content/favicon.png \ + src/content/style.css \ + src/content/$(PUBURL) \ + src/content/.well-known/security.txt \ + +dynamic-contents.gz = $(dynamic-contents:=.gz) + +static-contents.gz = \ + $(images.svg:=.gz) \ + src/content/favicon.ico.gz \ + src/content/style.css.gz \ + src/content/$(PUBURL).gz \ + src/content/.well-known/security.txt.gz \ + +contents.gz = \ + $(dynamic-contents.gz) \ + $(static-contents.gz) \ + +contents = \ + $(dynamic-contents) \ + $(static-contents) \ + +all-filelists = \ + $(sources.snippets) \ + $(sources.snippets.gz) \ + $(categories.xml) \ + $(categories.xml.gz) \ + +all-contents = \ + $(contents) \ + $(contents.gz) \ + +captured-assets = \ + src/content/$(PUBURL) \ + src/content/favicon.ico \ + src/content/favicon.png \ + +captured-assets.sentinel = $(captured-assets:=.sentinel) + +derived-assets = \ + $(dynamic-contents) \ + $(contents.gz) \ + $(sources.html) \ + $(sources.htmlbody) \ + $(sources.snippets) \ + $(sources.snippets.gz) \ + $(sources.conf) \ + $(sources.links) \ + $(sources.caslinks) \ + $(sources.mapentry) \ + src/dyn.conf \ + src/base.conf \ + src/global.conf \ + $(articles.indexentry) \ + $(articles.feedentry) \ + $(articles.sortdata) \ + $(articles.categorydata) \ + $(listings.htmlheader) \ + $(listings.htmlfooter) \ + $(listings.html) \ + $(indexes.htmllisting) \ + $(categories.htmllisting) \ + $(categories.txt) \ + $(categories.xml) \ + $(categories.xml.gz) \ + $(slides.ps) \ + $(slides.pdf) \ + email.txt \ + baseurl.txt \ + fingerprint.txt \ + expiry.txt \ + expiry-epoch.txt \ + now.txt \ + src/content/.well-known/security.txt \ + src/all-contents.txt \ + src/all-filelists.txt \ + src/all-symlinks.txt \ + src/install.txt \ + src/sort-expected.txt \ + src/sort-given.txt \ + src/sources.txt \ + install.txt \ + sources.txt \ + src/content/.gitignore \ + $(captured-assets.sentinel) \ + +side-assets = \ + src/collections/*/*/*/*/*/*.html.*.txt \ + src/collections/*/*/*/*/*/*.txt.gz \ + src/collections/*/*/index.html.*.txt \ + src/collections/*/*/sortdata.txt \ + src/collections/*/*/feed.*.xml \ + src/collections/*/*/feed.*.xml.gz \ + src/collections/*/*/*.sortdata \ + src/pages/*/*.html.*.txt \ + src/content/.well-known/ \ + `cat src/all-symlinks.txt 2>/dev/null` \ + `cat src/linkonly-dirs.txt 2>/dev/null` \ + + + +## Default target -- builds all derived + captured artifacts. +all: $(derived-assets) $(captured-assets) + + +$(sources.conf): src/global.conf + + +src/content/.gitignore: src/symlinks.txt + cd src/content/ && mkwb symlinks ../symlinks.txt > $(@F) + +src/dyn.conf: email.txt baseurl.txt fingerprint.txt + printf "export url_pre='%s'\n" "`cat baseurl.txt`" > $@ + printf "export email='%s'\n" "`cat email.txt`" >> $@ + printf "export publickey='%s'\n" "`cat fingerprint.txt`" >> $@ + printf "export publickey_url='$(PUBURL)'\n" >> $@ + printf 'export sourcecode_url="$$url_pre/git/$(NAME)"\n' >> $@ + +src/base.conf: src/dyn.conf src/static.conf + cat src/dyn.conf src/static.conf > $@ + +src/global.conf: src/base.conf + mkwb conf -G src/base.conf > $@ + +$(listings.html): + cat $*.htmlheader $*.htmlbody $*.htmllisting $*.htmlfooter > $@ + +$(indexes.htmllisting): + mkwb indexbody $*.conf > $@ + +$(categories.htmllisting): + mkwb categoriesbody $*.conf > $@ + +$(categories.txt): src/global.conf + mkwb categories src/global.conf $(@D) > $@ + +$(categories.xml): + for f in `cat $*.txt`; do \ + c="`printf '%s\n' "$$f" | cut -d. -f2`"; \ + mkwb feed src/global.conf "$$f" > $(@D)/feed."$$c".xml; \ + printf '%s\n' $(@D)/feed."$$c".xml; \ + done > $@ + +$(feeds.xml): + mkwb feed src/global.conf $(@D)/sortdata.txt > $@ + +$(contents.gz): + gzip -9fk $* + touch $@ + +$(sources.snippets.gz) $(categories.xml.gz): + if [ -s $* ]; then gzip -9fk `cat $*`; fi + sed 's/$$/.gz/' $* > $@ + +src/content/$(PUBURL).gz: src/content/$(PUBURL).sentinel +src/content/$(PUBURL).sentinel: email.txt + gpg --export --armour "`cat email.txt`" | ifne ifnew $* + touch $@ + +src/content/favicon.ico.gz: src/content/favicon.ico.sentinel +src/content/favicon.ico.sentinel: src/content/img/favicon.svg + convert src/content/img/favicon.svg -strip ico:- | ifnew $* + touch $@ + +src/content/favicon.png.sentinel: src/content/img/favicon.svg + convert src/content/img/favicon.svg -strip png:- | ifnew $* + touch $@ + +$(sources.media.torrent): + F="`printf '%s\n' $* | cut -d/ -f3-`" && \ + mktorrent -xfd -n $(*F) -o $@ -w "https://$(NAME)$(BASEURL)$${F}" $* + +src/content/sitemap.xml.gz: src/content/sitemap.xml +src/content/sitemap.xml: $(sources.mapentry) + mkwb sitemap $(sources.mapentry) > $@ + +email.txt: meta.capim + cat meta.capim | awk '$$1 == ":email" && $$0=$$2' | tr -d '"' > $@ + +baseurl.txt: meta.capim + cat meta.capim | awk '$$1 == ":baseurl" && $$0=$$2' | tr -d '"' > $@ + +fingerprint.txt: src/content/$(PUBURL) + gpg --always-trust --no-keyring --show-key --with-colons \ + src/content/$(PUBURL) | \ + awk -F: '/^pub:/ { print $$5 }' > $@ + +expiry.txt: src/content/$(PUBURL) + gpg --always-trust --no-keyring --show-key --with-colons \ + src/content/$(PUBURL) | \ + awk -F: '/^pub:/ { print $$7 }' | \ + xargs -I% date -Is -d@% > $@ + +expiry-epoch.txt: expiry.txt + date -d "`cat expiry.txt`" '+%s' > $@ + +now.txt: + now > $@ + +src/content/.well-known/security.txt.gz: src/content/.well-known/security.txt +src/content/.well-known/security.txt: email.txt baseurl.txt expiry.txt + mkdir -p $(@D) + printf 'Contact: mailto:%s\n' "`cat email.txt`" > $@ + printf 'Expires: %s\n' "`cat expiry.txt`" >> $@ + printf 'Encryption: %s/$(PUBURL)\n' "`cat baseurl.txt`" >> $@ + printf 'Preferred-Languages: en, pt, fr, eo, es, de\n' >> $@ + +src/sources.txt: + printf '%s\n' $(sources) > $@ + +src/all-contents.txt: + printf '%s\n' $(all-contents) > $@ + +src/all-filelists.txt: src/all-symlinks.txt + printf '%s\n' $(all-filelists) src/all-symlinks.txt > $@ + +src/all-symlinks.txt: src/content/.gitignore + sed 's|^|src/content|' src/content/.gitignore > $@ + +src/install.txt: src/all-contents.txt src/all-filelists.txt $(all-filelists) + cat src/all-contents.txt `cat src/all-filelists.txt` > $@ + +sources.txt: src/sources.txt +install.txt: src/install.txt +sources.txt install.txt: + sed 's|^src/content/||' src/$(@F) > $@ + + + +## ---- check-unit-* targets --------------------------------------- + +src/sort-expected.txt: + dirname $(articles.adoc) | env LANG=POSIX.UTF-8 sort | uniq -c | \ + awk '{ printf "%s\t%s\n", $$2, $$1 }' > $@ + +src/sort-given.txt: $(sources.conf) src/sort-expected.txt + awk '{ \ + "grep \"^export sort=\" " $$1 "/*.conf | wc -l" | getline cnt; \ + printf "%s\t%s\n", $$1, cnt; \ + }' src/sort-expected.txt > $@ + +check-unit-sorting: src/sort-expected.txt src/sort-given.txt + diff -U10 src/sort-expected.txt src/sort-given.txt + + +.SUFFIXES: .updatedat-check +sources.updatedat-check = $(sources.adoc:.adoc=.updatedat-check) +$(sources.updatedat-check): + . ./$*.conf && if [ -n "$$updatedat_epoch" ] && \ + [ "$$updatedat_epoch" -le "$$date_epoch" ]; then exit 3; fi + +check-unit-updatedat: $(sources.updatedat-check) + + +.SUFFIXES: .links-internal-check +sources.links-internal-check = $(sources.adoc:.adoc=.links-internal-check) +$(sources.links-internal-check): $(sources.html) $(slides.pdf) + grep -E '^(link|image):' $*.links | cut -d: -f2- | \ + xargs -I% test -e $(*D)/% + +check-unit-links-internal: $(sources.links-internal-check) + + +check-unit-links-external: + + +symlink-deps = \ + $(sources.html) \ + $(feeds.xml) \ + $(categories.xml) \ + src/content/.well-known/security.txt \ + $(sources.media.torrent) \ + +check-unit-links-symlinks: src/all-symlinks.txt $(symlink-deps) + find `cat src/all-symlinks.txt` | xargs -n1 test -e + + +check-unit-links: check-unit-links-internal check-unit-links-external +check-unit-links: check-unit-links-symlinks + + +MAXSIZE = 52428800 # from spec: https://www.sitemaps.org/protocol.html +check-unit-sitemap-size: src/content/sitemap.xml + test "`stat --printf='%s' src/content/sitemap.xml`" -le $(MAXSIZE) + +check-unit-sitemap-count: src/content/sitemap.xml + test "`grep -cF '</url>' src/content/sitemap.xml`" -le 50000 + +check-unit-sitemap: check-unit-sitemap-count check-unit-sitemap-size + + +check-unit-expiry: expiry-epoch.txt now.txt + test "`cat expiry-epoch.txt`" -gt "`cat now.txt`" + + +check-unit: check-unit-sorting check-unit-updatedat check-unit-links +check-unit: check-unit-sitemap check-unit-expiry + + +## ---- standard housekeeping -------------------------------------- + +## Remove all derived artifacts produced during the build. +clean: + rm -rf $(derived-assets) $(side-assets) + + +## Install into $(DESTDIR)$(PREFIX). +install: all + rsync --mkpath -a --files-from=install.txt src/content/ \ + '$(DESTDIR)$(HTMLDIR)' + rsync --mkpath -a --files-from=sources.txt src/content/ \ + '$(DESTDIR)$(SRCDIR)' + +## Remove what install placed. +uninstall: + rm -rf \ + '$(DESTDIR)$(SRCDIR)' \ + '$(DESTDIR)$(HTMLDIR)' \ + + +ALWAYS: diff --git a/src/rules.in b/src/rules.in new file mode 100755 index 0000000..b998091 --- /dev/null +++ b/src/rules.in @@ -0,0 +1,6 @@ +#!/bin/sh +# Print the absolute path of the canonical Makefile rules shipped +# alongside mkwb. Sites consume it with: +# include $(shell mkwb rules) +# in their top-level Makefile. +echo '@SHAREDIR@/mkwb/site.mk' diff --git a/tests/integration.sh b/tests/integration.sh new file mode 100755 index 0000000..b8b7c1f --- /dev/null +++ b/tests/integration.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# Integration test: drives mkwb against a slim fixture site and +# diffs every output against committed golden files under +# tests/resources/expected/. Run in an isolated tmpdir so the +# snapshot fixture (tests/resources/site/) stays clean. +# +# Required tools on PATH: mkwb (with all libexec scripts) and adoc. +set -eu + +HERE="$(dirname "$(readlink -f "$0")")" +RESOURCES="$HERE/resources" +SITE="$RESOURCES/site" +EXPECTED="$RESOURCES/expected" + +WORK="$(mktemp -d -t mkwb-integration.XXXXXX)" +trap 'rm -rf "$WORK"' EXIT INT TERM + +cp -r "$SITE/." "$WORK/" + +CONTENT="$WORK/src/content" +ACTUAL="$WORK/actual" +mkdir -p "$ACTUAL" + +# --- single-page subcommands ------------------------------------- +# htmlbody: .adoc -> HTML body fragment +mkwb htmlbody "$CONTENT/hello.adoc" > "$ACTUAL/hello.htmlbody" + +# links: extract :attr: link values from the .adoc +mkwb links "$CONTENT/hello.adoc" > "$ACTUAL/hello.links" + +# snippets: emits one .txt per "----" block next to the .adoc, and +# prints the list of filenames to stdout. Run from $CONTENT so the +# filenames are relative. +( cd "$CONTENT" && mkwb snippets hello.adoc ) > "$ACTUAL/hello.snippets" +cp "$CONTENT/hello.html.0.txt" "$ACTUAL/hello.html.0.txt" +cp "$CONTENT/hello.html.1.txt" "$ACTUAL/hello.html.1.txt" + +# --- sortdata: per-collection chronological sort ----------------- +# Each <collection>/YYYY/MM/DD/X.conf gets a sibling sentinel three +# levels up at <collection>/${date_iso}-${sort}.sortdata pointing +# back to the original .sortdata. Sorting these sentinel filenames +# alphabetically yields the chronological order per collection. +for conf in \ + "$CONTENT/en/blog/2024/01/15/launch.conf" \ + "$CONTENT/en/blog/2025/03/20/feature.conf" \ + "$CONTENT/en/news/2024/06/01/founding.conf" \ + "$CONTENT/en/news/2025/06/01/anniversary.conf" \ + ; do + ( cd "$WORK" && mkwb sortdata "${conf#$WORK/}" ) > /dev/null +done + +# --- diff every captured output against goldens ------------------ +fail=0 +diff_one() { + if diff -u "$EXPECTED/$1" "$2"; then + echo "PASS: $1" + else + echo "FAIL: $1 differs from expected" >&2 + fail=1 + fi +} + +for f in hello.htmlbody hello.links hello.snippets \ + hello.html.0.txt hello.html.1.txt; do + diff_one "$f" "$ACTUAL/$f" +done + +# Diff each sentinel file content (points back to .sortdata). +for f in src/content/en/blog/2024-01-15-launch.sortdata \ + src/content/en/blog/2025-03-20-feature.sortdata \ + src/content/en/news/2024-06-01-founding.sortdata \ + src/content/en/news/2025-06-01-anniversary.sortdata; do + diff_one "$f" "$WORK/$f" +done + +# Verify the FILENAME order per collection encodes chronological +# order -- sort all *.sortdata under each collection and check the +# listing matches expected. +for col in blog news; do + want="$(cd "$EXPECTED/src/content/en/$col" && \ + ls *.sortdata 2>/dev/null | sort)" + got="$(cd "$WORK/src/content/en/$col" && \ + ls *.sortdata 2>/dev/null | sort)" + if [ "$want" = "$got" ]; then + echo "PASS: sortdata order in collection '$col'" + else + echo "FAIL: sortdata order in collection '$col'" >&2 + echo " expected:"; echo "$want" | sed 's/^/ /' + echo " actual: "; echo "$got" | sed 's/^/ /' + fail=1 + fi +done + +exit "$fail" diff --git a/tests/resources/expected/hello.html.0.txt b/tests/resources/expected/hello.html.0.txt new file mode 100644 index 0000000..3307d1d --- /dev/null +++ b/tests/resources/expected/hello.html.0.txt @@ -0,0 +1,4 @@ +{ + "key": "value", + "n": 42 +} diff --git a/tests/resources/expected/hello.html.1.txt b/tests/resources/expected/hello.html.1.txt new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/tests/resources/expected/hello.html.1.txt @@ -0,0 +1 @@ +hello world diff --git a/tests/resources/expected/hello.htmlbody b/tests/resources/expected/hello.htmlbody new file mode 100644 index 0000000..34badfb --- /dev/null +++ b/tests/resources/expected/hello.htmlbody @@ -0,0 +1,54 @@ + <div id="preamble"> + <div class="sectionbody"> + <div class="paragraph"> + <p>A minimal asciidoc page used by mkwb’s integration test.</p> + </div> + </div> + </div> + <div class="sect1"> + <h2 id="section">Section<a class="anchor" + href="#section"></a></h2> + <div class="sectionbody"> + <div class="ulist"> + <ul> + <li> + <p>item one</p> + </li> + <li> + <p>item two</p> + </li> + </ul> + </div> + </div> + </div> + <div class="sect1"> + <h2 id="snippet">Snippet<a class="anchor" + href="#snippet"></a></h2> + <div class="sectionbody"> + <div class="listingblock"> + <div class="content"> + <pre>{ + "key": "value", + "n": 42 +}</pre> + </div> + </div> + <div class="paragraph plaintext"> + <p><a href="hello.html.0.txt">plaintext</a></p> + </div> + </div> + </div> + <div class="sect1"> + <h2 id="another-snippet">Another snippet<a class="anchor" + href="#another-snippet"></a></h2> + <div class="sectionbody"> + <div class="listingblock"> + <div class="content"> + <pre>hello world</pre> + </div> + </div> + <div class="paragraph plaintext"> + <p><a href="hello.html.1.txt">plaintext</a></p> + </div> + </div> + </div> diff --git a/tests/resources/expected/hello.links b/tests/resources/expected/hello.links new file mode 100644 index 0000000..222889b --- /dev/null +++ b/tests/resources/expected/hello.links @@ -0,0 +1,2 @@ +https://example.com/docs +https://www.rfc-editor.org/rfc/rfc7230 diff --git a/tests/resources/expected/hello.snippets b/tests/resources/expected/hello.snippets new file mode 100644 index 0000000..87c2af9 --- /dev/null +++ b/tests/resources/expected/hello.snippets @@ -0,0 +1,2 @@ +hello.html.0.txt +hello.html.1.txt diff --git a/tests/resources/expected/src/content/en/blog/2024-01-15-launch.sortdata b/tests/resources/expected/src/content/en/blog/2024-01-15-launch.sortdata new file mode 100644 index 0000000..39e52c0 --- /dev/null +++ b/tests/resources/expected/src/content/en/blog/2024-01-15-launch.sortdata @@ -0,0 +1 @@ +src/content/en/blog/2024/01/15/launch.sortdata diff --git a/tests/resources/expected/src/content/en/blog/2025-03-20-feature.sortdata b/tests/resources/expected/src/content/en/blog/2025-03-20-feature.sortdata new file mode 100644 index 0000000..e8a1011 --- /dev/null +++ b/tests/resources/expected/src/content/en/blog/2025-03-20-feature.sortdata @@ -0,0 +1 @@ +src/content/en/blog/2025/03/20/feature.sortdata diff --git a/tests/resources/expected/src/content/en/news/2024-06-01-founding.sortdata b/tests/resources/expected/src/content/en/news/2024-06-01-founding.sortdata new file mode 100644 index 0000000..72d71a6 --- /dev/null +++ b/tests/resources/expected/src/content/en/news/2024-06-01-founding.sortdata @@ -0,0 +1 @@ +src/content/en/news/2024/06/01/founding.sortdata diff --git a/tests/resources/expected/src/content/en/news/2025-06-01-anniversary.sortdata b/tests/resources/expected/src/content/en/news/2025-06-01-anniversary.sortdata new file mode 100644 index 0000000..185cf9b --- /dev/null +++ b/tests/resources/expected/src/content/en/news/2025-06-01-anniversary.sortdata @@ -0,0 +1 @@ +src/content/en/news/2025/06/01/anniversary.sortdata diff --git a/tests/resources/site/src/content/en/blog/2024/01/15/launch.adoc b/tests/resources/site/src/content/en/blog/2024/01/15/launch.adoc new file mode 100644 index 0000000..9360a9d --- /dev/null +++ b/tests/resources/site/src/content/en/blog/2024/01/15/launch.adoc @@ -0,0 +1,4 @@ += Launch +:updatedat: 2024-01-15 + +We launched. diff --git a/tests/resources/site/src/content/en/blog/2024/01/15/launch.conf b/tests/resources/site/src/content/en/blog/2024/01/15/launch.conf new file mode 100644 index 0000000..70163d5 --- /dev/null +++ b/tests/resources/site/src/content/en/blog/2024/01/15/launch.conf @@ -0,0 +1,2 @@ +date_iso=2024-01-15 +sort=launch diff --git a/tests/resources/site/src/content/en/blog/2025/03/20/feature.adoc b/tests/resources/site/src/content/en/blog/2025/03/20/feature.adoc new file mode 100644 index 0000000..681656f --- /dev/null +++ b/tests/resources/site/src/content/en/blog/2025/03/20/feature.adoc @@ -0,0 +1,4 @@ += Feature +:updatedat: 2025-03-20 + +We shipped a feature. diff --git a/tests/resources/site/src/content/en/blog/2025/03/20/feature.conf b/tests/resources/site/src/content/en/blog/2025/03/20/feature.conf new file mode 100644 index 0000000..aead7c2 --- /dev/null +++ b/tests/resources/site/src/content/en/blog/2025/03/20/feature.conf @@ -0,0 +1,2 @@ +date_iso=2025-03-20 +sort=feature diff --git a/tests/resources/site/src/content/en/news/2024/06/01/founding.adoc b/tests/resources/site/src/content/en/news/2024/06/01/founding.adoc new file mode 100644 index 0000000..ab650b8 --- /dev/null +++ b/tests/resources/site/src/content/en/news/2024/06/01/founding.adoc @@ -0,0 +1,4 @@ += Founding +:updatedat: 2024-06-01 + +Org founded. diff --git a/tests/resources/site/src/content/en/news/2024/06/01/founding.conf b/tests/resources/site/src/content/en/news/2024/06/01/founding.conf new file mode 100644 index 0000000..8504263 --- /dev/null +++ b/tests/resources/site/src/content/en/news/2024/06/01/founding.conf @@ -0,0 +1,2 @@ +date_iso=2024-06-01 +sort=founding diff --git a/tests/resources/site/src/content/en/news/2025/06/01/anniversary.adoc b/tests/resources/site/src/content/en/news/2025/06/01/anniversary.adoc new file mode 100644 index 0000000..de32ee0 --- /dev/null +++ b/tests/resources/site/src/content/en/news/2025/06/01/anniversary.adoc @@ -0,0 +1,4 @@ += Anniversary +:updatedat: 2025-06-01 + +One year in. diff --git a/tests/resources/site/src/content/en/news/2025/06/01/anniversary.conf b/tests/resources/site/src/content/en/news/2025/06/01/anniversary.conf new file mode 100644 index 0000000..01e24d9 --- /dev/null +++ b/tests/resources/site/src/content/en/news/2025/06/01/anniversary.conf @@ -0,0 +1,2 @@ +date_iso=2025-06-01 +sort=anniversary diff --git a/tests/resources/site/src/content/hello.adoc b/tests/resources/site/src/content/hello.adoc new file mode 100644 index 0000000..ef6ac5b --- /dev/null +++ b/tests/resources/site/src/content/hello.adoc @@ -0,0 +1,25 @@ += Hello +:upstream-docs: https://example.com/docs +:rfc-link: https://www.rfc-editor.org/rfc/rfc7230 + +A minimal asciidoc page used by mkwb's integration test. + +== Section + +* item one +* item two + +== Snippet + +---- +{ + "key": "value", + "n": 42 +} +---- + +== Another snippet + +---- +hello world +---- |
