@@ -16,6 +16,7 @@ import struct Basics.InternalError
16
16
import class Basics. ObservabilityScope
17
17
import struct Basics. SwiftVersion
18
18
import func Basics. temp_await
19
+ import func Basics. DFS
19
20
import class Basics. ThreadSafeKeyValueStore
20
21
import class Dispatch. DispatchGroup
21
22
import struct Dispatch. DispatchTime
@@ -494,12 +495,7 @@ extension Workspace {
494
495
// Continue to load the rest of the manifest for this graph
495
496
// Creates a map of loaded manifests. We do this to avoid reloading the shared nodes.
496
497
var loadedManifests = firstLevelManifests
497
- // Compute the transitive closure of available dependencies.
498
- let topologicalSortInput = topLevelManifests. map { identity, manifest in KeyedPair (
499
- manifest,
500
- key: Key ( identity: identity, productFilter: . everything)
501
- ) }
502
- let topologicalSortSuccessors : ( KeyedPair < Manifest , Key > ) throws -> [ KeyedPair < Manifest , Key > ] = { pair in
498
+ let successorManifests : ( KeyedPair < Manifest , Key > ) throws -> [ KeyedPair < Manifest , Key > ] = { pair in
503
499
// optimization: preload manifest we know about in parallel
504
500
let dependenciesRequired = pair. item. dependenciesRequired ( for: pair. key. productFilter)
505
501
let dependenciesToLoad = dependenciesRequired. map ( \. packageRef)
@@ -527,36 +523,26 @@ extension Workspace {
527
523
}
528
524
}
529
525
530
- // Look for any cycle in the dependencies.
531
- if let cycle = try findCycle ( topologicalSortInput, successors: topologicalSortSuccessors) {
532
- observabilityScope. emit (
533
- error: " cyclic dependency declaration found: " +
534
- ( cycle. path + cycle. cycle) . map ( \. key. identity. description) . joined ( separator: " -> " ) +
535
- " -> " + cycle. cycle [ 0 ] . key. identity. description
536
- )
537
- // return partial results
538
- return DependencyManifests (
539
- root: root,
540
- dependencies: [ ] ,
541
- workspace: self ,
542
- observabilityScope: observabilityScope
543
- )
544
- }
545
- let allManifestsWithPossibleDuplicates = try topologicalSort (
546
- topologicalSortInput,
547
- successors: topologicalSortSuccessors
548
- )
549
-
550
- // merge the productFilter of the same package (by identity)
551
- var deduplication = [ PackageIdentity: Int] ( )
552
526
var allManifests = [ ( identity: PackageIdentity, manifest: Manifest, productFilter: ProductFilter) ] ( )
553
- for pair in allManifestsWithPossibleDuplicates {
554
- if let index = deduplication [ pair. key. identity] {
555
- let productFilter = allManifests [ index] . productFilter. merge ( pair. key. productFilter)
556
- allManifests [ index] = ( pair. key. identity, pair. item, productFilter)
557
- } else {
527
+ do {
528
+ let manifestGraphRoots = topLevelManifests. map { identity, manifest in
529
+ KeyedPair (
530
+ manifest,
531
+ key: Key ( identity: identity, productFilter: . everything)
532
+ )
533
+ }
534
+
535
+ var deduplication = [ PackageIdentity: Int] ( )
536
+ try DFS (
537
+ manifestGraphRoots,
538
+ successors: successorManifests
539
+ ) { pair in
558
540
deduplication [ pair. key. identity] = allManifests. count
559
541
allManifests. append ( ( pair. key. identity, pair. item, pair. key. productFilter) )
542
+ } onDuplicate: { old, new in
543
+ let index = deduplication [ old. key. identity] !
544
+ let productFilter = allManifests [ index] . productFilter. merge ( new. key. productFilter)
545
+ allManifests [ index] = ( new. key. identity, new. item, productFilter)
560
546
}
561
547
}
562
548
0 commit comments