diff --git a/apt_query-arm64 b/apt_query-arm64 index 0b2bf6e..46a8e67 100755 Binary files a/apt_query-arm64 and b/apt_query-arm64 differ diff --git a/apt_query-x86 b/apt_query-x86 index 1fefad7..720dcf8 100755 Binary files a/apt_query-x86 and b/apt_query-x86 differ diff --git a/src/cmd/apt_query/main_test.go b/src/cmd/apt_query/main_test.go index 482716b..3acf3fe 100644 --- a/src/cmd/apt_query/main_test.go +++ b/src/cmd/apt_query/main_test.go @@ -72,6 +72,6 @@ func TestNormalizedList_VirtualPackagesExists_StdoutsConcretePackage(t *testing. func TestNormalizedList_VirtualPackageWithNoProviders_StderrsErrorMessage(t *testing.T) { var result = cmdtesting.New(t, createReplayLogs).Run("normalized-list", "python") result.ExpectError(`Encountered error resolving some or all package names, see combined std[out,err] below. -virtual package 'python' has no concrete package providers -virtual package 'python' has no concrete package providers`) +virtual package 'python' has no concrete package providers available +virtual package 'python' has no concrete package providers available`) } diff --git a/src/internal/common/apt.go b/src/internal/common/apt.go index ac2b1c9..e236f01 100644 --- a/src/internal/common/apt.go +++ b/src/internal/common/apt.go @@ -31,7 +31,13 @@ func isErrLine(line string) bool { return strings.HasPrefix(line, "E: ") || strings.HasPrefix(line, "N: ") } +// isVirtualPackage checks if a string indicates a purely virtual package message. +func isVirtualPackage(message string) bool { + return strings.Contains(message, "as it is purely virtual") +} + // Resolves virtual packages names to their concrete one. +// Returns the first available concrete package provider, or an error if none exist. func getNonVirtualPackage(executor exec.Executor, name string) (pkg *AptPackage, err error) { execution := executor.Exec("bash", "-c", fmt.Sprintf("apt-cache showpkg %s | grep -A 1 \"Reverse Provides\" | tail -1", name)) err = execution.Error() @@ -46,13 +52,15 @@ func getNonVirtualPackage(executor exec.Executor, name string) (pkg *AptPackage, // Check if the output is just "Reverse Provides:" with no actual package info trimmedOutput := strings.TrimSpace(execution.CombinedOut) if trimmedOutput == "Reverse Provides:" { - return pkg, fmt.Errorf("virtual package '%s' has no concrete package providers", name) + return pkg, fmt.Errorf("virtual package '%s' has no concrete package providers available", name) } splitLine := GetSplitLine(execution.CombinedOut, " ", 3) if len(splitLine.Words) < 2 { return pkg, fmt.Errorf("unable to parse space delimited line's package name and version from apt-cache showpkg output below:\n%s", execution.CombinedOut) } + + // Successfully found a concrete package provider return &AptPackage{Name: splitLine.Words[0], Version: splitLine.Words[1]}, nil } @@ -74,7 +82,7 @@ func getPackage(executor exec.Executor, paragraph string) (pkg *AptPackage, err case "N": // e.g. Can't select versions from package 'libvips' as it is purely virtual - if strings.Contains(splitLine.Words[1], "as it is purely virtual") { + if isVirtualPackage(splitLine.Words[1]) { return getNonVirtualPackage(executor, GetSplitLine(splitLine.Words[1], "'", 4).Words[2]) } if strings.HasPrefix(splitLine.Words[1], "Unable to locate package") && !ArrContainsString(errMsgs, splitLine.Line) {