diff options
| -rw-r--r-- | Makefile | 476 | ||||
| -rw-r--r-- | deps.mk | 468 | ||||
| -rw-r--r-- | meta.capim | 6 | ||||
| -rwxr-xr-x | mkdeps.sh | 7 |
4 files changed, 488 insertions, 469 deletions
@@ -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 @@ -220,3 +220,471 @@ 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 + +## mkwb canonical site rules. Sites consume this content by +## inlining it at the end of their generated deps.mk: mkdeps.sh +## runs `mkwb rules` (which cats this file) so deps.mk ends up +## self-contained -- no make-time `include` of an external file. +## 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 canonical rules below must follow deps.mk's variable +## assignments so that `all: $(derived-assets)` 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: @@ -2,4 +2,10 @@ :description "Landing page for Papo website (papo.im)." :baseurl "https://papo.im" :email "support@papo.im" + :dependencies { + :build #{ + eslaides + mkwb + } + } } @@ -164,3 +164,10 @@ for langlink in src/collections/*; do collectionentries "$langlink" "$colllink" done done + +## Inline the canonical mkwb rules at the end of deps.mk so that +## the variable assignments above are visible when those rules +## parse `all: $(derived-assets)` and its prereq list expands at +## parse time. Self-contained -- no make-time include needed. +echo +mkwb rules |
