From e55a7a43cda75db4a43d72d5f5655a99e1b1de71 Mon Sep 17 00:00:00 2001 From: John McQuah Date: Fri, 17 Feb 2023 08:54:10 -0500 Subject: [PATCH] pkgmeek: delete out-of-fashion subroutines, add support for custom unpack_source() --- scripts/pkgmeek | 158 +++++++++++++++++++++--------------------------- 1 file changed, 69 insertions(+), 89 deletions(-) diff --git a/scripts/pkgmeek b/scripts/pkgmeek index 5ddd67c..2d573c8 100755 --- a/scripts/pkgmeek +++ b/scripts/pkgmeek @@ -8,22 +8,12 @@ main() { ######################## main routine ################################ -local o_ignored pkg_dir src_dir work _local_ here url u f TARGET pkg_utd +local pkg_dir src_dir work _local_ here url u f DIR TARGET pkg_utd local errDL=0; local errUZ=0; parse_options "$@" -[ "$PKGMK_RECURSIVE" = "yes" ] && recursive "$@" -# -# Exit early if cleaning was requested -# -if [ "$PKGMK_CLEAN" = "yes" ]; then - [ "$PKGMK_MTIME_ONLY" = "yes" ] && o_ignored="'-utd' " - [ "$PKGMK_UPDATE_FOOTPRINT" = "yes" ] && o_ignored+="'-uf' " - [ "$PKGMK_CHECK_SIG" = "yes" ] && o_ignored+="'-cs' " - [ "$PKGMK_REFRESH_SIG" = "yes" ] && refresh_signature - [ "$o_ignored" = "" ] || { warning "option -c nullifies these requested options:"; - info "$o_ignored"; } - exec $PRTWASH_COMMAND -p -s -q "$(pwd)" -fi + +# Exit early if refreshing an existing sha256 manifest was requested +[ "$PKGMK_REFRESH_SIG" = "yes" ] && { refresh_signature; exit $?; } # # Read the Pkgfile to determine what to do next. But first ensure that # it came from a trusted source (FS#1851) @@ -46,17 +36,17 @@ fi package="${name}#${version}-${release}.pkg.tar.${PKGMK_COMPRESSION_MODE}" declare -a _local_ for (( s=0; s<${#source[@]}; s++ )); do - case "${source[$s]}" in + case "${source[s]}" in http://*|https://*|ftp://*|__git__*) - _local_[$s]="${source[$s]##*/}" # strip the leading path + _local_[s]="${source[s]##*/}" # strip the leading path # and for git sources, extract the project name: - [[ "${source[$s]}" =~ ^__git__ ]] && { _local_[$s]="${_local_[$s]%\#*}"; - _local_[$s]="${_local_[$s]%.git}"; } ;; + [[ "${source[s]}" =~ ^__git__ ]] && { _local_[s]="${_local_[s]%\#*}"; + _local_[s]="${_local_[s]%.git}"; } ;; *) - _local_[$s]="${source[$s]}" ;; + _local_[s]="${source[s]}" ;; esac - [ -z "${renames[$s]}" ] || [ "${renames[$s]}" = "SKIP" ] || \ - _local_[$s]="${renames[$s]}" + [ -z "${renames[s]}" ] || [ "${renames[s]}" = "SKIP" ] || \ + _local_[s]="${renames[s]}" done # Example: source = ( __git__https://gitlab.com/demo-user/cool-project.git#0.4.9 # https://dev.big-corp.com/src/needed-library.tgz @@ -140,14 +130,19 @@ esac; } [ "$PKGMK_CHECK_SIG" = "no" ] || { cleanup_work; exit 0; } # no need to continue if the user only requested -cs if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then - for (( u=0; u<${#_local_[@]}; u++ )) ; do - here="${_local_[$u]}" - if do_unpack "$here"; then - bsdtar -p -o -C src -xf "$here" || errUZ+=1 + if [ "$(type -t unpack_source)" = "function" ]; then + SRC=$PWD/src unpack_source || errUZ+=1 else - cp -r -L "$here" src/ + for (( u=0; u<${#_local_[@]}; u++ )) ; do + here="${_local_[$u]}" + case "$here" in + *.tar|*.tar.gz|*.tar.Z|*.tgz|*.tar.bz2|*.tbz2|*.tar.xz|*.txz|*.tar.lzma|*.tar.lz|*.7z|*.zip|*.rpm) + bsdtar -p -o -C src -xf "$here" || errUZ+=1 ;; + *) + cp -r -L "$here" src/ ;; + esac + done fi - done [ $errUZ = 0 ] && info "Sources successfully unpacked." || \ { error "Failed to unpack all sources."; cleanup_work; exit "$E_UNPACK"; } @@ -159,6 +154,7 @@ if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then [ $? = 0 ] && echo "Build successful. Moving on to compression." \ || { error "Unsuccessful build!"; cleanup_work; exit "$E_BUILD"; } + # Strip binaries [ -f "$PKGMK_ROOT/.nostrip" ] && ns_filter="| grep -v -f $PKGMK_ROOT/.nostrip" { while read -r f; do case $(file -b "$f") in @@ -168,12 +164,19 @@ if [ "$pkg_utd" = 0 ] || [ "$PKGMK_FORCE" = "yes" ]; then esac done } < <(eval find pkg -type f $ns_filter) - find pkg -type f -path "*/man/man*/*" | grep -v '.gz$' | xargs -r -I{} gzip -9 '{}' - find pkg -xtype l -path "*/man/man*/*" | while read f; do - TARGET="$(basename -s .gz $(readlink -n $f)).gz"; DIR="$(dirname ${f%%.gz}.gz)"; - rm -f $f; [ -e $DIR/$TARGET ] && ln -sf $TARGET ${f%%.gz}.gz - done + # Compress anything under /man that does not appear to be gzipped + find pkg -type f -path "*/man/man*/*" \! -iname '*.gz' \ + -exec gzip -9 '{}' + + # Ensure that symlinks point to the (now-compressed) manpages + { while IFS="!" read -r f DIR; do + TARGET="$(readlink -n "$DIR/$f")" + TARGET="${TARGET##*/}"; TARGET="${TARGET%.gz}.gz"; + rm -f "$DIR/$f" + [ -e "$DIR/$TARGET" ] && ln -sf "$TARGET" "$DIR/${f%.gz}.gz" + done } < <(find pkg -type l -path "*/man/man*/*" -printf '%f!%h\n') + + # Create the archive [ $UID = 0 ] || fake_uid="--uid 0 --gid 0" if (cd pkg; bsdtar --format=gnutar $fake_uid -cf "$pkg_dir$package" *); then info "Package creation successful." @@ -192,14 +195,13 @@ find . -maxdepth 1 -mindepth 1 -type l -delete; cleanup_work # Proceed to install/upgrade if requested. if [ -n "$PKGMK_INSTALL_COMMAND" ]; then - [ $UID = 0 ] || PKGMK_SU="sudo"; - [ -z "$PKGMK_SU" ] || [ -x "$(command -v $PKGMK_SU)" ] || PKGMK_SU="/usr/bin/doas"; - [ -z "$PKGMK_SU" ] || [ -x "$(command -v $PKGMK_SU)" ] \ - || { error "Cannot run pkgadd as a non-root user."; exit "$E_INSTALL"; } - + [ $UID = 0 ] && PKGMK_SU="" + [ -z "$PKGMK_SU" ] || [ -x "$PKGMK_SU" ] || PKGMK_SU="/usr/bin/doas" + [ -z "$PKGMK_SU" ] || [ -x "$PKGMK_SU" ] || + { error "Cannot run pkgadd as a non-root user."; exit "$E_INSTALL"; } $PKGMK_SU $PKGMK_INSTALL_COMMAND "$pkg_dir$package" \ - && info "$(basename $PKGMK_INSTALL_COMMAND) $package succeeded." || \ - { error "$(basename $PKGMK_INSTALL_COMMAND) $package failed."; + && info "pkgadd $package succeeded." || \ + { error "pkgadd $package failed."; exit "$E_INSTALL"; } fi @@ -220,15 +222,13 @@ E_SIGNATURE=9 # error verifying the signature readonly PKGMK_VERSION="#VERSION#" readonly PKGMK_COMMAND="$0" readonly PKGMK_ROOT="$PWD" -readonly PRTWASH_COMMAND="/usr/bin/prtwash" PKGMK_DOWNLOAD_PROG="/usr/bin/curl" PKGMK_GIT_COMMAND="/usr/bin/git" -PKGMK_CONF="/etc/pkgmk.conf" +PKGMK_CONF="/etc/pkgmk.conf"; PKGMK_SU="/usr/bin/sudo" PKGMK_SOURCE_DIR="$PWD"; PKGMK_WORK_DIR="$PWD/work" PKGMK_PACKAGE_DIR="$PWD"; PKGMK_COMPRESSION_MODE="gz" PKGMK_INSTALL_COMMAND=""; PKGMK_FORCE="no" -PKGMK_CLEAN="no"; PKGMK_KEEP_WORK="no" -PKGMK_DOWNLOAD_ONLY="no"; PKGMK_RECURSIVE="no" +PKGMK_DOWNLOAD_ONLY="no"; PKGMK_KEEP_WORK="no" PKGMK_EXTRACT_ONLY="no"; PKGMK_UPDATE_SIG="no" PKGMK_MTIME_ONLY="no"; PKGMK_IGNORE_SIG="no" PKGMK_UPDATE_FOOTPRINT="no"; PKGMK_REFRESH_SIG="no" @@ -239,17 +239,15 @@ PKGMK_IGNORE_NEW="no"; PKGMK_PRIVATEKEY="" parse_options() { while [ "$1" ]; do case $1 in - -r|--recursive) PKGMK_RECURSIVE="yes" ;; - -c|--clean) [ -x "$PRTWASH_COMMAND" ] && PKGMK_CLEAN="yes" || \ - { error "option '$1' not supported ($PRTWASH_COMMAND not installed)"; - exit 1; } ;; -uf|--update-footprint) PKGMK_UPDATE_FOOTPRINT="yes" ;; -us|--update-signature) PKGMK_UPDATE_SIG="yes" ;; -rs|--refresh-signature) PKGMK_REFRESH_SIG="yes" ;; -cs|--check-signature) PKGMK_CHECK_SIG="yes" ;; --check-md5sum|--ignore-md5sum) ;; # deprecated flags -d|-cm|-im|--download) ;; # but don't throw an error for them - -um|--update-md5sum) warn "updating md5sums is deprecated, ignoring option '$1'." ;; + -um|--update-md5sum) warn "updating md5sums is obsolete, ignoring option '$1'." ;; + -r|--recursive) warn "option '$1' no longer supported. Use a wrapper script for recursive operation." ;; + -c|--clean) { error "option '$1' no longer implemented in $(basename "$PKGMK_COMMAND"). Use prtwash instead."; exit 1; } ;; -do|--download-only) PKGMK_DOWNLOAD_ONLY="yes" ;; -eo|--extract-only) PKGMK_EXTRACT_ONLY="yes" ;; -utd|--up-to-date) PKGMK_MTIME_ONLY="yes" ;; @@ -287,9 +285,6 @@ parse_options() { print_help() { echo "usage: $(basename "$PKGMK_COMMAND") [options]" echo "options: " - echo " -r, --recursive search for Pkgfiles under $PWD, and run $(basename "$PKGMK_COMMAND")" - echo " with the other given options inside each directory found" - echo " -c, --clean remove package and downloaded files" echo " -i, --install build and install package" echo " -u, --upgrade build and install package (as upgrade)" echo " -do, --download-only stop after downloading all the necessary source file(s)" @@ -345,7 +340,7 @@ check_pkg_mtime() { # can be called even if some sources are missing utd=1 while [ $li -lt ${#_local_[@]} ] && [ "$utd" = 1 ]; do [ ! -e "${_local_[$li]}" ] || \ - [ "$pkg_dir$package" -nt $(realpath "${_local_[$li]}") ] || utd=0 + [ "$pkg_dir$package" -nt "$(realpath "${_local_[$li]}")" ] || utd=0 li=$(( li+1 )) done [ ! -e "$PKGMK_ROOT/Pkgfile" ] || [ "$pkg_dir$package" -nt "$PKGMK_ROOT/Pkgfile" ] || utd=0 @@ -372,7 +367,7 @@ fetch_url() { # Has this project been downloaded before? if [ -d "$src_dir/$h.partial" ]; then ln -s "$src_dir/$h.partial" "$h"; cd "$h" - "$PKGMK_GIT_COMMAND" pull $giturl $tag + "$PKGMK_GIT_COMMAND" pull "$giturl" "$tag" finished=$?; cd .. else "$PKGMK_GIT_COMMAND" clone "$giturl" $CLONE_ARGS "$h.partial" @@ -383,11 +378,13 @@ fetch_url() { else case "$PKGMK_DOWNLOAD_PROG" in *wget) OCONTINUE="-c" - OOUT=("--compression=none" "--passive-ftp" "--no-directories" - "--tries=3" "--waitretry=3" $PKGMK_WGET_OPTIONS -O) ;; + OOUT="--compression=none --passive-ftp + --no-directories --tries=3 --waitretry=3 + $PKGMK_WGET_OPTIONS -O" ;; *curl) OCONTINUE="-C -" - OOUT=("-L" "-#" "--fail" "--ftp-pasv" - --retry 3 --retry-delay 3 $PKGMK_CURL_OPTIONS -o) ;; + OOUT="-L -# --fail --ftp-pasv + --retry 3 --retry-delay 3 + $PKGMK_CURL_OPTIONS -o" ;; *) SAVE_AS="/bin/false" ;; esac # @@ -399,8 +396,8 @@ fetch_url() { m=$(( m+1 )) # interrupted downloads from a previous run should be put where wget or curl will find them [ -f "$src_dir/$h.partial" ] && { ln -s "$src_dir/$h.partial" . ; - SAVE_AS="$PKGMK_DOWNLOAD_PROG $um $OCONTINUE ${OOUT[@]}"; } \ - || SAVE_AS="$PKGMK_DOWNLOAD_PROG $um ${OOUT[@]}" + SAVE_AS="$PKGMK_DOWNLOAD_PROG $um $OCONTINUE $OOUT"; } \ + || SAVE_AS="$PKGMK_DOWNLOAD_PROG $um $OOUT" if $SAVE_AS "$h.partial"; then finished=1 [ "$src_dir" = "" ] || [ ! -w "$src_dir"/ ] || \ @@ -413,12 +410,6 @@ fetch_url() { fi } -do_unpack() { - [[ " ${nounpack[*]} " =~ " $(basename $1) " ]] && return 1 - [[ "$1" =~ \.(tar|tar.gz|tar.Z|tgz|tar.bz2|tbz2|tar.xz|txz|tar.lzma|tar.lz|7z|zip|rpm)$ ]] && return 0 - return 1 -} - cat_footprint() { pkginfo --footprint "$pkg_dir$package" \ | sed "s|\tlib/modules/$(uname -r)/|\tlib/modules//|g" \ @@ -438,14 +429,14 @@ check_footprint() { CN=$(grep -c ^NEW ".footprint.diff"); CM=$(grep -c ^MISSING ".footprint.diff") [ "$PKGMK_IGNORE_MISSING" = "yes" ] || diffs=$CM [ "$PKGMK_IGNORE_NEW" = "yes" ] || diffs=$(( diffs+CN )) - [ $diffs = 0 ] && severity=warning + (( diffs == 0 )) && severity=warning $severity "footprint mismatch found:"; cat ".footprint.diff" >&2 fi rm ".footprint.diff" else warning "footprint not found, creating new."; cat_footprint > "$TRUTH" fi - [ $diffs = 0 ] || exit $E_FOOTPRINT + (( diffs == 0 )) || exit $E_FOOTPRINT } parse_signify_output() { # chomps the output of check_signature() @@ -508,7 +499,7 @@ cat_signature() { done for ((si=0; si < ${#source[@]}; si++)); do # ignore git directories when writing the signature - [[ "${source[$si]}" =~ ^__git__ ]] || ordered+=("${_local_[$si]}"); done + [[ "${source[si]}" =~ ^__git__ ]] || ordered+=("${_local_[si]}"); done sha256sum --tag "${ordered[@]}" \ | sed 's|^SHA256 (.*/\(.*\))\(.* = .*\)|SHA256 (\1)\2|' \ | /usr/bin/signify -S -e -x - -q -s "$key" -m - \ @@ -519,13 +510,16 @@ cat_signature() { } refresh_signature() { - if [ -e ".signature" ] && [ ! -w ".signature" ]; then - echo "error: .signature not writable."; return $E_DIRPERM - fi + [ -e ".signature" ] && [ ! -w ".signature" ] || { + error ".signature not writable."; return $E_DIRPERM; } local REPO - [ -n "$PKGMK_PRIVATEKEY" ] || REPO=$(dirname "$PWD" | sed 's|^.*/||; s|\.git$||;') - [ -n "$REPO" ] && PKGMK_PRIVATEKEY="/etc/ports/${REPO}.sec" + if [ -z "$PKGMK_PRIVATEKEY" ]; then + REPO=${PWD##*/}; REPO=${REPO%.git}; + [ -r "/etc/ports/${REPO}.sec" ] && \ + PKGMK_PRIVATEKEY="/etc/ports/${REPO}.sec" || \ + { error "No suitable secret key found. Specify one explicitly with '-sk'."; return $E_SIGNATURE; } + fi if ! tail -n +3 ".signature" | /usr/bin/signify -S -e -x - -q \ -s "$PKGMK_PRIVATEKEY" -m - > .signature.tmp ; then @@ -534,6 +528,7 @@ refresh_signature() { return $E_SIGNATURE else mv .signature.tmp .signature + info "Signature refreshed." fi } @@ -545,21 +540,6 @@ cleanup_work() { [ "$PKGMK_KEEP_WORK" = "yes" ] || { cd "$PKGMK_ROOT"; rm -rf "$work"; } } -recursive() { - local ARGS DIR FILE - [ "$PKGMK_CLEAN" = "no" ] || { find "$PKGMK_ROOT" -name Pkgfile -printf "%h\n" \ - | xargs "$PRTWASH_COMMAND" -s -p -b -q; exit $? ; } - - ARGS=$(echo "$@" | sed "s/--recursive//g; s/\s*-r\s*/ /g") - for FILE in $(find "$PKGMK_ROOT" -name Pkgfile | sort); do - DIR=$(dirname "$FILE") - [ -d $DIR ] && { info "Entering directory '$DIR'."; - (cd "$DIR" && "$PKGMK_COMMAND" $ARGS); - info "Leaving directory '$DIR'."; } - done - exit -} - info() { echo "=======> $1" } @@ -577,7 +557,7 @@ error() { readonly -f main info warning error print_help parse_options validate_pkgfile \ check_reqvars check_pkg_mtime fetch_url cat_footprint check_footprint \ cat_signature check_signature parse_signify_output refresh_signature \ - cleanup_work recursive + cleanup_work trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM export LC_ALL=C.UTF-8