feat: add source of dependency error (#2720)

* feat: add source of dependency error

* add test for deps

* present the chain upwards

---------

Co-authored-by: Jo Garnier <git@jguer.space>
This commit is contained in:
Camilo Santana
2025-12-21 10:38:15 -03:00
committed by GitHub
parent 5cdb61fa05
commit dd0f44c78d
4 changed files with 60 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strconv"
"strings"
aurc "github.com/Jguer/aur"
alpm "github.com/Jguer/go-alpm/v2"
@@ -474,6 +475,8 @@ func (g *Grapher) GraphFromAUR(ctx context.Context,
// Removes found deps from the deps mapset and returns the found deps.
func (g *Grapher) findDepsFromAUR(ctx context.Context,
graph *topo.Graph[string, *InstallInfo],
parentPkgName string,
deps mapset.Set[string],
) []aurc.Pkg {
pkgsToAdd := make([]aurc.Pkg, 0, deps.Cardinality())
@@ -541,7 +544,24 @@ func (g *Grapher) findDepsFromAUR(ctx context.Context,
aurPkgs = satisfyingPkgs
if len(aurPkgs) == 0 {
g.logger.Errorln(gotext.Get("No AUR package found for"), " ", depString)
// set of packages that require this dependency
requiredBySet := mapset.NewThreadUnsafeSet[string]()
// add current parent
requiredBySet.Add(parentPkgName)
// if dependency is already in graph, get all packages that require it
if graph.Exists(depName) {
if deps := graph.Dependents(depName); deps != nil {
for parent := range deps {
requiredBySet.Add(parent)
}
}
}
requiredBySlice := requiredBySet.ToSlice()
requiredByStr := strings.Join(requiredBySlice, ", ")
g.logger.Errorln(gotext.Get("No AUR package found for"), " ", depString, " (", gotext.Get("required by"), ": ", requiredByStr, ")")
continue
}
@@ -671,7 +691,7 @@ func (g *Grapher) addNodes(
}
// Check AUR
pkgsToAdd := g.findDepsFromAUR(ctx, targetsToFind)
pkgsToAdd := g.findDepsFromAUR(ctx, graph, parentPkgName, targetsToFind)
for i := range pkgsToAdd {
aurPkg := &pkgsToAdd[i]
if err := graph.DependOn(aurPkg.Name, parentPkgName); err != nil {

View File

@@ -4,15 +4,18 @@
package dep
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"os"
"strings"
"testing"
aurc "github.com/Jguer/aur"
alpm "github.com/Jguer/go-alpm/v2"
mapset "github.com/deckarep/golang-set/v2"
"github.com/stretchr/testify/require"
"github.com/Jguer/yay/v12/pkg/db"
@@ -42,6 +45,31 @@ func getFromFile(t *testing.T, filePath string) mockaur.GetFunc {
}
}
func TestGrapher_findDepsFromAUR_logsRequiredByForMissingDep(t *testing.T) {
mockDB := &mock.DBExecutor{}
mockAUR := &mockaur.MockAUR{GetFn: func(ctx context.Context, query *aurc.Query) ([]aur.Pkg, error) {
// Simulate "no AUR package found" for any query.
return []aur.Pkg{}, nil
}}
var stderr bytes.Buffer
logger := text.NewLogger(io.Discard, &stderr, strings.NewReader(""), true, "test")
g := NewGrapher(mockDB, mockAUR, false, true, false, false, false, logger)
graph := NewGraph()
depString := "missingdep>=1.0"
depName := "missingdep"
require.NoError(t, graph.DependOn("existingNeeds", depName))
toFind := mapset.NewThreadUnsafeSet(depString)
_ = g.findDepsFromAUR(context.Background(), graph, "currentNeeds", toFind)
out := stderr.String()
require.Contains(t, out, "No AUR package found for "+depString+" (required by: currentNeeds, existingNeeds)")
}
func TestGrapher_GraphFromTargets_jellyfin(t *testing.T) {
mockDB := &mock.DBExecutor{
SyncPackageFn: func(string) mock.IPackage { return nil },

View File

@@ -307,10 +307,14 @@ msgid "Name"
msgstr ""
#: pkg/dep/dep_graph.go:442
#: pkg/dep/dep_graph.go:548
#: pkg/dep/dep_graph.go:564
msgid "No AUR package found for"
msgstr ""
#: pkg/dep/dep_graph.go:564
msgid "required by"
msgstr ""
#: pkg/dep/dep_graph.go:182
msgid "No package found for"
msgstr ""

View File

@@ -326,10 +326,14 @@ msgstr "Pacotes de debug do AUR em falta:"
msgid "Name"
msgstr "Nome"
#: pkg/dep/dep_graph.go:442 pkg/dep/dep_graph.go:548
#: pkg/dep/dep_graph.go:442 pkg/dep/dep_graph.go:564
msgid "No AUR package found for"
msgstr "Nenhum pacote AUR localizado para"
#: pkg/dep/dep_graph.go:564
msgid "required by"
msgstr "requerido por"
#: pkg/dep/dep_graph.go:182
msgid "No package found for"
msgstr "Nenhum pacote encontrado para"