From: Lady <redacted>
Date: Tue, 21 May 2024 03:46:42 +0000 (-0400)
Subject: Redirect messages to stderr & support disabling
X-Git-Tag: 0.9.0^0
X-Git-Url: https://git.ladys.computer/Shushe/commitdiff_plain/61599492d0451c48f963a13a78a11a59415eb6f0

Redirect messages to stderr & support disabling

This enables `make -s listout` to work as intended without need for
additional processing.
---

diff --git a/GNUmakefile b/GNUmakefile
index 7765095..2c77723 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -222,6 +222,9 @@ endif
 #   Generates archive files from parse results.
 MODE := urn:fdc:ladys.computer:20231231:Shu1She4:mode:default
 
+# Set to a non·empty value to silence informative messages.
+QUIET :=
+
 # Set to a non·empty value to print all commands as they run.
 VERBOSE :=
 
@@ -250,9 +253,6 @@ override comma := ,
 # (callable) Quote the given string for use within shell calls.
 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.
 #
 # Only the date·time information available via `ls -l´ is supported; that is, only minute precision for files newer than six months, and only day precision for files which are older.
@@ -269,6 +269,12 @@ override modtime = $(shell { $(DATE) -u '+%Y-%m'; LC_TIME=POSIX TZ=UTC0 ls -q -A
 
 # ─ ¶ Recipe Variable Definitions ─────────────────────────────────────
 
+# Outputs an `@´ to silence rules, unless `VERBOSE´ is non·empty.
+override silent := $(if $(VERBOSE),,@)
+
+# (callable) Only perform the rule if `QUIET` is not set.
+override inform = $(if $(QUIET),,@$1)
+
 # (callable) Check to see if the given directory exists and create it if not.
 override ensuredirectory = if $(TEST) ! -d $(call quote,$1); then $(MKDIR) -p $(call quote,$1); fi
 
@@ -507,7 +513,7 @@ list :
 
 # Lists out the destinations of all resulting files (relative to `DESTDIR´).
 listout :
-	@$(PRINTF) '⛩️📰 书社 Output: %s\n' $(call quote,$(foreach file,$(sort $(sourcefiles)),$(call destination,$(file))))
+	@$(PRINTF) '%s\n' $(call quote,$(foreach file,$(sort $(sourcefiles)),$(call destination,$(file))))
 
 # Destroy installed files.
 uninstall :
@@ -515,7 +521,7 @@ uninstall :
 
 # Raise an error when attempting to build any files with recursive dependencies.
 $(call built,$(recursivefiles)) :
-	@$(PRINTF) '%b\n' $(call quote,\0033[93;41mError:\0033[39;49m `$(call unbuilt,$@)´ has recursive dependencies:\n$(subst |, ,$(subst $(space),$(newline),$(foreach recursive,$(call recursives,$(call unbuilt,$@)),•|$(recursive))))) && false
+	@$(PRINTF) '%b\n' $(call quote,\0033[93;41mError:\0033[39;49m `$(call unbuilt,$@)´ has recursive dependencies:\n$(subst |, ,$(subst $(space),$(newline),$(foreach recursive,$(call recursives,$(call unbuilt,$@)),•|$(recursive))))) >&2 && false
 
 # Add as a prerequisite to treat the target as tho it were phony.
 FORCE : ;
@@ -542,10 +548,10 @@ ifneq ($(typeupdates)$(wildcard $(BUILDDIR)/dependencies)$(wildcard $(BUILDDIR)/
 $(THISDIR)/GNUmakefile :: $(BUILDDIR)/dependencies $(BUILDDIR)/destinations
 	$(silent)$(TOUCH) $(THISDIR)/GNUmakefile
 ifeq ($(typeupdates),)
-	@if $(TEST) ! -f $(call quote,$(BUILDDIR)/.update-types); then $(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m'; fi
+	$(call inform,if $(TEST) ! -f $(call quote,$(BUILDDIR)/.update-types); then $(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m' >&2; fi)
 else
 	$(silent)$(RM) $(call quote,$(BUILDDIR)/.update-types)
-	@$(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m'
+	$(call inform,$(PRINTF) '%b\n' '\0033[1mDependency graph and output destinations updated. Restarting…\0033[22m' >&2)
 endif
 endif
 
@@ -558,7 +564,7 @@ ifeq ($(typeupdates),)
 $(THISDIR)/GNUmakefile :: $(BUILDDIR)/magic.mgc $(BUILDDIR)/parser.xslt
 	$(silent)$(TOUCH) $(THISDIR)/GNUmakefile
 	$(silent)$(RM) -f $(call quote,$(BUILDDIR)/dependencies) $(call quote,$(BUILDDIR)/destinations)
-	@$(PRINTF) '%b\n' '\0033[1mMagic file or parsers have updated. Restarting…\0033[22m'
+	$(call inform,$(PRINTF) '%b\n' '\0033[1mMagic file or parsers have updated. Restarting…\0033[22m' >&2)
 	$(silent)$(SLEEP) 1
 	$(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types)
 endif
@@ -575,18 +581,18 @@ $(call magicfile,$(MAGIC)) : $(BUILDDIR)/magic/% : $$(call magicsource,$$@)
 # It must be updated if any of the files in the magic directory change.
 $(BUILDDIR)/magic.mgc : $(call diffprereqs,magic,$(sort $(call magicfile,$(MAGIC))))
 	$(foreach outdated,$(filter-out $^,$(wildcard $(BUILDDIR)/magic/*)),$(silent)$(RM) $(call quote,$(outdated))$(newline))
-	@$(PRINTF) '%s\n' 'Compiling new magic…'
+	$(call inform,$(PRINTF) '%s\n' 'Compiling new magic…' >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)cd $(call quote,$(BUILDDIR)) && $(FILE) -C -m $(call quote,$(realpath $(BUILDDIR)/magic))
 	$(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types)
 
 # Generate the main parser.
 $(BUILDDIR)/parser.catalog : $(call diffprereqs,parsers,$(sort $(PARSERS)))
-	@$(PRINTF) '%s\n' 'Generating catalog of parsers…'
+	$(call inform,$(PRINTF) '%s\n' 'Generating catalog of parsers…' >&2)
 	$(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
 	$(foreach parser,$(PARSERS),$(silent){ $(call id,$(parser)); $(PRINTF) '%s\n' $(call quote,$(call fileuri,$(parser))) '--noout' $(call quote,$@); } | $(xargsmultiquote) | $(XARGS) -E '' $(XMLCATALOG) --add uri$(newline))
 $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2parser.xslt
-	@$(PRINTF) '%s\n' 'Generating main parser…'
+	$(call inform,$(PRINTF) '%s\n' 'Generating main parser…' >&2)
 	$(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2parser.xslt) $(call quote,$<)
 	$(silent)$(TOUCH) $(call quote,$(BUILDDIR)/.update-types)
 
@@ -595,7 +601,7 @@ $(BUILDDIR)/parser.xslt : $(BUILDDIR)/parser.catalog $(THISDIR)/lib/catalog2pars
 # Even plain X·M·L files are parsed, because they may contain X·H·T·M·L `<script>´ elements which contain other kinds of data.
 # Asset files are turned into H·T·M·L embeds pointing to `data:´ U·R·I’s.
 $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BUILDDIR)/parser.xslt $(typeupdates)
-	@$(PRINTF) '%s\n' $(call quote,Processing `$<´…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Processing `$<´…) >&2)
 	$(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) --nonet --novalid -o $(call quote,$@) --stringparam BUILDTIME $$($(DATE) -u '+%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) -)
 
@@ -603,13 +609,13 @@ $(call parsed,$(sourcefiles) $(sourceincludes)) : % : $$(call unparsed,$$@) $(BU
 #
 # This does not depend on actually transforming the files.
 $(BUILDDIR)/catalog : $(call diffprereqs,sources,$(sort $(sourcefiles) $(sourceincludes))) $(typeupdates)
-	@$(PRINTF) '%s\n' 'Generating catalog of parsed files…'
+	$(call inform,$(PRINTF) '%s\n' 'Generating catalog of parsed files…' >&2)
 	$(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
 	$(foreach source,$(sourcefiles) $(sourceincludes),$(silent)$(XMLCATALOG) --add uri $(call quote,$(call localuri,$(source))) $(call quote,$(call fileuri,$(call parsed,$(source)))#$(if $(filter $(source),$(assetfiles)),asset,xml)) --noout $(call quote,$@)$(newline))
 
 # Build a list of dependencies for each parsed file.
 $(BUILDDIR)/dependencies : $(BUILDDIR)/catalog $(call parsed,$(plaintextfiles) $(xmlfiles)) $(THISDIR)/lib/catalog2dependencies.xslt
-	@$(PRINTF) '%s\n' 'Identifying dependencies…'
+	$(call inform,$(PRINTF) '%s\n' 'Identifying dependencies…' >&2)
 	$(silent)$(TOUCH) $(call quote,$@)
 	$(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2dependencies.xslt) $(call quote,$<)
 
@@ -618,40 +624,40 @@ $(BUILDDIR)/dependencies : $(BUILDDIR)/catalog $(call parsed,$(plaintextfiles) $
 # This depends on parsing non·asset source files, but not assets or includes.
 # It does not require knowing the dependencies.
 $(BUILDDIR)/destinations : $(BUILDDIR)/catalog $(call parsed,$(filter-out $(assetfiles),$(sourcefiles))) $(THISDIR)/lib/catalog2destinations.xslt
-	@$(PRINTF) '%s\n' 'Identifying output destinations…'
+	$(call inform,$(PRINTF) '%s\n' 'Identifying output destinations…' >&2)
 	$(silent)$(TOUCH) $(call quote,$@)
 	$(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2destinations.xslt) $(call quote,$<)
 
 # Generate the main transform.
 $(BUILDDIR)/transform.catalog : $(call diffprereqs,transforms,$(sort $(TRANSFORMS)))
-	@$(PRINTF) '%s\n' 'Generating catalog of transforms…'
+	$(call inform,$(PRINTF) '%s\n' 'Generating catalog of transforms…' >&2)
 	$(silent)$(XMLCATALOG) --create --noout $(call quote,$@)
 	$(foreach transform,$(TRANSFORMS),$(silent){ $(call id,$(transform)); $(PRINTF) '%s\n' $(call quote,$(call fileuri,$(transform))) '--noout' $(call quote,$@); } | $(xargsmultiquote) | $(XARGS) -E '' $(XMLCATALOG) --add uri$(newline))
 $(BUILDDIR)/transform.xslt : $(BUILDDIR)/transform.catalog $(THISDIR)/lib/catalog2transform.xslt
-	@$(PRINTF) '%s\n' 'Generating main transform…'
+	$(call inform,$(PRINTF) '%s\n' 'Generating main transform…' >&2)
 	$(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) $(call quote,$(THISDIR)/lib/catalog2transform.xslt) $(call quote,$<)
 
 # Compile the result files using the dependencies as necessary.
 $(call compiled,$(compilablefiles)) : $(BUILDDIR)/results/% : $$(call parsed,$$(call uncompiled,$$@)) $(BUILDDIR)/transform.xslt $$(call parsed,$$(call dependencies,$$(call uncompiled,$$@)))
-	@$(PRINTF) '%s\n' $(call quote,Compiling </$*>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Compiling </$*>…) >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --stringparam CATALOG 'catalog' --stringparam BUILDTIME $$($(DATE) -u '+%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/%
-	@$(PRINTF) '%s\n' $(call quote,Building </$*>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Building </$*>…) >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)$(RM) -f -R $(call quote,$@)
 	$(silent)$(call processresultto,$<,$@,$*)
 $(call built,$(filter $(assetfiles),$(sourcefiles))) : $(BUILDDIR)/public/% : $$(call unbuilt,$$@)
-	@$(PRINTF) '%s\n' $(call quote,Building </$*>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Building </$*>…) >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)$(RM) -f -R $(call quote,$@)
 	$(silent)$(CP) $(call quote,$<) $(call quote,$@)
 
 # Install compiled files (or error in the case of recursive ones).
 $(call installed,$(recursivefiles) $(installablefiles)) : $(DESTDIR)/% : $(BUILDDIR)/public/%
-	@$(PRINTF) '%s\n' $(call quote,Installing </$*>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Installing </$*>…) >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)$(RM) -f -R $(call quote,$@)
 	$(silent)$(CP) -R $(call quote,$<) $(call quote,$@)
@@ -676,7 +682,7 @@ endif
 # Reload this make·file if the archive components have changed.
 $(THISDIR)/GNUmakefile : $(BUILDDIR)/index
 	$(silent)$(TOUCH) $(THISDIR)/GNUmakefile
-	@$(PRINTF) '%b\n' $(call quote,\0033[1mArchive components for </$(NAME)> updated. Restarting…\0033[22m)
+	$(call inform,$(PRINTF) '%b\n' $(call quote,\0033[1mArchive components for </$(NAME)> updated. Restarting…\0033[22m) >&2)
 
 # ─ ¶ Build Targets ───────────────────────────────────────────────────
 
@@ -689,7 +695,7 @@ $(BUILDDIR)/extractor.xslt : $(SRC) $(THISDIR)/lib/archive2extractor.xslt
 #
 # This target sleeps for 1 second to ensure the resulting index will always be newer than this make·file.
 $(BUILDDIR)/index : $(BUILDDIR)/extractor.xslt $(SRC)
-	@$(PRINTF) '%s\n' $(call quote,Extracting components for </$(NAME)>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Extracting components for </$(NAME)>…) >&2)
 	$(silent)$(SLEEP) 1
 	$(silent)$(XSLTPROC) --nonet --novalid -o $(call quote,$@) --writesubtree $(call quote,$(dir $@)) $(call quote,$<) $(call quote,$(SRC))
 
@@ -698,7 +704,7 @@ $(foreach file,$(archivefiles),$(BUILDDIR)/extracted/$(file)) : $(BUILDDIR)/inde
 
 # Process each extractor component into its final form.
 $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) : $(BUILDDIR)/files/% : $(BUILDDIR)/extracted/%
-	@$(PRINTF) '%s\n' $(call quote,Building </$(NAME)/$*>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Building </$(NAME)/$*>…) >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)$(RM) -f -R $(call quote,$@)
 	$(silent)$(call processresultto,$<,$@,$*)
@@ -707,7 +713,7 @@ $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file)) : $(BUILDDIR)/files/%
 #
 # This is a match‐anything target, with the assumption that this make·file is being called recursively from the default mode.
 $(DESTDIR)/% : $(SRC) $(foreach file,$(archivefiles),$(BUILDDIR)/files/$(file))
-	@$(PRINTF) '%s\n' $(call quote,Archiving </$(NAME)>…)
+	$(call inform,$(PRINTF) '%s\n' $(call quote,Archiving </$(NAME)>…) >&2)
 	$(silent)$(call ensuredirectory,$(dir $@))
 	$(silent)$(RM) -f -R $(call quote,$@)
 	$(silent)cd $(call quote,$(BUILDDIR)/files); if $(call xpath,/*/@*[local-name()="expanded" and namespace-uri()="urn:fdc:ladys.computer:20231231:Shu1She4"],$(abspath $<)); then $(MKDIR) -p $(call quote,$(abspath $@)); $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -r -w $(call quote,$(abspath $@)); else $(PRINTF) '%s\n' $(foreach file,$(archivefiles),$(call quote,$(file))) | $(PAX) -w -x ustar > $(call quote,$(abspath $@)); fi
diff --git a/README.markdown b/README.markdown
index 5342790..3375b8a 100644
--- a/README.markdown
+++ b/README.markdown
@@ -303,6 +303,15 @@ The following additional variables can be used to control the behaviour
   The current version of the source files (default: derived from the
     current git tag/branch/commit).
 
+- **`QUIET`:**
+  If this variable has a value, informative messages will not be
+    printed (default: empty).
+  Informative messages print to stderr, not stdout, so disabling them
+    usually shouldn’t be necessary.
+  This does not (cannot) disable messages from Make itself, for which
+    the `-s`, `--silent` ∕ `--quiet` Make option is more likely to be
+    useful.
+
 - **`VERBOSE`:**
   If this variable has a value, every recipe instruction will be
     printed when it runs (default: empty).