[arch-projects] [devtools] [PATCH 4/4] common: implement find_cached_package

Dave Reisner d at falconindy.com
Mon Oct 21 08:24:03 EDT 2013


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 <dreisner at archlinux.org>
> ---
> 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
> 


More information about the arch-projects mailing list