This commit is contained in:
Copilot 2025-10-04 07:01:07 +00:00 committed by GitHub
commit 2d0b97641e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 40 additions and 5 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
src/cmd/apt_query/apt_query*
apt_query_test*
*.log

Binary file not shown.

Binary file not shown.

View file

@ -68,3 +68,9 @@ func TestNormalizedList_VirtualPackagesExists_StdoutsConcretePackage(t *testing.
result := cmdtesting.New(t, createReplayLogs).Run("normalized-list", "libvips")
result.ExpectSuccessfulOut("libvips42=8.9.1-2")
}
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 available`)
}

View file

@ -0,0 +1,17 @@
2025/10/04 06:59:56 Debug log created at /home/runner/work/cache-apt-pkgs-action/cache-apt-pkgs-action/src/cmd/apt_query/apt_query.log
2025/10/04 07:00:00 EXECUTION-OBJ-START
{
"Cmd": "apt-cache --quiet=0 --no-all-versions show python",
"CombinedOut": "N: Can't select candidate version from package python as it has no candidate\nN: Can't select versions from package 'python' as it is purely virtual\nN: No packages found\n",
"ExitCode": 0
}
EXECUTION-OBJ-END
2025/10/04 07:00:00 EXECUTION-OBJ-START
{
"Cmd": "bash -c apt-cache showpkg python | grep -A 1 \"Reverse Provides\" | tail -1",
"CombinedOut": "Reverse Provides: \n",
"ExitCode": 0
}
EXECUTION-OBJ-END
2025/10/04 07:00:00 Encountered error resolving some or all package names, see combined std[out,err] below.
virtual package 'python' has no concrete package providers available

View file

@ -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()
@ -42,10 +48,19 @@ func getNonVirtualPackage(executor exec.Executor, name string) (pkg *AptPackage,
if isErrLine(execution.CombinedOut) {
return pkg, execution.Error()
}
// 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 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
}
@ -67,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) {
@ -112,10 +127,6 @@ func GetAptPackages(executor exec.Executor, names []string) (AptPackages, error)
}
}
if len(errMsgs) > 0 {
errMsgs = append(errMsgs, strings.Join(errMsgs, "\n"))
}
sort.Slice(pkgs, func(i, j int) bool {
return pkgs[i].Name < pkgs[j].Name
})