kumquat-buildroot/support/download/helpers
Clayton Shotwell 6e40891a66 support/download/helpers: adjust for older coreutils versions
The -z option for head was only added in coreutils 8.25, but some older
enterprise-grade distributions (e.g. the oldest still maintained RHEL 7)
only have nothing more recent than coreutils 8.22.

We fix that by using sed to remove everything that starts with the first
NULL byte, \x00.

Signed-off-by: Clayton Shotwell <clayton.shotwell@collins.com>
[yann.morin.1998@free.fr: hex is \xHH, not \xH, reword commit log]
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2022-02-11 17:25:24 +01:00

99 lines
2.9 KiB
Bash
Executable File

# 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 :
# - the timestamp is internally rounded to the highest entire second
# less than or equal to the timestamp (i.e. any sub-second fractional
# part is ignored)
# - 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
# Drop sub-second precision to play nice with GNU tar's valid_timespec check
date="$(date -d "${date}" -u +%Y-%m-%dT%H:%M:%S+00:00)"
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}/#S" \
--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
}
post_process_unpack() {
local dest="${1}"
local tarball="${2}"
local one_file
mkdir "${dest}"
tar -C "${dest}" --strip-components=1 -xzf "${tarball}"
one_file="$(find "${dest}" -type f -print0 |LC_ALL=C sort -z |sed 's/\x0.*//')"
touch -r "${one_file}" "${dest}.timestamp"
}
post_process_repack() {
local in_dir="${1}"
local base_dir="${2}"
local out="${3}"
local date
date="@$(stat -c '%Y' "${in_dir}/${base_dir}.timestamp")"
mk_tar_gz "${in_dir}/${base_dir}" "${base_dir}" "${date}" "${out}"
}
# Keep this line and the following as last lines in this file.
# vim: ft=bash