add tools to compare entry's manifest with its files

Added `bin/bin/tar-entry.sh` to build a compressed tarball for an
entry.  The compressed tarball is formed by gnu tar with options
so that the same entry file content will always produce the same
compressed tarball, byte for byte.

As some files are missing from some entries, one should
use the `-W` option as in:

```sh
bin/tar-entry.sh -v 5 -W 2020/ferguson1
```

Added `make form_entry_tarball` to the top level `Makefile`
to build entry tarballs even when files are still missing.

Added `make verify_entry_files` to verify that all entries have all
of their files listed in their manifest, plus the top level ioccc.css
and var.mk files.  As file entry files are still missing (due to
HTML files that need to be built), the overall `make quick_www` and
`make www` do **NOT** (yet) exit when the `make verify_entry_files`
fails.

Improved `bin/chk-entry.sh` by removing some variables
that were not needed.

TODO: Improve `bin/` tool exit codes as the current use is a bit silly.

TODO: Clean out some variables used in `bin/` tools as some of then
are only set printed in debug statements.

TODO: Clean up usage messages, some of the options listed to not
match the `getopts(1)` parsing.  In some cases the option needs to
be parsed but needs to be ignored by the tool because another tool
automatically passes along certain options that really have no
effect.  Such ignored options need to be show as "This option is
ignored" in the usage message.
This commit is contained in:
Landon Curt Noll committed 2024-02-13 03:29:54 -08:00
1 parent dd36a407ad
commit ecabb73bf6
325 files changed
+748 -19

No files matched your search

+690
View File
@@ -0,0 +1,690 @@
#!/usr/bin/env bash
#
# tar-entry.sh - tar files belonging to an entry
#
# Copyright (c) 2024 by Landon Curt Noll. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright, this permission notice and text
# this comment, and the disclaimer below appear in all of the following:
#
# supporting documentation
# source copies
# source works derived from this source
# binaries derived from this source or from derived source
#
# LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
# EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
#
# Share and enjoy! :-)
# firewall - must be bash with a version 4.2 or later
#
# We must declare arrays with -ag or -Ag, and we need loops to "export" modified variables.
#
if [[ -z ${BASH_VERSINFO[0]} || ${BASH_VERSINFO[0]} -lt 4 || ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 2 ]]; then
echo "$0: ERROR: bash version must be >= 4.2: $BASH_VERSION" 1>&2
exit 4
fi
# setup bash file matching
#
# Requires bash with a version 4.2 or later
#
shopt -s nullglob # enable expanded to nothing rather than remaining unexpanded
shopt -u failglob # disable error message if no matches are found
shopt -u dotglob # disable matching files starting with .
shopt -s globskipdots # enable never matching . or ..
shopt -u nocaseglob # disable strict case matching
shopt -u extglob # enable extended globbing patterns
shopt -s globstar # enable ** to match all files and zero or more directories and subdirectories
# set variables referenced in the usage message
#
export VERSION="1.0 2024-02-13"
NAME=$(basename "$0")
export NAME
export V_FLAG=0
GIT_TOOL=$(type -P git)
export GIT_TOOL
if [[ -z "$GIT_TOOL" ]]; then
echo "$0: FATAL: git tool is not installed or not in \$PATH" 1>&2
exit 210
fi
"$GIT_TOOL" rev-parse --is-inside-work-tree >/dev/null 2>&1
status="$?"
if [[ $status -eq 0 ]]; then
TOPDIR=$("$GIT_TOOL" rev-parse --show-toplevel)
fi
export TOPDIR
export REPO_URL="https://github.com/ioccc-src/temp-test-ioccc"
export CAP_W_FLAG_FOUND=
GTAR_TOOL=$(type -P gtar)
export GTAR_TOOL
if [[ -z "$GIT_TOOL" ]]; then
echo "$0: FATAL: gtar (gnu tar) tool is not installed or not in \$PATH" 1>&2
exit 9
fi
# set usage message
#
export USAGE="usage: $0 [-h] [-v level] [-V] [-d topdir] [-D docroot/] [-n] [-N]
[-p tool] [-u repo_url] [-w site_url] [-W]
YYYY/dir
-h print help message and exit
-v level set verbosity level (def level: 0)
-V print version string and exit
-d topdir set topdir (def: $TOPDIR)
-D docroot/ This option is ignored
-n go thru the actions, but do not update any files (def: do the action)
-N do not process file, just parse arguments and ignore the file (def: process the file)
-p tool This option is ignored
-u repo_url This option is ignored
-w site_url This option is ignored
-W Warn if a file in the manifest is missing: (def: error if a file is missing)
YYYY/dir path from topdir to entry directory: must contain the files: README.md, .path and .entry.json
Exit codes:
0 all OK
1 some file in the .entry.json manifest is missing and -W was not used or no files were found
2 -h and help string printed or -V and version string printed
3 command line error
4 bash version is < 4.2
5 YYYY/dir is not a entry directory
6 bin/filelist.entry.json.awk is not a non-empty readable file
7 error in trying to determine files used by the entry
8 missing critical top level file
9 gnu tar is missing or execution failed
>= 10 < 210 ((not used))
>= 210 internal tool error
$NAME version: $VERSION"
# setup
#
export NOOP=
export DO_NOT_PROCESS=
export EXIT_CODE="0"
# parse command line
#
while getopts :hv:Vd:D:nNp:u:U:w:W flag; do
case "$flag" in
h) echo "$USAGE" 1>&2
exit 2
;;
v) V_FLAG="$OPTARG"
;;
V) echo "$VERSION"
exit 2
;;
d) TOPDIR="$OPTARG"
;;
D) ;;
n) NOOP="-n"
;;
N) DO_NOT_PROCESS="-N"
;;
p) ;;
u) ;;
U) ;;
w) ;;
W) CAP_W_FLAG_FOUND="true"
;;
\?) echo "$0: ERROR: invalid option: -$OPTARG" 1>&2
echo 1>&2
print_usage 1>&2
exit 3
;;
:) echo "$0: ERROR: option -$OPTARG requires an argument" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 3
;;
*) echo "$0: ERROR: unexpected value from getopts: $flag" 1>&2
echo 1>&2
echo "$USAGE" 1>&2
exit 3
;;
esac
done
# parse the command line arguments
#
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: debug level: $V_FLAG" 1>&2
fi
#
shift $(( OPTIND - 1 ));
#
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: file argument count: $#" 1>&2
fi
if [[ $# -ne 1 ]]; then
echo "$0: ERROR: expected 1 arg, found: $#" 1>&2
exit 3
fi
#
export ENTRY_PATH="$1"
# verify that we have a topdir directory
#
REPO_NAME=$(basename "$REPO_URL")
export REPO_NAME
if [[ -z $TOPDIR ]]; then
echo "$0: ERROR: cannot find top of git repo directory" 1>&2
echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_URL; cd $REPO_NAME" 1>&2
exit 220
fi
if [[ ! -e $TOPDIR ]]; then
echo "$0: ERROR: TOPDIR does not exist: $TOPDIR" 1>&2
echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_URL; cd $REPO_NAME" 1>&2
exit 221
fi
if [[ ! -d $TOPDIR ]]; then
echo "$0: ERROR: TOPDIR is not a directory: $TOPDIR" 1>&2
echo "$0: Notice: if needed: $GIT_TOOL clone $REPO_URL; cd $REPO_NAME" 1>&2
exit 222
fi
# verify that we have an bin subdirectory
#
export BIN_PATH="$TOPDIR/bin"
if [[ ! -d $BIN_PATH ]]; then
echo "$0: ERROR: bin is not a directory under topdir: $BIN_PATH" 1>&2
exit 223
fi
export BIN_DIR="bin"
# cd to topdir
#
if [[ ! -e $TOPDIR ]]; then
echo "$0: ERROR: cannot cd to non-existent path: $TOPDIR" 1>&2
exit 224
fi
if [[ ! -d $TOPDIR ]]; then
echo "$0: ERROR: cannot cd to a non-directory: $TOPDIR" 1>&2
exit 225
fi
export CD_FAILED
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: about to: cd $TOPDIR" 1>&2
fi
cd "$TOPDIR" || CD_FAILED="true"
if [[ -n $CD_FAILED ]]; then
echo "$0: ERROR: cd $TOPDIR failed" 1>&2
exit 226
fi
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: now in directory: $(/bin/pwd)" 1>&2
fi
# verify that ENTRY_PATH is a entry directory
#
# ENTRY_PATH must be in YYYY/dir form
# YYYY must be a directory
# YYYY must be a writable directory
# YYYY/.year must be a non-empty file
# YYYY/dir must be a directory
# YYYY/dir/.path must be a non-empty file
# ENTRY_PATH must match the contents of YYYY/dir/.path
# YYYY/dir/.entry.json must be a non-empty file
#
if [[ ! -d $ENTRY_PATH ]]; then
echo "$0: ERROR: arg is not a directory: $ENTRY_PATH" 1>&2
exit 5
fi
if [[ ! -w $ENTRY_PATH ]]; then
echo "$0: ERROR: arg is not a writable directory: $ENTRY_PATH" 1>&2
exit 5
fi
export YEAR_DIR=${ENTRY_PATH%%/*}
if [[ -z $YEAR_DIR ]]; then
echo "$0: ERROR: arg not in YYYY/dir form: $ENTRY_PATH" 1>&2
exit 5
fi
export ENTRY_DIR=${ENTRY_PATH#*/}
if [[ -z $ENTRY_DIR ]]; then
echo "$0: ERROR: arg: $ENTRY_PATH not in $YEAR_DIR/dir form: $ENTRY_PATH" 1>&2
exit 5
fi
if [[ $ENTRY_DIR = */* ]]; then
echo "$0: ERROR: dir from arg: $ENTRY_PATH contains a /: $ENTRY_DIR" 1>&2
exit 5
fi
if [[ ! -d $YEAR_DIR ]]; then
echo "$0: ERROR: YYYY from arg: $ENTRY_PATH is not a directory: $YEAR_DIR" 1>&2
exit 5
fi
export ENTRY_ID="${YEAR_DIR}_${ENTRY_DIR}"
# Now that we have moved to topdir, form and verify YYYY_DIR is a writable directory
export YYYY_DIR="$YEAR_DIR/$ENTRY_DIR"
if [[ ! -e $YYYY_DIR ]]; then
echo "$0: ERROR: YYYY/dir from arg: $ENTRY_PATH does not exist: $YYYY_DIR" 1>&2
exit 5
fi
if [[ ! -d $YYYY_DIR ]]; then
echo "$0: ERROR: YYYY/dir from arg: $ENTRY_PATH is not a directory: $YYYY_DIR" 1>&2
exit 5
fi
if [[ ! -w $YYYY_DIR ]]; then
echo "$0: ERROR: YYYY/dir from arg: $ENTRY_PATH is not a writable directory: $YYYY_DIR" 1>&2
exit 5
fi
export DOT_PATH="$YYYY_DIR/.path"
if [[ ! -s $DOT_PATH ]]; then
echo "$0: ERROR: not a non-empty file: $DOT_PATH" 1>&2
exit 5
fi
DOT_PATH_CONTENT=$(< "$DOT_PATH")
if [[ $ENTRY_PATH != "$DOT_PATH_CONTENT" ]]; then
echo "$0: ERROR: arg: $ENTRY_PATH does not match $DOT_PATH contents: $DOT_PATH_CONTENT" 1>&2
exit 5
fi
export ENTRY_JSON="$YYYY_DIR/.entry.json"
if [[ ! -e $ENTRY_JSON ]]; then
echo "$0: ERROR: .entry.json does not exist: $ENTRY_JSON" 1>&2
exit 5
fi
if [[ ! -f $ENTRY_JSON ]]; then
echo "$0: ERROR: .entry.json is not a file: $ENTRY_JSON" 1>&2
exit 5
fi
if [[ ! -r $ENTRY_JSON ]]; then
echo "$0: ERROR: .entry.json is not a readable file: $ENTRY_JSON" 1>&2
exit 5
fi
# determine the name of our tarball
#
export TARBALL="$YYYY_DIR/$ENTRY_ID.tar.bz2"
# verify we have our awk tool
#
FILELIST_ENTRY_JSON_AWK="$BIN_DIR/filelist.entry.json.awk"
if [[ ! -e $FILELIST_ENTRY_JSON_AWK ]]; then
echo "$0: ERROR: filelist.entry.json.awk does not exist: $FILELIST_ENTRY_JSON_AWK" 1>&2
exit 6
fi
if [[ ! -f $FILELIST_ENTRY_JSON_AWK ]]; then
echo "$0: ERROR: filelist.entry.json.awk is not a file: $FILELIST_ENTRY_JSON_AWK" 1>&2
exit 6
fi
if [[ ! -r $FILELIST_ENTRY_JSON_AWK ]]; then
echo "$0: ERROR: filelist.entry.json.awk is not a readable file: $FILELIST_ENTRY_JSON_AWK" 1>&2
exit 6
fi
if [[ ! -s $FILELIST_ENTRY_JSON_AWK ]]; then
echo "$0: ERROR: filelist.entry.json.awk is not a not a non-empty readable file: $FILELIST_ENTRY_JSON_AWK" 1>&2
exit 6
fi
# verify we have non-empty readable ioccc.css file
#
IOCCC_CSS="ioccc.css"
if [[ ! -e $IOCCC_CSS ]]; then
echo "$0: ERROR: ioccc.css does not exist: $IOCCC_CSS" 1>&2
exit 8
fi
if [[ ! -f $IOCCC_CSS ]]; then
echo "$0: ERROR: ioccc.css is not a file: $IOCCC_CSS" 1>&2
exit 8
fi
if [[ ! -r $IOCCC_CSS ]]; then
echo "$0: ERROR: ioccc.css is not a readable file: $IOCCC_CSS" 1>&2
exit 8
fi
if [[ ! -s $IOCCC_CSS ]]; then
echo "$0: ERROR: ioccc.css is not a not a non-empty readable file: $IOCCC_CSS" 1>&2
exit 8
fi
# verify we have non-empty readable ioccc.css file
#
VAR_MK="var.mk"
if [[ ! -e $VAR_MK ]]; then
echo "$0: ERROR: var.mk does not exist: $VAR_MK" 1>&2
exit 8
fi
if [[ ! -f $VAR_MK ]]; then
echo "$0: ERROR: var.mk is not a file: $VAR_MK" 1>&2
exit 8
fi
if [[ ! -r $VAR_MK ]]; then
echo "$0: ERROR: var.mk is not a readable file: $VAR_MK" 1>&2
exit 8
fi
if [[ ! -s $VAR_MK ]]; then
echo "$0: ERROR: var.mk is not a not a non-empty readable file: $VAR_MK" 1>&2
exit 8
fi
# parameter debugging
#
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: VERSION=$VERSION" 1>&2
echo "$0: debug[3]: NAME=$NAME" 1>&2
echo "$0: debug[3]: V_FLAG=$V_FLAG" 1>&2
echo "$0: debug[3]: GIT_TOOL=$GIT_TOOL" 1>&2
echo "$0: debug[3]: GTAR_TOOL=$GTAR_TOOL" 1>&2
echo "$0: debug[3]: TOPDIR=$TOPDIR" 1>&2
echo "$0: debug[3]: REPO_URL=$REPO_URL" 1>&2
echo "$0: debug[3]: NOOP=$NOOP" 1>&2
echo "$0: debug[3]: DO_NOT_PROCESS=$DO_NOT_PROCESS" 1>&2
echo "$0: debug[3]: CAP_W_FLAG_FOUND=$CAP_W_FLAG_FOUND" 1>&2
echo "$0: debug[3]: ENTRY_PATH=$ENTRY_PATH" 1>&2
echo "$0: debug[3]: EXIT_CODE=$EXIT_CODE" 1>&2
echo "$0: debug[3]: REPO_NAME=$REPO_NAME" 1>&2
echo "$0: debug[3]: BIN_PATH=$BIN_PATH" 1>&2
echo "$0: debug[3]: BIN_DIR=$BIN_DIR" 1>&2
echo "$0: debug[3]: YEAR_DIR=$YEAR_DIR" 1>&2
echo "$0: debug[3]: ENTRY_DIR=$ENTRY_DIR" 1>&2
echo "$0: debug[3]: ENTRY_ID=$ENTRY_ID" 1>&2
echo "$0: debug[3]: DOT_PATH=$DOT_PATH" 1>&2
echo "$0: debug[3]: ENTRY_JSON=$ENTRY_JSON" 1>&2
echo "$0: debug[3]: TARBALL=$TARBALL" 1>&2
echo "$0: debug[3]: FILELIST_ENTRY_JSON_AWK=$FILELIST_ENTRY_JSON_AWK" 1>&2
echo "$0: debug[3]: IOCCC_CSS=$IOCCC_CSS" 1>&2
echo "$0: debug[3]: VAR_MK=$VAR_MK" 1>&2
fi
# If -N, time to exit
#
if [[ -n $DO_NOT_PROCESS ]]; then
if [[ $V_FLAG -ge 1 ]]; then
echo "$0: debug[1]: arguments parsed, -N given, exit 0" 1>&2
fi
exit 0
fi
# create a temporary file manifest list
#
TMP_MANIFEST_LIST=".$NAME.$$.manifest.list"
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: temporary file manifest list: $TMP_MANIFEST_LIST" 1>&2
fi
if [[ -z $NOOP ]]; then
trap 'rm -f $TMP_MANIFEST_LIST; exit' 0 1 2 3 15
rm -f "$TMP_MANIFEST_LIST"
if [[ -e $TMP_MANIFEST_LIST ]]; then
echo "$0: ERROR: cannot remove temporary file manifest list: $TMP_MANIFEST_LIST" 1>&2
exit 227
fi
:> "$TMP_MANIFEST_LIST"
if [[ ! -e $TMP_MANIFEST_LIST ]]; then
echo "$0: ERROR: cannot create temporary file manifest list: $TMP_MANIFEST_LIST" 1>&2
exit 228
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary file manifest list is not used: $TMP_MANIFEST_LIST" 1>&2
fi
# create a temporary sort list of files to tar
#
TMP_TAR_LIST=".$NAME.$$.tar.list"
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: temporary file tar list: $TMP_TAR_LIST" 1>&2
fi
if [[ -z $NOOP ]]; then
trap 'rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST; exit' 0 1 2 3 15
rm -f "$TMP_TAR_LIST"
if [[ -e $TMP_TAR_LIST ]]; then
echo "$0: ERROR: cannot remove temporary file tar list: $TMP_TAR_LIST" 1>&2
exit 231
fi
:> "$TMP_TAR_LIST"
if [[ ! -e $TMP_TAR_LIST ]]; then
echo "$0: ERROR: cannot create temporary file tar list: $TMP_TAR_LIST" 1>&2
exit 232
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary file tar list is not used: $TMP_TAR_LIST" 1>&2
fi
# create a temporary exit code
#
# It is a pain to set the EXIT_CODE deep inside a loop, so we write the EXIT_CODE into a file
# and read the file (setting EXIT_CODE again) after the loop. A hack, but good enough for our needs.
#
TMP_EXIT_CODE=".$NAME.$$.exit.code"
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: temporary exit code: $TMP_EXIT_CODE" 1>&2
fi
if [[ -z $NOOP ]]; then
trap 'rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST $TMP_EXIT_CODE; exit' 0 1 2 3 15
rm -f "$TMP_EXIT_CODE"
if [[ -e $TMP_EXIT_CODE ]]; then
echo "$0: ERROR: cannot remove temporary exit code: $TMP_EXIT_CODE" 1>&2
exit 233
fi
echo "$EXIT_CODE" > "$TMP_EXIT_CODE"
if [[ ! -e $TMP_EXIT_CODE ]]; then
echo "$0: ERROR: cannot create temporary exit code: $TMP_EXIT_CODE" 1>&2
exit 234
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary exit code is not used: $TMP_EXIT_CODE" 1>&2
fi
# create a temporary tarball
#
TMP_TARBALL=".$NAME.$$.tar.bz2"
if [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: temporary tarball: $TMP_TARBALL" 1>&2
fi
if [[ -z $NOOP ]]; then
trap 'rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST $TMP_EXIT_CODE $TMP_TARBALL; exit' 0 1 2 3 15
rm -f "$TMP_TARBALL"
if [[ -e $TMP_TARBALL ]]; then
echo "$0: ERROR: cannot remove temporary tarball: $TMP_TARBALL" 1>&2
exit 231
fi
:> "$TMP_TARBALL"
if [[ ! -e $TMP_TARBALL ]]; then
echo "$0: ERROR: cannot create temporary tarball: $TMP_TARBALL" 1>&2
exit 232
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary tarball is not used: $TMP_TARBALL" 1>&2
fi
# generate sorted list of entry files from the entry's manifest
#
# We also add ioccc.css and var.mk from the top level.
#
if [[ -z $NOOP ]]; then
awk -f "$FILELIST_ENTRY_JSON_AWK" "$ENTRY_JSON" > "$TMP_MANIFEST_LIST"
status="$?"
if [[ $status -ne 0 ]]; then
echo "$0: ERROR: awk -f $FILELIST_ENTRY_JSON_AWK $ENTRY_JSON > $TMP_MANIFEST_LIST failed, error: $status" 1>&2
exit 7
fi
echo "$IOCCC_CSS" >> "$TMP_MANIFEST_LIST"
echo "$VAR_MK" >> "$TMP_MANIFEST_LIST"
sort -d -u "$TMP_MANIFEST_LIST" -o "$TMP_MANIFEST_LIST"
status="$?"
if [[ $status -ne 0 ]]; then
echo "$0: ERROR: sort -d -u $TMP_MANIFEST_LIST -o $TMP_MANIFEST_LIST failed, error: $status" 1>&2
exit 7
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary file manifest list was not formed: $TMP_MANIFEST_LIST" 1>&2
fi
# generate sorted list of found entry files
#
# We exclude the compressed tarball itself because we are writing it.
#
if [[ -z $NOOP ]]; then
# exclude the compressed tarball from the tarlist
#
grep -F -v "$TARBALL" < "$TMP_MANIFEST_LIST" | while read -r file; do
# if file does not exist, warn
#
if [[ ! -e $file ]]; then
echo "$0: Warning: missing $YYYY_DIR file: $file" 1>&2
# unless -W, missing files cause this tool to exit 1
if [[ -z $CAP_W_FLAG_FOUND ]]; then
echo 1 > "$TMP_EXIT_CODE" # exit 1
fi
else
echo "$file"
fi
done > "$TMP_TAR_LIST"
if [[ $V_FLAG -ge 7 ]]; then
echo "$0: debug[7]: list of files to tar start below" 1>&2
cat "$TMP_TAR_LIST" 1>&2
echo "$0: debug[7]: list of files to tar ends above" 1>&2
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, temporary file tar list was not formed: $TMP_MANIFEST_LIST" 1>&2
fi
if [[ ! -s "$TMP_TAR_LIST" ]]; then
echo "$0: ERROR: no files found to tar for: $ENTRY_JSON" 1>&2
exit 1
fi
EXIT_CODE=$(< "$TMP_EXIT_CODE")
if [[ -z $EXIT_CODE ]]; then
echo "$0: ERROR: temporary exit file is empty: $TMP_EXIT_CODE" 1>&2
exit 233
fi
# form the tarball
#
# We use gnu tar to form the bzip2 compressed tarball with careful arguments
# so that the resulting tarball is the same, byte for byte.
#
if [[ -z $NOOP ]]; then
# case: form the tarball verbosely if -v 3 or more
#
if [[ $V_FLAG -gt 3 ]]; then
echo "$0: debug[3]: about to execute:" \
"$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \
"--owner=501 --group=20 --numeric-owner --totals" \
"--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \
"-jcvf $TMP_TARBALL < $TMP_TAR_LIST" 1>&2
"$GTAR_TOOL" --files-from=- --sparse --no-acls --sort=name \
--owner=501 --group=20 --numeric-owner --totals \
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
-jcvf "$TMP_TARBALL" < "$TMP_TAR_LIST"
status="$?"
if [[ $status -ne 0 ]]; then
echo "$0: ERROR:" \
"$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \
"--owner=501 --group=20 --numeric-owner --totals" \
"--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \
"-jcvf $TMP_TARBALL < $TMP_TAR_LIST failed, error: $status" 1>&2
EXIT_CODE=9 # exit 9
fi
# case: form the tarball silently
#
else
"$GTAR_TOOL" --files-from=- --sparse --no-acls --sort=name \
--owner=501 --group=20 --numeric-owner \
--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
-jcf "$TMP_TARBALL" < "$TMP_TAR_LIST"
status="$?"
if [[ $status -ne 0 ]]; then
echo "$0: ERROR:" \
"$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \
"--owner=501 --group=20 --numeric-owner" \
"--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \
"-jcf $TMP_TARBALL < $TMP_TAR_LIST failed, error: $status" 1>&2
EXIT_CODE=9 # exit 9
fi
fi
# verify the tarball is not empty
#
if [[ ! -s $TMP_TARBALL ]]; then
echo "$0: ERROR: tarball is missing os empty: $TMP_TARBALL" 1>&2
EXIT_CODE=9 # exit 9
fi
# case: -n
#
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, did not execute:" \
"$GTAR_TOOL --files-from=- --sparse --no-acls --sort=name" \
"--owner=501 --group=20 --numeric-owner --totals" \
"--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime" \
"-jcvf $TMP_TARBALL < $TMP_TAR_LIST" 1>&2
fi
EXIT_CODE=$(< "$TMP_EXIT_CODE")
if [[ -z $EXIT_CODE ]]; then
echo "$0: ERROR: temporary exit file has no contents: $TMP_EXIT_CODE" 1>&2
exit 234
fi
# move the tarball in place onlt if differnt
#
if [[ -z $NOOP ]]; then
if cmp -s "$TMP_TARBALL" "$TARBALL"; then
# case: tarball did not change
#
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: file did not change: $TARBALL" 1>&2
fi
else
# case: tarball changed, update the file
#
if [[ $V_FLAG -ge 5 ]]; then
echo "$0: debug[5]: mv -f -- $TMP_TARBALL $TARBALL" 1>&2
fi
if [[ $V_FLAG -ge 3 ]]; then
mv -f -v -- "$TMP_TARBALL" "$TARBALL"
status="$?"
else
mv -f -- "$TMP_TARBALL" "$TARBALL"
status="$?"
fi
if [[ status -ne 0 ]]; then
echo "$0: ERROR: mv -f -- $TMP_TARBALL $TARBALL filed, error code: $status" 1>&2
EXIT_CODE=9 # exit 9
elif [[ $V_FLAG -ge 1 ]]; then
echo "$0: debug[1]: built replaced HTML file: $TARBALL" 1>&2
fi
if [[ ! -s $TARBALL ]]; then
echo "$0: ERROR: not a non-empty index HTML file: $TARBALL" 1>&2
EXIT_CODE=9 # exit 9
fi
fi
elif [[ $V_FLAG -ge 3 ]]; then
echo "$0: debug[3]: because of -n, tarball was not touched: $TARBALL" 1>&2
fi
EXIT_CODE=$(< "$TMP_EXIT_CODE")
if [[ -z $EXIT_CODE ]]; then
echo "$0: ERROR: temporary exit file has no contents: $TMP_EXIT_CODE" 1>&2
exit 234
fi
# All Done!!! -- Jessica Noll, Age 2
#
if [[ -z $NOOP ]]; then
rm -f "$TMP_MANIFEST_LIST" "$TMP_TAR_LIST" "$TMP_EXIT_CODE" "$TMP_TARBALL"
elif [[ $V_FLAG -ge 1 ]]; then
echo "$0: debug[1]: -n disabled execution of: rm -f $TMP_MANIFEST_LIST $TMP_TAR_LIST $TMP_EXIT_CODE $TMP_TARBALL" 1>&2
fi
exit "$EXIT_CODE"