fix: --include-needs should only include direct dependencies

The DAG's WithDependencies option was incorrectly including transitive dependencies
when only direct dependencies were requested. This fix:

1. Builds the DAG with only unfiltered releases and their dependencies
2. Uses the unfiltered release IDs as the Only parameter when IncludeNeeds is true
3. Sets WithDependencies to false since all needed releases are already in the DAG

This ensures that --include-needs only includes direct dependencies of selected
releases, while --include-transitive-needs continues to include all transitive
dependencies.

Fixes #1003

Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
yxxhero 2026-03-13 13:19:10 +08:00
parent efa599380e
commit d54789a036
2 changed files with 23 additions and 7 deletions

View File

@ -3067,10 +3067,8 @@ func collectDirectNeeds(filteredReleases []Release, allReleases []ReleaseSpec) m
for _, r := range filteredReleases {
if !r.Filtered {
for _, need := range r.Needs {
if release, exists := allReleasesMap[need]; exists {
if release.Installed == nil || *release.Installed {
directNeeds[need] = struct{}{}
}
if _, exists := allReleasesMap[need]; exists {
directNeeds[need] = struct{}{}
}
}
}

View File

@ -143,6 +143,13 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas
idToReleases := map[string][]Release{}
idToIndex := map[string]int{}
unfilteredIDs := make(map[string]struct{})
for _, r := range releases {
if !r.Filtered {
unfilteredIDs[ReleaseToID(&r.ReleaseSpec)] = struct{}{}
}
}
d := dag.New()
for i, r := range releases {
id := ReleaseToID(&r.ReleaseSpec)
@ -153,7 +160,9 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas
var needs []string
for i := 0; i < len(r.Needs); i++ {
n := r.Needs[i]
needs = append(needs, n)
if _, exists := unfilteredIDs[n]; exists {
needs = append(needs, n)
}
}
d.Add(id, dag.Dependencies(needs))
}
@ -171,9 +180,18 @@ func GroupReleasesByDependency(releases []Release, opts PlanOptions) ([][]Releas
selectedReleaseIDs = append(selectedReleaseIDs, id)
}
var onlyReleaseIDs []string
if opts.IncludeNeeds || opts.IncludeTransitiveNeeds {
for id := range unfilteredIDs {
onlyReleaseIDs = append(onlyReleaseIDs, id)
}
} else {
onlyReleaseIDs = selectedReleaseIDs
}
plan, err := d.Plan(dag.SortOptions{
Only: selectedReleaseIDs,
WithDependencies: opts.IncludeNeeds,
Only: onlyReleaseIDs,
WithDependencies: false,
WithoutDependencies: opts.SkipNeeds,
})
if err != nil {