From: Lady <redacted>
Date: Sun, 28 Apr 2024 02:48:30 +0000 (-0400)
Subject: Support GNU stat
X-Git-Tag: 0.7.3~2
X-Git-Url: https://git.ladys.computer/Shushe/commitdiff_plain/ccef2f2a2243cf086b165562cb73defa14f34f62?ds=sidebyside;hp=54fe3a7117cb2f1783e623df1d19e415757fcfb2

Support GNU stat

`stat` isn’t at all portable; it’s necessary to just try to figure out
which version is being used and then handle each case accordingly.
---

diff --git a/GNUmakefile b/GNUmakefile
index 42e677c..bbf15d7 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -25,6 +25,7 @@ override define makefileinfo
 ║│ • echo                                                     │║
 ║│ • file                                                     │║
 ║│ • find                                                     │║
+║│ • grep                                                     │║
 ║│ • git (optional)                                           │║
 ║│ • ln                                                       │║
 ║│ • mkdir (requires support for `-p´)                        │║
@@ -102,6 +103,7 @@ ECHO := echo
 FILE := file
 FIND := find
 GIT := git
+GREP := grep
 LN := ln
 MKDIR := mkdir
 MV := mv
@@ -246,6 +248,13 @@ override quote = '$(subst ','"'"',$1)'
 # Outputs an `@´ to silence rules, unless `VERBOSE´ is nonempty.
 override silent := $(if $(VERBOSE),,@)
 
+# (callable) Get the modified time of the provided file.
+#
+# This is messy; there is no portable way of using `stat´.
+#
+# ☡ This variable creates a subshell every time it is computed.
+override modtime = $(shell if $(STAT) --version 2> /dev/null | $(GREP) -q GNU; then $(DATE) -d "@$$(TZ= $(STAT) -c '%Y' $(call quote,$1))" '+%Y-%m-%dT%H:%M:%SZ'; else TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$1); fi)
+
 # ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
 
 # (callable) Check to see if the given directory exists and create it if not.
@@ -562,7 +571,7 @@ $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2pars
 $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(typeupdates)
 	@$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
 	$(silent)$(call ensuredirectory,$(dir $@))
-	$(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$<)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(call serializexml,$<)) | $(XSLTPROC) -o $(call quote,$@) --stringparam BUILDTIME $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam IDENTIFIER $(call quote,$(call localuri,$<)) --stringparam SRCTIME $$(TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$<)) --stringparam CKSUM $$($(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/parser.xslt) -)
+	$(silent)$(if $(filter $<,$(assetfiles)),$(PRINTF) '%s\n' $(call quote,<object xmlns="http://www.w3.org/1999/xhtml" type="$(call typeoffile,$<)" data="$(call datauri,$<)"/>) > $(call quote,$@),$(if $(filter $<,$(plaintextfiles)),$(call wrapplaintext,$<),$(call serializexml,$<)) | $(XSLTPROC) -o $(call quote,$@) --stringparam BUILDTIME $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam IDENTIFIER $(call quote,$(call localuri,$<)) --stringparam SRCTIME '$(call modtime,$<)' --stringparam CKSUM $$($(CKSUM) $(call quote,$<) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/parser.xslt) -)
 
 # Generate a catalog of all parsed files, for use when processing includes.
 #
@@ -598,7 +607,7 @@ $(BUILDDIR)/transform.xslt : $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalo
 $(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parsed,$$(call uncompiled,$$@)) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@)))
 	@$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
 	$(silent)$(call ensuredirectory,$(dir $@))
-	$(silent)$(XSLTPROC) -o $(call quote,$@) --stringparam CATALOG 'catalog' --stringparam BUILDTIME $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam SRCTIME $$(TZ= $(STAT) -f '%Sm' -t '%Y-%m-%dT%H:%M:%SZ' $(call quote,$(call uncompiled,$@))) --stringparam IDENTIFIER $(call quote,$(call localuri,$(call uncompiled,$@))) --stringparam PATH $(call quote,/$*) --stringparam CKSUM $$($(CKSUM) $(call quote,$(call uncompiled,$@)) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
+	$(silent)$(XSLTPROC) -o $(call quote,$@) --stringparam CATALOG 'catalog' --stringparam BUILDTIME $$(TZ= $(DATE) '+%Y-%m-%dT%H:%M:%SZ') --stringparam SRCTIME '$(call modtime,$(call uncompiled,$@))' --stringparam IDENTIFIER $(call quote,$(call localuri,$(call uncompiled,$@))) --stringparam PATH $(call quote,/$*) --stringparam CKSUM $$($(CKSUM) $(call quote,$(call uncompiled,$@)) | $(SED) 's/[ ].*//')$(if $(THISREV), --stringparam THISREV $(call quote,$(THISREV)),)$(if $(SRCREV), --stringparam SRCREV $(call quote,$(SRCREV)),) $(call quote,$(BUILDDIR)/transform.xslt) $(call quote,$<)
 
 # Create the final files from the compiled results (or error in the case of recursive ones).
 $(call built,$(compilablefiles)) : $(BUILDDIR)/public/% : $(BUILDDIR)/results/%
diff --git a/README.markdown b/README.markdown
index 8a0ebe1..5457ce7 100644
--- a/README.markdown
+++ b/README.markdown
@@ -121,6 +121,7 @@ In every case, you may supply your own implementation by overriding the
 - `file`
 - `find`
 - `git` (optional; set `GIT=` to disable)
+- `grep`
 - `ln`
 - `mkdir` (requires support for `-p`)
 - `mv`
@@ -130,7 +131,7 @@ In every case, you may supply your own implementation by overriding the
 - `rm`
 - `sed`
 - `sleep`
-- `stat`
+- `stat` (BSD *or* GNU)
 - `test`
 - `touch`
 - `tr` (requires support for `-d`)