summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-05-26 09:44:03 -0300
committerEuAndreh <eu@euandre.org>2026-05-26 09:44:03 -0300
commit1425add8cdcc648c4a91d8500c95a933eec8abfe (patch)
treedc363a5ccde69eb55a8d283305de502b32820460
parentmeta.capim: Add :dependencies key (diff)
downloadpapo.im-1425add8cdcc648c4a91d8500c95a933eec8abfe.tar.gz
papo.im-1425add8cdcc648c4a91d8500c95a933eec8abfe.tar.xz
Makefile: Slim to ~25 lines via include of mkwb's site.mk
All the suffix rules, derived-asset variable lists, and recipes (global.conf assembly, sitemap, security.txt, gpg-derived fingerprint/expiry, check-unit-*) moved into mkwb itself as share/mkwb/site.mk. mkdeps.sh now appends `include $(mkwb rules)` as the last line of deps.mk, so the Makefile only needs an `all:` anchor and `include deps.mk`. Per-site bits remain: NAME, VERSION, DATE, LANGUAGES, PORT, plus the i18n/run targets. Output of `make all` verified identical to the pre-refactor 251-file baseline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
-rw-r--r--Makefile476
-rw-r--r--deps.mk2
-rwxr-xr-xmkdeps.sh6
3 files changed, 15 insertions, 469 deletions
diff --git a/Makefile b/Makefile
index 007eb43..4cf6689 100644
--- a/Makefile
+++ b/Makefile
@@ -2,486 +2,24 @@
DATE = 1970-01-01
VERSION = 0.1.0
NAME = papo.im
-NAME_UC = $(NAME)
LANGUAGES = en
-## Installation prefix. Defaults to "/usr".
-PREFIX = /usr
-BINDIR = $(PREFIX)/bin
-LIBDIR = $(PREFIX)/lib
-INCLUDEDIR = $(PREFIX)/include
-SRCDIR = $(PREFIX)/src/$(NAME)
-SHAREDIR = $(PREFIX)/share
-LOCALEDIR = $(SHAREDIR)/locale
-MANDIR = $(SHAREDIR)/man
-DOCDIR = $(SHAREDIR)/doc/$(NAME)
-HTMLDIR = $(SHAREDIR)/html/$(NAME)
-EXEC = ./
-## Where to store the installation. Empty by default.
-DESTDIR =
-LDLIBS =
-PUBURL = public.asc.txt
-FFMFLAGS = -y -hide_banner -loglevel warning
-BASEURL = /
-
-
-
-.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 - < $< > $@
-
+PORT = 3333
+## `all:` anchors the default target before deps.mk's first rule
+## would otherwise claim it. deps.mk ends with `include` of mkwb's
+## site.mk, so the canonical rules load transitively.
all:
include 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 artifacts required for testing
-## and installation.
-all: $(derived-assets)
-all: $(captured-assets)
-
-
-$(derived-assets): Makefile deps.mk
-$(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) > $@
-
-
-
-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
-
-
-integration-tests = \
-
-.PRECIOUS: $(integration-tests)
-$(integration-tests): ALWAYS
- sh $@
-
-check-integration: $(integration-tests)
-
-
-## Run all tests. Each test suite is isolated, so that a parallel
-## build can run tests at the same time. The required artifacts
-## are created if missing.
-check: check-unit check-integration
-
-
+## ---- per-site additions to the canonical rules ----------------
i18n:
po4a po/po4a.cfg
-
-
-## Remove *all* derived artifacts produced during the build.
-## A dedicated test asserts that this is always true.
-clean:
- rm -rf $(derived-assets) $(side-assets)
-
-
-## Installs into $(DESTDIR)$(PREFIX). Its dependency target
-## ensures that all installable artifacts are crafted beforehand.
-install: all
- rsync --mkpath -a --files-from=install.txt src/content/ \
- '$(DESTDIR)$(HTMLDIR)'
- rsync --mkpath -a --files-from=sources.txt src/content/ \
- '$(DESTDIR)$(SRCDIR)'
-
-## Uninstalls from $(DESTDIR)$(PREFIX). This is a perfect mirror
-## of the "install" target, and removes *all* that was installed.
-## A dedicated test asserts that this is always true.
-uninstall:
- rm -rf \
- '$(DESTDIR)$(SRCDIR)' \
- '$(DESTDIR)$(HTMLDIR)' \
-
-
-
-PORT = 3333
-## Run file server for local installed static files.
+## Run file server for the installed static files.
run:
serve -n -p $(PORT) -d '$(DESTDIR)$(HTMLDIR)'
-
-ALWAYS:
+$(derived-assets): Makefile deps.mk
diff --git a/deps.mk b/deps.mk
index dcb63ef..3455d37 100644
--- a/deps.mk
+++ b/deps.mk
@@ -220,3 +220,5 @@ src/content/en/incidents/categories.txt: $(articles.en.incidents.categorydata)
src/content/en/incidents/categories.txt src/content/en/incidents/feed.xml: $(articles.en.incidents.feedentry)
src/content/en/incidents/categories.htmllisting src/content/en/incidents/categories.xml: src/content/en/incidents/categories.txt
src/content/en/incidents/categories.xml.gz: src/content/en/incidents/categories.xml
+
+include /home/andreh/.usr/var/mkg/share/mkwb/site.mk
diff --git a/mkdeps.sh b/mkdeps.sh
index 9df3e5a..58b4515 100755
--- a/mkdeps.sh
+++ b/mkdeps.sh
@@ -164,3 +164,9 @@ for langlink in src/collections/*; do
collectionentries "$langlink" "$colllink"
done
done
+
+## Pull in the canonical mkwb rules. Placed at the end of deps.mk
+## so that the variable assignments above are visible when site.mk
+## parses `all: $(derived-assets)` and its prereq list expands at
+## parse time (no GNU $(shell) needed in the site Makefile).
+printf '\ninclude %s\n' "`mkwb rules`"