Add rewritten gen-repo-metadata.

This commit is contained in:
Darren 'Tadgy' Austin 2022-10-05 21:46:36 +01:00
commit 0a4eb22bcb

545
gen-repo-metadata Executable file
View file

@ -0,0 +1,545 @@
#!/bin/bash
# shellcheck disable=SC2015,SC2059
VERSION="0.3.2"
# Copyright (c) 2005-2022:
# Darren 'Tadgy' Austin <darren (at) afterdark.org.uk>
# Licensed under the terms of the GNU General Public License version 3.
# Configuration.
REPO_ROOT="${REPO_ROOT:-/data/slackware/repo}"
REPO_PACKAGE_DIRS=( "$REPO_ROOT"/slackware* )
GPG_KEY="${GPG_KEY:-Darren 'Tadgy' Austin <darren@slackware.uk>}"
# Defaults
FORCE=0
NO_CL=0
NO_MD5=0
NO_SIGN=0
LOCKFILE=".${0##*/}.lock"
# Timestamp to be used in ChangeLog.txt and a few other files.
NOW="$(date --utc)"
# Extra shell features.
shopt -s extglob globstar nullglob
set -o pipefail
die() {
# $* = Error message output before exiting.
printf "\\033[1;31;40m%s\\033[0;39m\\n" "${*:-abort}." >&2
exit 1
}
display_version() {
# |........1.........2.........3.........4.........5.........6.........7.........8
cat <<-EOF
${0##*/} v$VERSION.
Copyright (c) 2005-2022 Darren 'Tadgy' Austin <darren (at) afterdark.org.uk>.
Licensed under the terms of the GNU GPL v3 <http://gnu.org/licenses/gpl.html>.
This program is free software; you can modify or redistribute it in accordence
with the GNU GPL. However, it comes with ABSOLUTELY NO WARRANTY; not even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF
}
display_help() {
# |........1.........2.........3.........4.........5.........6.........7.........8
cat <<-EOF
Usage: ${0##*/} [options] [directory] [...]
Generate slapt-get compatible meta-files for a Slackware package repository.
Options (all of which are optional):
-b, --blurb When generating the ChangeLog.txt, prompt for the blurb
to appear above the individual package log entries, and
for every ChangeLog.txt entry.
-f, --force Force rebuild of metdata for all packages.
-h, --help This help text.
-nc, --no-changelog No ChangeLog.txt updates.
-nm, --no-md5 No .md5sums checksum cache generation for packages.
Without checksum cache files, creation of the repository
CHECKSUMS.md5 file will md5sum every file every time.
-ns, --no-sign No .asc GPG signature generation for packages, or
generation of the final CHECKSUMS.md5.asc file.
-v, --version Display the version and copyright information.
-- Cease option processing and begin argument parsing.
Option processing ceases with the first non-option argument or --.
Arguments (all of which are optional):
[directory] [...] Only process the (space delimited) list of directories
given on the command line.
EOF
}
gen_changelog() {
local CUR_X CUR_Y ENTRY JUNK LINES ORIG_X ORIG_Y TEXT
{ [[ -s ".ChangeLog.stub" ]] && {
printf "%s\\n" "$NOW" >&20
# Read and add header blurb.
(( BLURB == 1 )) && {
# Do some terminal trickery to recover the space used.
printf "\\033[6n"
IFS='[;' read -r -s -d R JUNK ORIG_Y ORIG_X
printf "\\033[1;31;40m%s:\\033[0;39m\\n" "Enter the (optional) ChangeLog.txt header blurb - finish with Ctl+D"
IFS= read -r -d$'\004' TEXT
LINES="$(wc -l <<<"$TEXT")"
# More terminal trickery.
printf "\\033[6n"
IFS='[;' read -r -s -d R JUNK CUR_Y CUR_X
printf "\\033[$(( CUR_Y - LINES ));${ORIG_X}f\\033[J"
# Output the header to the log.
[[ -n "$TEXT" ]] && printf "%s\\n" "$(fmt -s -u -w 78 <<<"$TEXT")" >&20
}
# Process each package that is in the stub file.
while read -r -u 21 ENTRY; do
(( BLURB == 1 )) && {
printf "\\033[6n"
# shellcheck disable=SC2034
IFS='[;' read -r -s -d R JUNK ORIG_Y ORIG_X
printf "\\033[1;33;40m%s: %s\\n" "ChangeLog.txt entry" "$ENTRY"
printf "\\033[1;31;40m%s:\\n" "Enter the (optional) blurb for the above ChangeLog.txt entry - finish with Ctl+D"
printf "%s\\033[0;39m\\n" "(Text will be re-formatted, wraped to 78 chars and indented automatically)"
IFS= read -r -d$'\004' TEXT
LINES="$(( $(wc -l <<<"$TEXT") + 2 ))"
printf "\\033[6n"
# shellcheck disable=SC2034
IFS='[;' read -r -s -d R JUNK CUR_Y CUR_X
printf "\\033[$(( CUR_Y - LINES ));${ORIG_X}f\\033[J"
}
# Output to the log.
printf "%s\\n" "$ENTRY" >&20
[[ -n "$TEXT" ]] && printf "%s\\n" "$(fmt -s -u -w 76 <<<"$TEXT" | sed -re 's/^/ /g')" >&20
done 21<.ChangeLog.stub
# If there's a previous changelog, append it to the end of the new one.
[[ -e ChangeLog.txt ]] && printf "+--------------------------+\\n" >&20
}
[[ -e ChangeLog.txt ]] && cat ChangeLog.txt >&20
} 20>.ChangeLog.staged
rm -f .ChangeLog.stub
return 0
}
gen_checksums() {
local FILE
# shellcheck disable=SC2094
{ cat <<-EOF
These are the MD5 message digests for the files in this directory.
If you want to test your files, use 'md5sum' and compare the values to
the ones listed here.
To test all these files, use this command:
tail +13 CHECKSUMS.md5 | md5sum -c --quiet - | less
'md5sum' can be found in the GNU coreutils package on ftp.gnu.org in
/pub/gnu, or at any GNU mirror site.
MD5 message digest Filename
EOF
if (( NO_MD5 == 0 )); then
# Create from the .md5sums files if possible, otherwise sum individually.
for FILE in **/!(*.asc|*.manifest|*.md5sums|*-*-*-*.txt|CHECKSUMS.md5); do
if [[ "$FILE" == *.t?z ]]; then
if [[ -e "${FILE%.t?z}.md5sums" ]]; then
# Just cat the .md5sums file.
cat "${FILE%.t?z}.md5sums"
else
# No .md5sums file - sum the relevant files.
if [[ -e "$FILE.asc" ]]; then
md5sum "$FILE" "$FILE.asc" "${FILE%.t?z}.txt" 2>/dev/null || return 1
else
md5sum "$FILE" "${FILE%.t?z}.txt" 2>/dev/null || return 1
fi
fi
else
# md5sum the file.
[[ -f "$FILE" ]] && { md5sum "$FILE" || return 1; }
fi
done
else
# Ignore the .md5sums files and sum everything.
find . \( ! -type f -o -path '*/.*' -o -name '*.manifest' -o -name '*.md5sums' -a -prune \) -o -printf "%P\\n" | sort | xargs md5sum || return 1
fi
} >CHECKSUMS.md5
return 0
}
gen_filelist() {
{ printf "%s\\n\\n" "$NOW"
printf "%s\\n" "Here is the file list for this directory. If you are using a"
printf "%s\\n" "mirror site and find missing or extra files in the disk"
printf "%s\\n" "subdirectories, please have the archive administrator refresh"
printf "%s\\n\\n" "the mirror."
# Trying to use the output of ls is always a bad idea, but there's little choice here....
find . \( -path '*/.*' -o -name '*.manifest' -o -name '*.md5sums' -a -prune \) -o -print | sort | xargs ls -1bld --time-style=long-iso | \
sed -re 's/([^[:space:]]+[[:space:]]+[[:digit:]]+[[:space:]]+)[^[:space:]]+([[:space:]]+)[^[:space:]]+(.*)/\1root\2root\3/g' || return 1
} >FILELIST.TXT
return 0
}
gen_manifest() {
local FILE
# Create from the .manifest cache files if possible, otherwise create inline.
{ for FILE in **/*-*-*-*.t?z; do
printf "++========================================\\n||\\n"
printf "|| Package: ./%s\\n" "$FILE"
printf "||\\n++========================================\\n"
if [[ -e "${FILE%.t?z}.manifest" ]]; then
# Include the .manifest file.
cat "${FILE%.t?z}.manifest" 2>/dev/null || return 1
else
# No .manifest file.
tar -vvtf "$FILE" 2>/dev/null || return 1
fi
printf "\\n\\n"
done
} | bzip2 -c9 >MANIFEST.bz2 2>/dev/null || return 1
return 0
}
gen_packages() {
{ printf "%s; %s\\n\\n" "PACKAGES.TXT" "$NOW"
printf "%s\\n%s\\n\\n" "This file provides details on the Slackware packages found" "in this directory."
# shellcheck disable=SC2046
printf "%s: %s MB\\n" "Total size of all packages (compressed)" "$(numfmt --from=iec --to-unit=1048576 "$(( \
($(awk -F' ' -e '/^PACKAGE SIZE \(compressed\)/ { print $4 " + "}' $(find . -type f -name '*-*-*-*.txt'; printf "/dev/null"))0) * 1024 ))")"
# shellcheck disable=SC2046
printf "%s: %s MB\\n\\n\\n" "Total size of all packages (uncompressed)" "$(numfmt --from=iec --to-unit=1048576 "$(( \
($(awk -F' ' -e '/^PACKAGE SIZE \(uncompressed\)/ { print $4 " + "}' $(find . -type f -name '*-*-*-*.txt'; printf "/dev/null"))0) * 1024 ))")"
for TXT in **/*-*-*-*.txt; do
cat "$TXT" || return 1
printf "\\n"
done
} >PACKAGES.TXT
return 0
}
gen_pkg_changelog() {
# $1 = Package file to process [required].
local CACHE=() CACHED_ARCH CACHED_BUILD CACHED_DIR CACHED_EXT CACHED_TAG CACHED_VER
local I J PKG_ARCH PKG_BUILD PKG_DIR PKG_EXT PKG_NAME PKG_TAG PKG_VER TMP
[[ -z "$1" ]] || [[ ! -e "$1" ]] && die "abort: ${FUNCNAME[0]} ($LINENO)"
# Get the new package details.
PKG_DIR="${1%/*}"; [[ "$PKG_DIR" == "$1" ]] && PKG_DIR=""
PKG_NAME="$(printf "$1" | rev | cut -d- -f4- | cut -d/ -f1 | rev)"
PKG_VER="$(printf "$1" | rev | cut -d- -f3 | rev)"
PKG_ARCH="$(printf "$1" | rev | cut -d- -f2 | rev)"
TMP="$(printf "$1" | rev | cut -d- -f1 | rev)"
PKG_BUILD="${TMP%%[^[:digit:]]*}"
TMP="${TMP/#+([[:digit:]])}"
PKG_TAG="${TMP%.t?z}"
PKG_EXT="${TMP##*.}"
unset TMP
# Read the cache file.
[[ -e ".versions.cache" ]] && { mapfile -t CACHE <.versions.cache || die "Failed to read .versions.cache"; }
# Find the package details in the array.
for ((I = 0; I < ${#CACHE[*]}; I++)); do
IFS=';' read -r CACHED_DIR CACHED_NAME CACHED_VER CACHED_ARCH CACHED_BUILD CACHED_TAG CACHED_EXT <<<"${CACHE[I]}"
[[ "$CACHED_NAME" == "$PKG_NAME" ]] && break
done
{ # If there's no CACHED_VER set, then there's either no cache or the package isn't in it.
# Either way, just mark the package as added.
if [[ -z "$CACHED_VER" ]]; then
printf "%s: %s.\\n" "$1" "Added"
elif [[ "$PKG_DIR" != "$CACHED_DIR" ]] || [[ "$PKG_EXT" != "$CACHED_EXT" ]]; then
# Package has changed directory or extension - mark new one as added; the other as removed.
printf "%s: %s.\\n" "$1" "Added"
printf "%s: %s.\\n" "${CACHED_DIR:+$CACHED_DIR/}$PKG_NAME-$CACHED_VER-$CACHED_ARCH-$CACHED_BUILD$CACHED_TAG.$CACHED_EXT" "Removed"
elif [[ "$PKG_VER" != "$CACHED_VER" ]]; then
# Versions are different, no need to do more than mark as upgraded.
printf "%s: %s.\\n" "$1" "Upgraded"
else
# Versions are the same, check the build details.
if [[ "$PKG_TAG" != "$CACHED_TAG" ]]; then
# Different build tag, no need to test the build number.
# Mark the new package as added; the old one as removed.
printf "%s: %s.\\n" "$1" "Added"
printf "%s: %s.\\n" "${CACHED_DIR:+$CACHED_DIR/}$PKG_NAME-$CACHED_VER-$CACHED_ARCH-$CACHED_BUILD$CACHED_TAG.$CACHED_EXT" "Removed"
elif (( PKG_BUILD != CACHED_BUILD )); then
# If the build numbers differ, just mark a rebuild.
printf "%s: %s.\\n" "$1" "Rebuilt"
fi
fi
} | sort >>.ChangeLog.stub
# There may still be old entries for the package in the cache.
for ((J = I; J < ${#CACHE[*]}; J++)); do
[[ "$(printf "${CACHE[J]}" | cut -d: -f2)" == "$PKG_NAME" ]] && unset 'CACHE[J]'
done
# Remove the upgraded/rebuilt package from the cache.
[[ -n "${CACHE[I]}" ]] && unset 'CACHE[I]'
# Finally, add the new package to the cache.
CACHE+="$PKG_DIR;$PKG_NAME;$PKG_VER;$PKG_ARCH;$PKG_BUILD;$PKG_TAG;$PKG_EXT"
# Write the new cache file.
printf "%s\\n" "${CACHE[@]}" | sort -r >.versions.cache
}
gen_pkg_md5sums() {
# $1 = Package file to process [required].
local TXT="${1%.t?z}.txt"
local MD5="${1%.t?z}.md5sums"
[[ -z "$1" ]] || [[ ! -e "$1" ]] && die "abort: ${FUNCNAME[0]} ($LINENO)"
if [[ -e "$1.asc" ]]; then
md5sum "$1" "$1.asc" "$TXT" >"$MD5" || return 1
else
md5sum "$1" "$TXT" >"$MD5" || return 1
fi
return 0
}
gen_pkg_txt() {
# $1 = Package file to process [required].
local TXT="${1%.t?z}.txt"
[[ -z "$1" ]] || [[ ! -e "$1" ]] && die "abort: ${FUNCNAME[0]} ($LINENO)"
{ printf "%s: %s\\n" "PACKAGE NAME" "${1##*/}"
printf "%s: %s\\n" "PACKAGE LOCATION" "./${1%/*}"
printf "%s: %s\\n" "PACKAGE SIZE (compressed)" "$(du -k "$1" | cut -d $'\t' -f 1) K"
printf "%s: %s\\n" "PACKAGE SIZE (uncompressed)" "$(numfmt --to-unit=1024 "$(tar -xOf "$1" | wc -c)") K"
printf "%s: %s\\n" "PACKAGE REQUIRED" "$(tar --occurrence=1 -xOf "$1" install/slack-required 2>/dev/null | tr $'\n' ',' | sed -e 's/,$//')"
printf "%s: %s\\n" "PACKAGE CONFLICTS" "$(tar --occurrence=1 -xOf "$1" install/slack-conflicts 2>/dev/null | tr $'\n' ',' | sed -e 's/,$//')"
printf "%s: %s\\n" "PACKAGE SUGGESTS" "$(tar --occurrence=1 -xOf "$1" install/slack-suggests 2>/dev/null | tr $'\n' ' ' | sed -e 's/ $//')"
printf "%s:\\n" "PACKAGE DESCRIPTION"
tar --occurrence=1 -xOf "$1" install/slack-desc 2>/dev/null
} >"$TXT" || return 1
return 0
}
runtime() {
# $1 = Number of seconds to convert to readable text [required].
[[ -z "$1" ]] && die "abort: ${FUNCNAME[0]} ($LINENO)"
local D=$(( $1 / 86400 ))
local H=$(( ($1 - (D * 86400)) / 3600 ))
local M=$(( ($1 - (D * 86400) - (H * 3600)) / 60 ))
local S=$(( $1 - (D * 86400) - (H * 3600) - (M * 60) ))
if (( D > 0 )); then
printf "%s, %s %s %s" "${D}d" "${H}h" "${M}m" "${S}s"
else
printf "%s, %s %s" "${H}h" "${M}m" "${S}s"
fi
return 0
}
sign_file() {
# $1 = The file to sign [required].
[[ -z "$1" ]] || [[ ! -e "$1" ]] && die "abort: ${FUNCNAME[0]} ($LINENO)"
gpg2 --sign --detach-sign --armor --batch --quiet --local-user "$GPG_KEY" "$1" || return 1
return 0
}
# Parse command line options.
while [[ -n "$1" ]]; do
case "$1" in
-b|-blub|--blurb)
BLURB=1
shift
;;
-f|-force|--force)
FORCE=1
shift
;;
-h|-help|--help)
display_help
exit 0
;;
-nc|-no-changelog|--no-changelog)
NO_CL=1
shift
;;
-nm|-no-md5|--no-md5)
NO_MD5=1
shift
;;
-ns|-no-sign|--no-sign)
NO_SIGN=1
shift
;;
-v|-version|--version)
display_version
exit 0
;;
--)
shift
break
;;
-*)
printf "%s: %s: %s\\n" "${0##*/}" "invalid option" "$1" >&2
printf "Try: %s %s\\n" "${0##*/}" "--help" >&2
exit 1
;;
*)
break
;;
esac
done
# Operate from the top level of the repository.
cd "$REPO_ROOT" || die "Failed to change directory to repo root"
# Any remaining command line arguments are the directories to process.
[[ -n "$*" ]] && REPO_PACKAGE_DIRS=( "$@" ) || REPO_PACKAGE_DIRS=( slackware* )
# Sanity check of REPO_PACKAGE_DIRS.
for ((I = 0; I < ${#REPO_PACKAGE_DIRS[*]}; I++)); do
[[ ! -e "${REPO_PACKAGE_DIRS[I]}" ]] && die "no such package directory: ${REPO_PACKAGE_DIRS[I]}"
done
# Create lockfile.
{ exec {FD}>"$LOCKFILE" && flock -E 10 -e -w 0.5 "$FD"; } || {
if (( $? == 10 )); then
die "Failed to obtain lockfile - another instance is running"
else
die "flock usage error"
fi
}
trap 'exec {FD}<&-; rm -f "$LOCKFILE"' EXIT INT TERM
# Check gpg-agent and unlock key if required.
(( NO_SIGN == 0 )) && {
gpg2 -K "$GPG_KEY" >/dev/null 2>&1
(( $? == 2 )) && die "no key available for ID: $GPG_KEY"
printf "test" | gpg2 --sign -o /dev/null --pinentry-mode error --local-user "$GPG_KEY" >/dev/null 2>&1
(( $? == 2 )) && {
printf "\\033[1;31;40m%s\\033[0;39m\\n" "GPG signing key is locked - passphrase required."
while :; do
printf "test" | gpg2 --sign -o /dev/null --local-user "$GPG_KEY" 2>/dev/null
ERR=$?
(( ERR == 130 )) && die "caught interrupt - aborting"
(( ERR == 2 )) && {
printf "\\033[1;31;40m%s\\033[0;39m" "Incorrect passphrase. Retry? (Y/n): "
read -r -N 1
printf "\\n"
[[ "$REPLY" =~ [Nn] ]] && die "cannot continue without unlocking GPG signing key"
continue
}
(( ERR > 0 )) && die "unknown error -aborting"
break
done
}
}
# Process the package dirs.
for ((I = 0; I < ${#REPO_PACKAGE_DIRS[*]}; I++)); do
cd "${REPO_PACKAGE_DIRS[I]}" >/dev/null 2>&1 || die "abort: $LINENO"
printf "\\033[1;32;40m%s '%s':\\033[0;39m\\n" "Processing repository directory" "${REPO_PACKAGE_DIRS[I]}"
SECONDS=0
# Sanity check: make sure there is not more than one package of each name in the repository.
PKGS=()
for FILE in **/*-*-*-*.t?z; do
PKG_NAME="$(printf "$FILE" | rev | cut -d- -f4- | cut -d/ -f1 | rev)"
PKG_ARCH="${PKG_ARCH:-$(printf "$FILE" | rev | cut -d- -f2 | rev)}"
if printf "%s " "${PKGS[@]}" | grep -E "\<$PKG_NAME\>" >/dev/null 2>&1; then
die "Repository corrupt: more than one package of the same name in repository ($PKG_NAME)"
elif [[ "$PKG_ARCH" != "$(printf "$FILE" | rev | cut -d- -f2 | rev)" ]]; then
die "Repository corrupt: more than one package architecture in repository"
else
PKGS+=("$PKG_NAME")
fi
done
unset FILE PKG_ARCH PKG_NAME PKGS
# Process each package in repository.
for FILE in **/*-*-*-*.t?z; do
printf "\\033[1;33;40m %s: " "$FILE"
if (( FORCE == 1 )) || [[ "$FILE" -nt "$FILE.asc" ]] || [[ "$FILE" -nt "${FILE%.t?z}.txt" ]] || [[ "$FILE" -nt "${FILE%.t?z}.md5sums" ]] || \
[[ "$FILE" -nt "${FILE%.t?z}.manifest" ]] || ! grep -E "\<$(gpg2 --list-packets "$FILE.asc" | awk -e '/:signature packet:/ { print $6 }')\>" \
< <(gpg2 --list-keys --with-colons "$GPG_KEY" | awk -F: -e '/sub/ { if ($11 == "") print $5 }') >/dev/null 2>&1; then
rm -f "$FILE.asc" "${FILE%.t?z}.txt" "${FILE%.t?z}.md5sums"
# GPG signature.
(( NO_SIGN == 0 )) && { sign_file "$FILE" && printf "%s " "signed" || die "signing failed"; }
# .txt file metadata.
gen_pkg_txt "$FILE" && printf "%s " "metadata generated" || die "metadata generation failed"
# md5sums cache.
(( NO_MD5 == 0 )) && { gen_pkg_md5sums "$FILE" && printf "%s " "md5sums calculated" || die "md5sums calculation failed"; }
# Manifest cache.
(( VERBOSE == 1 )) && printf " %s " "manifest"
tar -vvtf "$FILE" >"${FILE%.t?z}.manifest" && printf "%s " "manifest extracted" || die "manifest extraction failed"
# ChangeLog.txt entry.
(( NO_CL == 0 )) && { gen_pkg_changelog "$FILE" && printf "%s" "changelog created" || die "changelog creation failed"; }
# Force update of top-level repository files.
FLAG_UPDATES=1
else
printf "\\033[1;32;40m%s\\033[0;39m\\n" "up to date"
FLAG_UPDATES=0
fi
done
# Formatting.
printf "\\033[0;39m\\n"
# Only update the top level files if there was a change in the repository or files don't exist.
(( FLAG_UPDATES == 1 )) || [[ ! -e "GPG-KEY" ]] || [[ ! -e "PACKAGES.TXT" ]] || [[ ! -e "FILELIST.TXT" ]] || [[ ! -e "MANIFEST.bz2" ]] || \
[[ ! -e "CHECKSUMS.md5" ]] && {
printf "\\033[1;33;40m %s\\n" "Generating:"
# Add the GPG signing key if required.
(( FORCE == 1 )) || [[ ! -e GPG-KEY ]] || [[ "$(gpg2 --with-colons <GPG-KEY 2>/dev/null | awk -F: -e '/^fpr/ { print $10; exit }')" != \
"$(gpg2 --with-colons --list-keys "$GPG_KEY" 2>/dev/null | awk -F: -e '/^fpr/ { print $10; exit }')" ]] && (( NO_SIGN == 0 )) && {
printf " %s\\n" "GPG-KEY"
gpg2 --list-keys "$GPG_KEY" >GPG-KEY && gpg2 --export --armor "$GPG_KEY" >>GPG-KEY || die "Failed to export GPG key"
}
# Pull all the ChangeLog parts together.
(( NO_CL == 0 )) && [[ -e ".ChangeLog.stub" ]] && {
printf " %s\\n" "ChangeLog.txt"
gen_changelog && mv .ChangeLog.staged ChangeLog.txt 2>/dev/null || die "Failed to generate ChangeLog.txt"
}
# Create the top-level PACKAGES.TXT.
printf "\\033[1;33;40m %s\\n" "PACKAGES.TXT"
gen_packages || die "Failed to generate PACKAGES.TXT"
# Generate MANIFEST.bz2.
printf " %s\\n" "MANIFEST.bz2"
gen_manifest || die "Failed to generate MANIFEST.bz2"
# Create stub files to be included in FILELIST.TXT.
: >CHECKSUMS.md5
(( NO_SIGN == 0 )) && : >CHECKSUMS.md5.asc
# Crate FILELIST.TXT.
printf " %s\\n" "FILELIST.TXT"
gen_filelist || die "Failed to generate FILELIST.TXT"
# Generate repository CHECKSUMS.md5.
printf " %s\\n" "CHECKSUMS.md5"
gen_checksums || die "Failed to generate CHECKSUMS.md5"
(( NO_SIGN == 0 )) && printf " %s:\\n" "Signing"
# Sign the checksums.
(( NO_SIGN == 0 )) && printf " %s\\n" "CHECKSUMS.md5"
(( NO_SIGN == 0 )) && { rm -f CHECKSUMS.md5.asc; sign_file "CHECKSUMS.md5" || die "Failed to sign CHECKSUMS.md5"; }
}
# Sanity check.
[[ ! -e "CHECKSUMS.md5" ]] || [[ ! -e "FILELIST.TXT" ]] || [[ ! -e "PACKAGES.TXT" ]] && \
printf "\\033[1;31;40m%s\\033[0;39m\\n" "Warning: files missing from repository - not Slackware compliant."
printf "\\033[1;32;40m%s: %s\\033[0;39m\\n" "Repository updated in" "$(runtime "$SECONDS")."
cd - >/dev/null 2>&1 || die "abort: $LINENO"
done