@@ -49,16 +49,6 @@ impl<'env> TreeDisplay<'env> {
49
49
}
50
50
51
51
for dependency in & package. dependencies {
52
- // Skip dependencies that don't apply to the current environment.
53
- if let Some ( environment_markers) = markers {
54
- if !dependency
55
- . complexified_marker
56
- . evaluate ( environment_markers, & [ ] )
57
- {
58
- continue ;
59
- }
60
- }
61
-
62
52
// Insert the package into the graph.
63
53
let package_node = if let Some ( index) = inverse. get ( & package. id ) {
64
54
* index
@@ -78,38 +68,15 @@ impl<'env> TreeDisplay<'env> {
78
68
} ;
79
69
80
70
// Add an edge between the package and the dependency.
81
- if invert {
82
- graph. add_edge (
83
- dependency_node,
84
- package_node,
85
- Edge :: Prod ( Cow :: Owned ( Dependency {
86
- package_id : package. id . clone ( ) ,
87
- extra : dependency. extra . clone ( ) ,
88
- simplified_marker : dependency. simplified_marker . clone ( ) ,
89
- complexified_marker : dependency. complexified_marker . clone ( ) ,
90
- } ) ) ,
91
- ) ;
92
- } else {
93
- graph. add_edge (
94
- package_node,
95
- dependency_node,
96
- Edge :: Prod ( Cow :: Borrowed ( dependency) ) ,
97
- ) ;
98
- }
71
+ graph. add_edge (
72
+ package_node,
73
+ dependency_node,
74
+ Edge :: Prod ( Cow :: Borrowed ( dependency) ) ,
75
+ ) ;
99
76
}
100
77
101
78
for ( extra, dependencies) in & package. optional_dependencies {
102
79
for dependency in dependencies {
103
- // Skip dependencies that don't apply to the current environment.
104
- if let Some ( environment_markers) = markers {
105
- if !dependency
106
- . complexified_marker
107
- . evaluate ( environment_markers, & [ ] )
108
- {
109
- continue ;
110
- }
111
- }
112
-
113
80
// Insert the package into the graph.
114
81
let package_node = if let Some ( index) = inverse. get ( & package. id ) {
115
82
* index
@@ -129,42 +96,16 @@ impl<'env> TreeDisplay<'env> {
129
96
} ;
130
97
131
98
// Add an edge between the package and the dependency.
132
- if invert {
133
- graph. add_edge (
134
- dependency_node,
135
- package_node,
136
- Edge :: Optional (
137
- extra,
138
- Cow :: Owned ( Dependency {
139
- package_id : package. id . clone ( ) ,
140
- extra : dependency. extra . clone ( ) ,
141
- simplified_marker : dependency. simplified_marker . clone ( ) ,
142
- complexified_marker : dependency. complexified_marker . clone ( ) ,
143
- } ) ,
144
- ) ,
145
- ) ;
146
- } else {
147
- graph. add_edge (
148
- package_node,
149
- dependency_node,
150
- Edge :: Optional ( extra, Cow :: Borrowed ( dependency) ) ,
151
- ) ;
152
- }
99
+ graph. add_edge (
100
+ package_node,
101
+ dependency_node,
102
+ Edge :: Optional ( extra, Cow :: Borrowed ( dependency) ) ,
103
+ ) ;
153
104
}
154
105
}
155
106
156
107
for ( group, dependencies) in & package. dev_dependencies {
157
108
for dependency in dependencies {
158
- // Skip dependencies that don't apply to the current environment.
159
- if let Some ( environment_markers) = markers {
160
- if !dependency
161
- . complexified_marker
162
- . evaluate ( environment_markers, & [ ] )
163
- {
164
- continue ;
165
- }
166
- }
167
-
168
109
// Insert the package into the graph.
169
110
let package_node = if let Some ( index) = inverse. get ( & package. id ) {
170
111
* index
@@ -184,56 +125,53 @@ impl<'env> TreeDisplay<'env> {
184
125
} ;
185
126
186
127
// Add an edge between the package and the dependency.
187
- if invert {
188
- graph. add_edge (
189
- dependency_node,
190
- package_node,
191
- Edge :: Dev (
192
- group,
193
- Cow :: Owned ( Dependency {
194
- package_id : package. id . clone ( ) ,
195
- extra : dependency. extra . clone ( ) ,
196
- simplified_marker : dependency. simplified_marker . clone ( ) ,
197
- complexified_marker : dependency. complexified_marker . clone ( ) ,
198
- } ) ,
199
- ) ,
200
- ) ;
201
- } else {
202
- graph. add_edge (
203
- package_node,
204
- dependency_node,
205
- Edge :: Dev ( group, Cow :: Borrowed ( dependency) ) ,
206
- ) ;
207
- }
128
+ graph. add_edge (
129
+ package_node,
130
+ dependency_node,
131
+ Edge :: Dev ( group, Cow :: Borrowed ( dependency) ) ,
132
+ ) ;
208
133
}
209
134
}
210
135
}
211
136
212
137
let mut modified = false ;
213
138
214
- // Filter the graph to those nodes reachable from the root nodes .
215
- if !packages . is_empty ( ) {
139
+ // Step 1: Filter out packages that aren't reachable on this platform .
140
+ if let Some ( environment_markers ) = markers {
216
141
let mut reachable = FxHashSet :: default ( ) ;
217
142
218
- // Perform a DFS from the root nodes to find the reachable nodes.
219
- let mut dfs = Dfs {
220
- stack : graph
221
- . node_indices ( )
222
- . filter ( |index| packages. contains ( & graph[ * index] . name ) )
223
- . collect :: < Vec < _ > > ( ) ,
224
- ..Dfs :: empty ( & graph)
225
- } ;
226
- while let Some ( node) = dfs. next ( & graph) {
143
+ // Perform a DFS from the root nodes to find the reachable nodes, following only the
144
+ // production edges.
145
+ let mut stack = graph
146
+ . node_indices ( )
147
+ . filter ( |index| {
148
+ graph
149
+ . edges_directed ( * index, Direction :: Incoming )
150
+ . next ( )
151
+ . is_none ( )
152
+ } )
153
+ . collect :: < VecDeque < _ > > ( ) ;
154
+ while let Some ( node) = stack. pop_front ( ) {
227
155
reachable. insert ( node) ;
156
+ for edge in graph. edges_directed ( node, Direction :: Outgoing ) {
157
+ if edge
158
+ . weight ( )
159
+ . dependency ( )
160
+ . complexified_marker
161
+ . evaluate ( environment_markers, & [ ] )
162
+ {
163
+ stack. push_back ( edge. target ( ) ) ;
164
+ }
165
+ }
228
166
}
229
167
230
168
// Remove the unreachable nodes from the graph.
231
169
graph. retain_nodes ( |_, index| reachable. contains ( & index) ) ;
232
170
modified = true ;
233
171
}
234
172
235
- // Filter the graph to those that are reachable from production nodes , if `--no-dev` or
236
- // `--only-dev` was specified.
173
+ // Step 2: Filter the graph to those that are reachable in production or development , if
174
+ // `--no-dev` or `-- only-dev` were specified, respectively .
237
175
if dev != DevMode :: Include {
238
176
let mut reachable = FxHashSet :: default ( ) ;
239
177
@@ -268,6 +206,33 @@ impl<'env> TreeDisplay<'env> {
268
206
modified = true ;
269
207
}
270
208
209
+ // Step 3: Reverse the graph.
210
+ if invert {
211
+ graph. reverse ( ) ;
212
+ modified = true ;
213
+ }
214
+
215
+ // Step 4: Filter the graph to those nodes reachable from the target packages.
216
+ if !packages. is_empty ( ) {
217
+ let mut reachable = FxHashSet :: default ( ) ;
218
+
219
+ // Perform a DFS from the root nodes to find the reachable nodes.
220
+ let mut dfs = Dfs {
221
+ stack : graph
222
+ . node_indices ( )
223
+ . filter ( |index| packages. contains ( & graph[ * index] . name ) )
224
+ . collect :: < Vec < _ > > ( ) ,
225
+ ..Dfs :: empty ( & graph)
226
+ } ;
227
+ while let Some ( node) = dfs. next ( & graph) {
228
+ reachable. insert ( node) ;
229
+ }
230
+
231
+ // Remove the unreachable nodes from the graph.
232
+ graph. retain_nodes ( |_, index| reachable. contains ( & index) ) ;
233
+ modified = true ;
234
+ }
235
+
271
236
// If the graph was modified, re-create the inverse map.
272
237
if modified {
273
238
inverse. clear ( ) ;
@@ -307,9 +272,9 @@ impl<'env> TreeDisplay<'env> {
307
272
308
273
match node {
309
274
Node :: Root ( _) => line,
310
- Node :: Dependency ( _) => line,
311
- Node :: OptionalDependency ( extra , _) => format ! ( "{line} (extra: {extra})" ) ,
312
- Node :: DevDependency ( group , _) => format ! ( "{line} (group: {group})" ) ,
275
+ Node :: Dependency ( _, _ ) => line,
276
+ Node :: OptionalDependency ( _ , _, extra ) => format ! ( "{line} (extra: {extra})" ) ,
277
+ Node :: DevDependency ( _ , _, group ) => format ! ( "{line} (group: {group})" ) ,
313
278
}
314
279
} ;
315
280
@@ -330,9 +295,13 @@ impl<'env> TreeDisplay<'env> {
330
295
. graph
331
296
. edges_directed ( self . inverse [ node. package_id ( ) ] , Direction :: Outgoing )
332
297
. map ( |edge| match edge. weight ( ) {
333
- Edge :: Prod ( dependency) => Node :: Dependency ( dependency) ,
334
- Edge :: Optional ( extra, dependency) => Node :: OptionalDependency ( extra, dependency) ,
335
- Edge :: Dev ( group, dependency) => Node :: DevDependency ( group, dependency) ,
298
+ Edge :: Prod ( dependency) => Node :: Dependency ( self . graph [ edge. target ( ) ] , dependency) ,
299
+ Edge :: Optional ( extra, dependency) => {
300
+ Node :: OptionalDependency ( self . graph [ edge. target ( ) ] , dependency, extra)
301
+ }
302
+ Edge :: Dev ( group, dependency) => {
303
+ Node :: DevDependency ( self . graph [ edge. target ( ) ] , dependency, group)
304
+ }
336
305
} )
337
306
. collect :: < Vec < _ > > ( ) ;
338
307
dependencies. sort_unstable ( ) ;
@@ -424,30 +393,40 @@ enum Edge<'env> {
424
393
Dev ( & ' env GroupName , Cow < ' env , Dependency > ) ,
425
394
}
426
395
396
+ impl < ' env > Edge < ' env > {
397
+ fn dependency ( & self ) -> & Dependency {
398
+ match self {
399
+ Self :: Prod ( dependency) => dependency,
400
+ Self :: Optional ( _, dependency) => dependency,
401
+ Self :: Dev ( _, dependency) => dependency,
402
+ }
403
+ }
404
+ }
405
+
427
406
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Ord , PartialOrd ) ]
428
407
enum Node < ' env > {
429
408
Root ( & ' env PackageId ) ,
430
- Dependency ( & ' env Dependency ) ,
431
- OptionalDependency ( & ' env ExtraName , & ' env Dependency ) ,
432
- DevDependency ( & ' env GroupName , & ' env Dependency ) ,
409
+ Dependency ( & ' env PackageId , & ' env Dependency ) ,
410
+ OptionalDependency ( & ' env PackageId , & ' env Dependency , & ' env ExtraName ) ,
411
+ DevDependency ( & ' env PackageId , & ' env Dependency , & ' env GroupName ) ,
433
412
}
434
413
435
414
impl < ' env > Node < ' env > {
436
415
fn package_id ( & self ) -> & ' env PackageId {
437
416
match self {
438
417
Self :: Root ( id) => id,
439
- Self :: Dependency ( dep ) => & dep . package_id ,
440
- Self :: OptionalDependency ( _, dep ) => & dep . package_id ,
441
- Self :: DevDependency ( _, dep ) => & dep . package_id ,
418
+ Self :: Dependency ( id , _ ) => id ,
419
+ Self :: OptionalDependency ( id , _, _ ) => id ,
420
+ Self :: DevDependency ( id , _, _ ) => id ,
442
421
}
443
422
}
444
423
445
424
fn extras ( & self ) -> Option < & BTreeSet < ExtraName > > {
446
425
match self {
447
426
Self :: Root ( _) => None ,
448
- Self :: Dependency ( dep) => Some ( & dep. extra ) ,
449
- Self :: OptionalDependency ( _, dep) => Some ( & dep. extra ) ,
450
- Self :: DevDependency ( _, dep) => Some ( & dep. extra ) ,
427
+ Self :: Dependency ( _ , dep) => Some ( & dep. extra ) ,
428
+ Self :: OptionalDependency ( _, dep, _ ) => Some ( & dep. extra ) ,
429
+ Self :: DevDependency ( _, dep, _ ) => Some ( & dep. extra ) ,
451
430
}
452
431
}
453
432
}
0 commit comments