On Sun, Oct 20, 2013 at 04:17:45PM -0400, Dave Reisner wrote:
> This function (currently) searches through $PWD and $PKGDEST looking
> for a tarball matching the requested package name, architecture, and
> pkgver. If found, it writes the full path to the located package to
> stdout and returns 0, else 1. If more than 1 match is found, it's
> treated as an error and the user will need to figure out what to do.
> 
> Use this in checkpkg and commitpkg, which previously implemented their
> own less complete logic, to locate the build artifacts they rely on.
> 
> Signed-off-by: Dave Reisner <[email protected]>
> ---
> This fixes a regression I caused in 9c85d116f042 which didn't consider finding
> the package in PKGDEST. I took the heavy handed approach and wrote a generic
> function to find cached packages since we do this in both checkpkg and
> commitpkg (and maybe some day elsewhere). Neither of the existing solutions
> are particularly thorough.

Replying to myself...

> 
>  checkpkg.in   | 14 ++++--------
>  commitpkg.in  | 24 +++------------------
>  lib/common.sh | 69 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 76 insertions(+), 31 deletions(-)
> 
> diff --git a/checkpkg.in b/checkpkg.in
> index 9a32d00..3ad912f 100644
> --- a/checkpkg.in
> +++ b/checkpkg.in
> @@ -29,18 +29,12 @@ STARTDIR=$(pwd)
>  TEMPDIR=$(mktemp -d --tmpdir checkpkg-script.XXXX)
>  
>  for _pkgname in "${pkgname[@]}"; do
> -  pkgfile=(${_pkgname}-$(get_full_version $_pkgname)-${CARCH}.pkg.tar?(.?z))
> -     if (( ${#pkgfile[*]} != 1 )); then
> -             die 'Ambiguous package name: %s\n' "${pkgfile[*]}"
> +     target_pkgver=$(get_full_version "$_pkgname")
> +     if ! pkgfile=$(find_cached_package "$_pkgname" "$target_pkgver" 
> "$CARCH"); then
> +             die 'tarball not found for package: %s' 
> "${_pkgname}-$target_pkgver"
>       fi
>  
> -     if [[ -f "$STARTDIR/$pkgfile" ]]; then
> -             ln -s "$STARTDIR/$pkgfile" "$TEMPDIR/$pkgfile"
> -     elif [[ -f "$PKGDEST/$pkgfile" ]]; then
> -             ln -s "$PKGDEST/$pkgfile" "$TEMPDIR/$pkgfile"
> -     else
> -             die "File \"$pkgfile\" doesn't exist"
> -     fi
> +     ln -s "$pkgfile" "$TEMPDIR"
>  
>       pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname")
>  
> diff --git a/commitpkg.in b/commitpkg.in
> index d584f92..809ff81 100644
> --- a/commitpkg.in
> +++ b/commitpkg.in
> @@ -2,22 +2,6 @@
>  
>  m4_include(lib/common.sh)
>  
> -getpkgfile() {
> -     case $# in
> -             0)
> -                     error 'No canonical package found!'
> -                     return 1
> -                     ;;
> -             [!1])
> -                     error 'Failed to canonicalize package name -- multiple 
> packages found:'
> -                     msg2 '%s' "$@"
> -                     return 1
> -                     ;;
> -     esac
> -
> -     echo "$1"
> -}
> -
>  # Source makepkg.conf; fail if it is not found
>  if [[ -r '/etc/makepkg.conf' ]]; then
>       source '/etc/makepkg.conf'
> @@ -99,9 +83,8 @@ for _arch in ${arch[@]}; do
>       for _pkgname in ${pkgname[@]}; do
>               fullver=$(get_full_version $_pkgname)
>  
> -             if pkgfile=$(shopt -s nullglob;
> -                             getpkgfile 
> "${PKGDEST+$PKGDEST/}$_pkgname-$fullver-${_arch}".pkg.tar.?z); then
> -                     if grep -q "packager = Unknown Packager" <(bsdtar -xOqf 
> $pkgfile .PKGINFO); then
> +             if pkgfile=$(find_cached_package "$_pkgname" "$_arch" 
> "$fullver"); then
> +                     if grep -q "packager = Unknown Packager" <(bsdtar -xOqf 
> "$pkgfile" .PKGINFO); then
>                               die "PACKAGER was not set when building package"
>                       fi
>               fi
> @@ -151,8 +134,7 @@ for _arch in ${arch[@]}; do
>       for _pkgname in ${pkgname[@]}; do
>               fullver=$(get_full_version $_pkgname)
>  
> -             if ! pkgfile=$(shopt -s nullglob;
> -                             getpkgfile 
> "${PKGDEST+$PKGDEST/}$_pkgname-$fullver-${_arch}".pkg.tar.?z); then
> +             if ! pkgfile=$(find_cached_package "$_pkgname" "$fullver" 
> "${_arch}"); then
>                       warning "Skipping $_pkgname-$fullver-$_arch: failed to 
> locate package file"
>                       skip_arches+=($_arch)
>                       continue 2
> diff --git a/lib/common.sh b/lib/common.sh
> index 3ec26ff..1812cb7 100644
> --- a/lib/common.sh
> +++ b/lib/common.sh
> @@ -1,6 +1,8 @@
>  # Avoid any encoding problems
>  export LANG=C
>  
> +shopt -s extglob
> +
>  # check if messages are to be printed using color
>  unset ALL_OFF BOLD BLUE GREEN RED YELLOW
>  if [[ -t 2 ]]; then
> @@ -154,3 +156,70 @@ slock() {
>               stat_done
>       fi
>  }
> +
> +##
> +# usage: pkgver_equal( $pkgver1, $pkgver2 )
> +##
> +pkgver_equal() {
> +     local left right
> +
> +     if [[ $1 = *-* && $2 = *-* ]]; then
> +             # if both versions have a pkgrel, then they must be an exact 
> match
> +             [[ $1 = "$2" ]]
> +     else
> +             # otherwise, trim any pkgrel and compare the bare version.
> +             [[ ${1%%-*} = "${2%%-*}" ]]
> +     fi
> +}
> +
> +##
> +#  usage: find_cached_package( $pkgname, $pkgver, $arch )
> +#
> +#    $pkgver can be supplied with or without a pkgrel appended.
> +#    If not supplied, any pkgrel will be matched.
> +##
> +find_cached_package() {
> +     local searchdirs=("$PWD" "$PKGDEST") results=()
> +     local targetname=$1 targetver=$2 targetarch=$3
> +     local dir pkg pkgbasename pkgparts name ver rel arch size results
> +
> +     for dir in "${searchdirs[@]}"; do
> +             [[ -d $dir ]] || continue
> +
> +             for pkg in "$dir"/*.pkg.tar?(.?z); do
> +                     [[ -f $pkg ]] || continue
> +
> +                     # split apart package filename into parts
> +                     pkgbasename=${pkg##*/}
> +                     pkgbasename=${pkgbasename%.pkg.tar?(.?z)}
> +
> +                     arch=${pkgbasename##*-}
> +                     pkgbasename=${pkgbasename%-"$arch"}
> +
> +                     rel=${pkgbasename##*-}
> +                     pkgbasename=${pkgbasename%-"$rel"}
> +
> +                     ver=${pkgbasename##*-}
> +                     name=${pkgbasename%-"$ver"}
> +
> +                     if [[ $targetname = "$name" && $targetarch = "$arch" ]] 
> &&
> +                                     pkgver_equal "$targetver" "$ver-$rel"; 
> then
> +                             results+=("$pkg")
> +                     fi
> +             done
> +     done
> +
> +     case ${#results[*]} in
> +             0)
> +                     return 1

Need to print an error here because we don't return enough to the
caller to let them differentiate between no results and multiple
results.

> +                     ;;
> +             1)
> +                     printf '%s\n' "$results"
> +                     return 0
> +                     ;;
> +             *)
> +                     error 'Multiple packages found:'
> +                     printf '\t%s\n' "${results[@]}"
> +                     return 1
> +     esac
> +}
> -- 
> 1.8.4.1
> 

Reply via email to