Subject: [bug#19614] Split packaging invocation to catch errors

From: Bogdan <[email-masked]>
Date: Fri, 30 Dec 2022 14:15:13 +0100

Hello again.

This time a patch that splits 'tar ... | gzip/bzip2/whatever' into 2 
commands.

Yes, this introduces a requirement for a "temporary" .tar file (and 
i-node allocation, and filesystem free space/performance, and ...), 
but gives gains (I hope they're gains):

1) when 'tar' exits with an error, 'make' handles it and stops the 
packaging instead of letting the second packer in the chain possibly 
create an incomplete package,

2) when 'tar' fails but does NOT exit with an error, I check the 
standard error output for any messages. If present, I assume an error 
and let 'make' handle it like in case 1).

GNU tar behaves nicely: when a problem is encountered, it stops with 
an error exit code. The unfortunate default on my system, BSD tar, 
doesn't. In case of a problem, just a warning is emitted, the exit 
code is success even though files are missing from the resulting .tar 
file. And there is no way to turn those warnings into errors. No idea 
who thought of that. Hence manual checking stderr.

Feel free to modify the test if needed. I assumed all dist types are 
available, but that may not always be the case - maybe some 
conditionals are needed.

Regards,
Bogdan Drozdowski

-- 
Regards - Bogdan ('bogdro') D.                 (GNU/Linux & FreeDOS)
X86 assembly (DOS, GNU/Linux):    http://bogdro.evai.pl/index-en.php
Soft(EN): http://bogdro.evai.pl/soft  http://bogdro.evai.pl/soft4asm
www.Xiph.org  www.TorProject.org  www.LibreOffice.org  www.GnuPG.org

From c3ee1c91693bf09c2815644933e6abd0afaccdd6 Mon Sep 17 00:00:00 2001
From: Bogdan Drozdowski <>
Date: Tue, 27 Dec 2022 22:39:58 +0100
Subject: [PATCH] Split packaging so tar error fails the build

---
 lib/am/distdir.am  | 42 ++++++++++++++++++++++++++-----
 t/list-of-tests.mk |  1 +
 t/tar-split-cmd.sh | 62 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 6 deletions(-)
 create mode 100644 t/tar-split-cmd.sh

diff --git a/lib/am/distdir.am b/lib/am/distdir.am
index aa2be5238..5ccae5397 100644
--- a/lib/am/distdir.am
+++ b/lib/am/distdir.am
@@ -334,31 +334,56 @@ if %?TOPDIR_P%
 GZIP_ENV = --best
 .PHONY: dist-gzip
 dist-gzip: distdir
-	tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
+	tardir=$(distdir) && $(am__tar) > $(distdir).tar 2>$(distdir).err
+	test ! -s $(distdir).err || (cat $(distdir).err && \
+		rm -rf $(DIST_ARCHIVES) $(distdir).tar $(distdir).err && \
+		$(am__post_remove_distdir) && \
+		exit 1)
+	eval GZIP= gzip $(GZIP_ENV) $(distdir).tar -c >$(distdir).tar.gz
 	$(am__post_remove_distdir)
 
 ?BZIP2?DIST_ARCHIVES += $(distdir).tar.bz2
 .PHONY: dist-bzip2
 dist-bzip2: distdir
-	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	tardir=$(distdir) && $(am__tar) > $(distdir).tar 2>$(distdir).err
+	test ! -s $(distdir).err || (cat $(distdir).err && \
+		rm -rf $(DIST_ARCHIVES) $(distdir).tar $(distdir).err && \
+		$(am__post_remove_distdir) && \
+		exit 1)
+	BZIP2=$${BZIP2--9} bzip2 -c $(distdir).tar >$(distdir).tar.bz2
 	$(am__post_remove_distdir)
 
 ?LZIP?DIST_ARCHIVES += $(distdir).tar.lz
 .PHONY: dist-lzip
 dist-lzip: distdir
-	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	tardir=$(distdir) && $(am__tar) > $(distdir).tar 2>$(distdir).err
+	test ! -s $(distdir).err || (cat $(distdir).err && \
+		rm -rf $(DIST_ARCHIVES) $(distdir).tar $(distdir).err && \
+		$(am__post_remove_distdir) && \
+		exit 1)
+	lzip -c $${LZIP_OPT--9} $(distdir).tar >$(distdir).tar.lz
 	$(am__post_remove_distdir)
 
 ?XZ?DIST_ARCHIVES += $(distdir).tar.xz
 .PHONY: dist-xz
 dist-xz: distdir
-	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	tardir=$(distdir) && $(am__tar) > $(distdir).tar 2>$(distdir).err
+	test ! -s $(distdir).err || (cat $(distdir).err && \
+		rm -rf $(DIST_ARCHIVES) $(distdir).tar $(distdir).err && \
+		$(am__post_remove_distdir) && \
+		exit 1)
+	XZ_OPT=$${XZ_OPT--e} xz -c $(distdir).tar >$(distdir).tar.xz
 	$(am__post_remove_distdir)
 
 ?ZSTD?DIST_ARCHIVES += $(distdir).tar.zst
 .PHONY: dist-zstd
 dist-zstd: distdir
-	tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+	tardir=$(distdir) && $(am__tar) > $(distdir).tar 2>$(distdir).err
+	test ! -s $(distdir).err || (cat $(distdir).err && \
+		rm -rf $(DIST_ARCHIVES) $(distdir).tar $(distdir).err && \
+		$(am__post_remove_distdir) && \
+		exit 1)
+	zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} $(distdir).tar >$(distdir).tar.zst
 	$(am__post_remove_distdir)
 
 ?COMPRESS?DIST_ARCHIVES += $(distdir).tar.Z
@@ -367,7 +392,12 @@ dist-tarZ: distdir
 	@echo WARNING: "Support for distribution archives compressed with" \
 		       "legacy program 'compress' is deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
-	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	tardir=$(distdir) && $(am__tar) > $(distdir).tar 2>$(distdir).err
+	test ! -s $(distdir).err || (cat $(distdir).err && \
+		rm -rf $(DIST_ARCHIVES) $(distdir).tar $(distdir).err && \
+		$(am__post_remove_distdir) && \
+		exit 1)
+	compress -c $(distdir).tar >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 ?SHAR?DIST_ARCHIVES += $(distdir).shar.gz
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index d82cf9c4d..8f8e08885 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -1210,6 +1210,7 @@ t/tar-pax.sh \
 t/tar-opts-errors.sh \
 t/tar-ustar-id-too-high.sh \
 t/tar-override.sh \
+t/tar-split-cmd.sh \
 t/target-cflags.sh \
 t/targetclash.sh \
 t/tests-environment-fd-redirect.sh \
diff --git a/t/tar-split-cmd.sh b/t/tar-split-cmd.sh
new file mode 100644
index 000000000..f3a43c811
--- /dev/null
+++ b/t/tar-split-cmd.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+# Copyright (C) 2004-2022 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# Check if failing 'tar' is not silenced and fails the build.
+
+. test-init.sh
+
+ver=1.0
+
+cat > configure.ac <<ENDCONF
+AC_INIT([$me], [$ver])
+AM_INIT_AUTOMAKE()
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+ENDCONF
+
+fname=miss-obj01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+touch $fname
+#ls -l # debug
+
+cat > Makefile.am <<ENDMAKE
+EXTRA_DIST=$fname
+ENDMAKE
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+./configure
+
+rm -f $me-$ver.tar*
+
+# expected to fail:
+$MAKE dist-gzip 2>&1 || true
+#ls -l # debug
+test ! -e $me-$ver.tar.gz || exit 1
+
+$MAKE dist-bzip2 2>&1 || true
+test ! -e $me-$ver.tar.bz2 || exit 2
+
+$MAKE dist-lzip 2>&1 || true
+test ! -e $me-$ver.tar.lz || exit 3
+
+$MAKE dist-xz 2>&1 || true
+test ! -e $me-$ver.tar.xz || exit 4
+
+$MAKE dist-zstd 2>&1 || true
+test ! -e $me-$ver.tar.zst || exit 5
+
+:
-- 
2.35.1