@@ -1251,6 +1251,8 @@ func (d *Discovery) Discover(
12511251 }
12521252 }
12531253
1254+ allComponents := components
1255+
12541256 if len (d .filters ) > 0 {
12551257 filtered , evaluateErr := d .filters .Evaluate (l , components )
12561258 if evaluateErr != nil {
@@ -1285,12 +1287,10 @@ func (d *Discovery) Discover(
12851287 return components , errors .Join (errs ... )
12861288 }
12871289
1288- // When filter queries include ONLY dependents (e.g., ...{target}) and NO dependencies,
1289- // apply additional pruning to retain only the target(s) and their transitive dependents.
1290- // Skip this when dependency expressions exist (e.g., ...{target}...) since those require
1291- // keeping both dependencies AND dependents.
1292- if len (d .dependencyTargetExpressions ) == 0 {
1293- components = d .applyDependentTargeting (l , components )
1290+ // When filter queries include dependents (e.g., ...{target}), re-expand the filtered set
1291+ // to include the target(s) and their transitive dependents from the full component graph.
1292+ if len (d .dependentTargetExpressions ) > 0 {
1293+ components = d .applyDependentTargeting (allComponents , components )
12941294 }
12951295
12961296 if d .graphTarget != "" {
@@ -1326,43 +1326,32 @@ func (d *Discovery) filterGraphTarget(components component.Components) (componen
13261326 return filterByAllowSet (components , allowed ), nil
13271327}
13281328
1329- // applyDependentTargeting prunes the discovered components to the union of all
1330- // filter targets that requested dependents (via ... prefix) and their transitive dependents.
1331- // This aligns behavior with --graph-target pruning when the filter queries specify dependents.
1332- func (d * Discovery ) applyDependentTargeting (l log.Logger , components component.Components ) component.Components {
1329+ // applyDependentTargeting re-expands the filtered set of components to include
1330+ // the target(s) selected by dependent filter expressions and their transitive dependents.
1331+ func (d * Discovery ) applyDependentTargeting (full component.Components , filtered component.Components ) component.Components {
13331332 if len (d .dependentTargetExpressions ) == 0 {
1334- return components
1333+ return filtered
13351334 }
13361335
1337- // Build dependents index once over the full component graph.
1338- dependentUnits := buildDependentsIndex (components )
1336+ dependentUnits := buildDependentsIndex (full )
13391337 propagateTransitiveDependents (dependentUnits )
13401338
13411339 allowed := make (map [string ]struct {})
13421340
1343- for _ , targetExpr := range d .dependentTargetExpressions {
1344- matched , err := filter .Evaluate (l , targetExpr , components )
1345- if err != nil {
1346- l .Warnf ("Failed to evaluate dependent target expression %q: %v" , targetExpr , err )
1347-
1348- continue
1349- }
1350-
1351- for _ , c := range matched {
1352- targetPath := resolvePath (c .Path ())
1353- allowed [targetPath ] = struct {}{}
1341+ for _ , target := range filtered {
1342+ targetPath := resolvePath (target .Path ())
1343+ allowed [targetPath ] = struct {}{}
13541344
1355- for _ , dep := range dependentUnits [targetPath ] {
1356- allowed [dep ] = struct {}{}
1357- }
1345+ for _ , dep := range dependentUnits [targetPath ] {
1346+ allowed [dep ] = struct {}{}
13581347 }
13591348 }
13601349
13611350 if len (allowed ) == 0 {
1362- return components
1351+ return filtered
13631352 }
13641353
1365- return filterByAllowSet (components , allowed )
1354+ return filterByAllowSet (full , allowed )
13661355}
13671356
13681357// canonicalizeGraphTarget resolves the graph target to an absolute, cleaned path with symlinks resolved.
0 commit comments