@@ -90,7 +90,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (st *llb.Sta
90
90
if ds .ignoreCache {
91
91
sbom .IgnoreCache = true
92
92
}
93
- for _ , dsi := range findReachable (ds ) {
93
+ for dsi := range allReachableStages (ds ) {
94
94
if ds != dsi && dsi .scanStage {
95
95
sbom .Extras [dsi .stageName ] = dsi .state
96
96
if dsi .ignoreCache {
@@ -409,11 +409,12 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
409
409
allStageNames = append (allStageNames , s .stageName )
410
410
}
411
411
}
412
+ allReachable := allReachableStages (target )
412
413
413
414
baseCtx := ctx
414
415
eg , ctx := errgroup .WithContext (ctx )
415
416
for i , d := range allDispatchStates .states {
416
- reachable := isReachable ( target , d )
417
+ _ , reachable := allReachable [ d ]
417
418
// resolve image config for every stage
418
419
if d .base == nil && ! d .noinit {
419
420
if d .stage .BaseName == emptyImageName {
@@ -546,7 +547,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
546
547
ctxPaths := map [string ]struct {}{}
547
548
548
549
for _ , d := range allDispatchStates .states {
549
- if ! isReachable ( target , d ) || d .noinit {
550
+ if _ , ok := allReachable [ d ]; ! ok || d .noinit {
550
551
continue
551
552
}
552
553
d .init ()
@@ -1724,33 +1725,23 @@ func commitToHistory(img *dockerspec.DockerOCIImage, msg string, withLayer bool,
1724
1725
return nil
1725
1726
}
1726
1727
1727
- func isReachable (from , to * dispatchState ) (ret bool ) {
1728
- if from == nil {
1729
- return false
1730
- }
1731
- if from == to || isReachable (from .base , to ) {
1732
- return true
1733
- }
1734
- for d := range from .deps {
1735
- if isReachable (d , to ) {
1736
- return true
1737
- }
1738
- }
1739
- return false
1728
+ func allReachableStages (s * dispatchState ) map [* dispatchState ]struct {} {
1729
+ stages := make (map [* dispatchState ]struct {})
1730
+ addReachableStages (s , stages )
1731
+ return stages
1740
1732
}
1741
1733
1742
- func findReachable ( from * dispatchState ) ( ret [] * dispatchState ) {
1743
- if from == nil {
1744
- return nil
1734
+ func addReachableStages ( s * dispatchState , stages map [ * dispatchState ] struct {} ) {
1735
+ if _ , ok := stages [ s ]; ok {
1736
+ return
1745
1737
}
1746
- ret = append ( ret , from )
1747
- if from .base != nil {
1748
- ret = append ( ret , findReachable ( from .base ) ... )
1738
+ stages [ s ] = struct {}{}
1739
+ if s .base != nil {
1740
+ addReachableStages ( s .base , stages )
1749
1741
}
1750
- for d := range from .deps {
1751
- ret = append ( ret , findReachable ( d ) ... )
1742
+ for d := range s .deps {
1743
+ addReachableStages ( d , stages )
1752
1744
}
1753
- return ret
1754
1745
}
1755
1746
1756
1747
func validateCircularDependency (states []* dispatchState ) error {
0 commit comments