@@ -47,6 +47,7 @@ impl Problem {
47
47
) -> ProblemGraph {
48
48
let mut graph = DiGraph :: < ProblemNode , ProblemEdge > :: default ( ) ;
49
49
let mut nodes: HashMap < SolvableId , NodeIndex > = HashMap :: default ( ) ;
50
+ let mut excluded_nodes: HashMap < StringId , NodeIndex > = HashMap :: default ( ) ;
50
51
51
52
let root_node = Self :: add_node ( & mut graph, & mut nodes, SolvableId :: root ( ) ) ;
52
53
let unresolved_node = graph. add_node ( ProblemNode :: UnresolvedDependency ) ;
@@ -58,8 +59,15 @@ impl Problem {
58
59
Clause :: Excluded ( solvable, reason) => {
59
60
tracing:: info!( "{solvable:?} is excluded" ) ;
60
61
let package_node = Self :: add_node ( & mut graph, & mut nodes, * solvable) ;
61
- let conflict = ConflictCause :: Excluded ( * solvable, * reason) ;
62
- graph. add_edge ( root_node, package_node, ProblemEdge :: Conflict ( conflict) ) ;
62
+ let excluded_node = excluded_nodes
63
+ . entry ( * reason)
64
+ . or_insert_with ( || graph. add_node ( ProblemNode :: Excluded ( * reason) ) ) ;
65
+
66
+ graph. add_edge (
67
+ package_node,
68
+ * excluded_node,
69
+ ProblemEdge :: Conflict ( ConflictCause :: Excluded ) ,
70
+ ) ;
63
71
}
64
72
Clause :: Learnt ( ..) => unreachable ! ( ) ,
65
73
& Clause :: Requires ( package_id, version_set_id) => {
@@ -176,6 +184,8 @@ pub enum ProblemNode {
176
184
Solvable ( SolvableId ) ,
177
185
/// Node representing a dependency without candidates
178
186
UnresolvedDependency ,
187
+ /// Node representing an exclude reason
188
+ Excluded ( StringId ) ,
179
189
}
180
190
181
191
impl ProblemNode {
@@ -185,6 +195,9 @@ impl ProblemNode {
185
195
ProblemNode :: UnresolvedDependency => {
186
196
panic ! ( "expected solvable node, found unresolved dependency" )
187
197
}
198
+ ProblemNode :: Excluded ( _) => {
199
+ panic ! ( "expected solvable node, found excluded node" )
200
+ }
188
201
}
189
202
}
190
203
}
@@ -224,7 +237,7 @@ pub enum ConflictCause {
224
237
/// It is forbidden to install multiple instances of the same dependency
225
238
ForbidMultipleInstances ,
226
239
/// The node was excluded
227
- Excluded ( SolvableId , StringId ) ,
240
+ Excluded ,
228
241
}
229
242
230
243
/// Represents a node that has been merged with others
@@ -302,9 +315,7 @@ impl ProblemGraph {
302
315
| ProblemEdge :: Conflict ( ConflictCause :: Locked ( _) ) => {
303
316
"already installed" . to_string ( )
304
317
}
305
- ProblemEdge :: Conflict ( ConflictCause :: Excluded ( _, reason) ) => {
306
- format ! ( "excluded because {}" , pool. resolve_string( * reason) )
307
- }
318
+ ProblemEdge :: Conflict ( ConflictCause :: Excluded ) => "excluded" . to_string ( ) ,
308
319
} ;
309
320
310
321
let target = match target {
@@ -322,6 +333,9 @@ impl ProblemGraph {
322
333
solvable_2. display ( pool) . to_string ( )
323
334
}
324
335
ProblemNode :: UnresolvedDependency => "unresolved" . to_string ( ) ,
336
+ ProblemNode :: Excluded ( reason) => {
337
+ format ! ( "reason: {}" , pool. resolve_string( reason) )
338
+ }
325
339
} ;
326
340
327
341
write ! (
@@ -346,7 +360,7 @@ impl ProblemGraph {
346
360
let mut maybe_merge = HashMap :: new ( ) ;
347
361
for node_id in graph. node_indices ( ) {
348
362
let candidate = match graph[ node_id] {
349
- ProblemNode :: UnresolvedDependency => continue ,
363
+ ProblemNode :: UnresolvedDependency | ProblemNode :: Excluded ( _ ) => continue ,
350
364
ProblemNode :: Solvable ( solvable_id) => {
351
365
if solvable_id. is_root ( ) {
352
366
continue ;
@@ -415,12 +429,10 @@ impl ProblemGraph {
415
429
416
430
// Determine any incoming "exclude" edges to the node. This would indicate that the
417
431
// node is disabled for external reasons.
418
- let excluding_edges = self . graph . edges_directed ( nx, Direction :: Incoming ) . any ( |e| {
419
- matches ! (
420
- e. weight( ) ,
421
- ProblemEdge :: Conflict ( ConflictCause :: Excluded ( _, _) )
422
- )
423
- } ) ;
432
+ let excluding_edges = self
433
+ . graph
434
+ . edges_directed ( nx, Direction :: Incoming )
435
+ . any ( |e| matches ! ( e. weight( ) , ProblemEdge :: Conflict ( ConflictCause :: Excluded ) ) ) ;
424
436
if excluding_edges {
425
437
// Nodes with incoming disabling edges aren't installable
426
438
continue ;
@@ -673,9 +685,12 @@ impl<'pool, VS: VersionSet, N: PackageName + Display, M: SolvableDisplay<VS, N>>
673
685
} ;
674
686
675
687
let excluded = graph
676
- . edges_directed ( candidate, Direction :: Incoming )
688
+ . edges_directed ( candidate, Direction :: Outgoing )
677
689
. find_map ( |e| match e. weight ( ) {
678
- ProblemEdge :: Conflict ( ConflictCause :: Excluded ( _, reason) ) => {
690
+ ProblemEdge :: Conflict ( ConflictCause :: Excluded ) => {
691
+ let ProblemNode :: Excluded ( reason) = graph[ e. target ( ) ] else {
692
+ unreachable ! ( ) ;
693
+ } ;
679
694
Some ( reason)
680
695
}
681
696
_ => None ,
@@ -695,7 +710,7 @@ impl<'pool, VS: VersionSet, N: PackageName + Display, M: SolvableDisplay<VS, N>>
695
710
writeln ! (
696
711
f,
697
712
"{indent}{name} {version} is excluded because {reason}" ,
698
- reason = self . pool. resolve_string( * excluded_reason)
713
+ reason = self . pool. resolve_string( excluded_reason)
699
714
) ?;
700
715
} else if is_leaf {
701
716
writeln ! ( f, "{indent}{name} {version}" ) ?;
@@ -795,7 +810,7 @@ impl<VS: VersionSet, N: PackageName + Display, M: SolvableDisplay<VS, N>> fmt::D
795
810
. display_candidates( self . pool, & [ solvable_id] )
796
811
) ?;
797
812
}
798
- ConflictCause :: Excluded ( _ , _ ) => continue ,
813
+ ConflictCause :: Excluded => continue ,
799
814
} ;
800
815
}
801
816
}
0 commit comments