|
@@ -0,0 +1,70 @@
|
|
|
|
+# Generate a reproducible archive from the content of a directory
|
|
|
|
+#
|
|
|
|
+# $1 : input directory
|
|
|
|
+# $2 : leading component in archive
|
|
|
|
+# $3 : ISO8601 date: YYYY-MM-DDThh:mm:ssZZ
|
|
|
|
+# $4 : output file
|
|
|
|
+# $5... : globs of filenames to exclude from the archive, suitable for
|
|
|
|
+# find's -path option, and relative to the input directory $1
|
|
|
|
+#
|
|
|
|
+# Notes :
|
|
|
|
+# - must not be called with CWD as, or below, the input directory
|
|
|
|
+# - some temporary files are created in CWD, and removed at the end
|
|
|
|
+#
|
|
|
|
+# Example:
|
|
|
|
+# $ find /path/to/temp/dir
|
|
|
|
+# /path/to/temp/dir/
|
|
|
|
+# /path/to/temp/dir/some-file
|
|
|
|
+# /path/to/temp/dir/some-dir/
|
|
|
|
+# /path/to/temp/dir/some-dir/some-other-file
|
|
|
|
+#
|
|
|
|
+# $ mk_tar_gz /path/to/some/dir \
|
|
|
|
+# foo_bar-1.2.3 \
|
|
|
|
+# 1970-01-01T00:00:00Z \
|
|
|
|
+# /path/to/foo.tar.gz \
|
|
|
|
+# '.git/*' '.svn/*'
|
|
|
|
+#
|
|
|
|
+# $ tar tzf /path/to/foo.tar.gz
|
|
|
|
+# foo_bar-1.2.3/some-file
|
|
|
|
+# foo_bar-1.2.3/some-dir/some-other-file
|
|
|
|
+#
|
|
|
|
+mk_tar_gz() {
|
|
|
|
+ local in_dir="${1}"
|
|
|
|
+ local base_dir="${2}"
|
|
|
|
+ local date="${3}"
|
|
|
|
+ local out="${4}"
|
|
|
|
+ shift 4
|
|
|
|
+ local glob tmp pax_options
|
|
|
|
+ local -a find_opts
|
|
|
|
+
|
|
|
|
+ for glob; do
|
|
|
|
+ find_opts+=( -or -path "./${glob#./}" )
|
|
|
|
+ done
|
|
|
|
+
|
|
|
|
+ pax_options="delete=atime,delete=ctime,delete=mtime"
|
|
|
|
+ pax_options+=",exthdr.name=%d/PaxHeaders/%f,exthdr.mtime={${date}}"
|
|
|
|
+
|
|
|
|
+ tmp="$(mktemp --tmpdir="$(pwd)")"
|
|
|
|
+ pushd "${in_dir}" >/dev/null
|
|
|
|
+
|
|
|
|
+ # Establish list
|
|
|
|
+ find . -not -type d -and -not \( -false "${find_opts[@]}" \) >"${tmp}.list"
|
|
|
|
+ # Sort list for reproducibility
|
|
|
|
+ LC_ALL=C sort <"${tmp}.list" >"${tmp}.sorted"
|
|
|
|
+
|
|
|
|
+ # Create POSIX tarballs, since that's the format the most reproducible
|
|
|
|
+ tar cf - --transform="s#^\./#${base_dir}/#" \
|
|
|
|
+ --numeric-owner --owner=0 --group=0 --mtime="${date}" \
|
|
|
|
+ --format=posix --pax-option="${pax_options}" \
|
|
|
|
+ -T "${tmp}.sorted" >"${tmp}.tar"
|
|
|
|
+
|
|
|
|
+ # Compress the archive
|
|
|
|
+ gzip -6 -n <"${tmp}.tar" >"${out}"
|
|
|
|
+
|
|
|
|
+ rm -f "${tmp}"{.list,.sorted,.tar}
|
|
|
|
+
|
|
|
|
+ popd >/dev/null
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# Keep this line and the following as last lines in this file.
|
|
|
|
+# vim: ft=bash
|