1
1
use crate :: core:: registry:: PackageRegistry ;
2
2
use crate :: core:: resolver:: features:: { CliFeatures , HasDevUnits } ;
3
+ use crate :: core:: shell:: Verbosity ;
3
4
use crate :: core:: Registry as _;
4
5
use crate :: core:: { PackageId , PackageIdSpec , PackageIdSpecQuery } ;
5
6
use crate :: core:: { Resolve , SourceId , Workspace } ;
@@ -163,15 +164,19 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
163
164
let print_change = |status : & str , msg : String , color : & Style | {
164
165
opts. config . shell ( ) . status_with_color ( status, msg, color)
165
166
} ;
166
- for ( removed, added) in compare_dependency_graphs ( & previous_resolve, & resolve) {
167
- let latest = if let Some ( added) = added
168
- . iter ( )
169
- . rev ( )
170
- . next ( )
171
- . filter ( |p| p. source_id ( ) . is_registry ( ) )
167
+ let mut unchanged_behind = 0 ;
168
+ for ( removed, added, unchanged) in compare_dependency_graphs ( & previous_resolve, & resolve) {
169
+ let highest_present = [ added. iter ( ) . rev ( ) . next ( ) , unchanged. iter ( ) . rev ( ) . next ( ) ]
170
+ . into_iter ( )
171
+ . flatten ( )
172
+ . max_by_key ( |s| s. version ( ) ) ;
173
+ let latest = if let Some ( present) = highest_present. filter ( |p| p. source_id ( ) . is_registry ( ) )
172
174
{
173
- let query =
174
- crate :: core:: dependency:: Dependency :: parse ( added. name ( ) , None , added. source_id ( ) ) ?;
175
+ let query = crate :: core:: dependency:: Dependency :: parse (
176
+ present. name ( ) ,
177
+ None ,
178
+ present. source_id ( ) ,
179
+ ) ?;
175
180
let possibilities = loop {
176
181
match registry. query_vec ( & query, QueryKind :: Exact ) {
177
182
std:: task:: Poll :: Ready ( res) => {
@@ -187,7 +192,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
187
192
. filter ( |s| s. version ( ) . pre . is_empty ( ) )
188
193
. map ( |s| s. version ( ) . clone ( ) )
189
194
. max ( )
190
- . filter ( |v| added . version ( ) < v)
195
+ . filter ( |v| present . version ( ) < v)
191
196
. map ( |v| format ! ( " {warn}(latest: v{v}){warn:#}" ) )
192
197
} else {
193
198
None
@@ -222,6 +227,26 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
222
227
print_change ( "Adding" , format ! ( "{package}{latest}" ) , & style:: NOTE ) ?;
223
228
}
224
229
}
230
+ if !latest. is_empty ( ) {
231
+ if opts. config . shell ( ) . verbosity ( ) == Verbosity :: Verbose {
232
+ for package in & unchanged {
233
+ opts. config . shell ( ) . status_with_color (
234
+ "Unchanged" ,
235
+ format ! ( "{package}{latest}" ) ,
236
+ & anstyle:: Style :: new ( ) . bold ( ) ,
237
+ ) ?;
238
+ }
239
+ } else {
240
+ if !unchanged. is_empty ( ) {
241
+ unchanged_behind += 1 ;
242
+ }
243
+ }
244
+ }
245
+ }
246
+ if 0 < unchanged_behind {
247
+ opts. config . shell ( ) . note ( format ! (
248
+ "Pass `--verbose` to see {unchanged_behind} unchanged dependencies behind latest"
249
+ ) ) ?;
225
250
}
226
251
if opts. dry_run {
227
252
opts. config
@@ -250,7 +275,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
250
275
fn compare_dependency_graphs (
251
276
previous_resolve : & Resolve ,
252
277
resolve : & Resolve ,
253
- ) -> Vec < ( Vec < PackageId > , Vec < PackageId > ) > {
278
+ ) -> Vec < ( Vec < PackageId > , Vec < PackageId > , Vec < PackageId > ) > {
254
279
fn key ( dep : PackageId ) -> ( & ' static str , SourceId ) {
255
280
( dep. name ( ) . as_str ( ) , dep. source_id ( ) )
256
281
}
@@ -259,6 +284,10 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
259
284
a. iter ( ) . filter ( |a| !contains_id ( b, a) ) . cloned ( ) . collect ( )
260
285
}
261
286
287
+ fn vec_intersection ( a : & [ PackageId ] , b : & [ PackageId ] ) -> Vec < PackageId > {
288
+ a. iter ( ) . filter ( |a| contains_id ( b, a) ) . cloned ( ) . collect ( )
289
+ }
290
+
262
291
// Check if a PackageId is present `b` from `a`.
263
292
//
264
293
// Note that this is somewhat more complicated because the equality for source IDs does not
@@ -288,7 +317,7 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
288
317
289
318
// Map `(package name, package source)` to `(removed versions, added versions)`.
290
319
let mut changes = BTreeMap :: new ( ) ;
291
- let empty = ( Vec :: new ( ) , Vec :: new ( ) ) ;
320
+ let empty = ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) ) ;
292
321
for dep in previous_resolve. iter ( ) {
293
322
changes
294
323
. entry ( key ( dep) )
@@ -305,13 +334,15 @@ pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoRes
305
334
}
306
335
307
336
for v in changes. values_mut ( ) {
308
- let ( ref mut old, ref mut new) = * v;
337
+ let ( ref mut old, ref mut new, ref mut other ) = * v;
309
338
old. sort ( ) ;
310
339
new. sort ( ) ;
311
340
let removed = vec_subset ( old, new) ;
312
341
let added = vec_subset ( new, old) ;
342
+ let unchanged = vec_intersection ( new, old) ;
313
343
* old = removed;
314
344
* new = added;
345
+ * other = unchanged;
315
346
}
316
347
debug ! ( "{:#?}" , changes) ;
317
348
0 commit comments