@@ -5,13 +5,26 @@ use hamcrest::{assert_that, contains, is_not};
5
5
use cargo:: core:: source:: { GitReference , SourceId } ;
6
6
use cargo:: core:: dependency:: Kind :: { self , Development } ;
7
7
use cargo:: core:: { Dependency , PackageId , Registry , Summary } ;
8
- use cargo:: util:: { CargoResult , ToUrl } ;
8
+ use cargo:: util:: { CargoResult , Config , ToUrl } ;
9
9
use cargo:: core:: resolver:: { self , Method } ;
10
10
11
+ use cargotest:: ChannelChanger ;
12
+ use cargotest:: support:: { execs, project} ;
13
+ use cargotest:: support:: registry:: Package ;
14
+
11
15
fn resolve (
12
16
pkg : & PackageId ,
13
17
deps : Vec < Dependency > ,
14
18
registry : & [ Summary ] ,
19
+ ) -> CargoResult < Vec < PackageId > > {
20
+ resolve_with_config ( pkg, deps, registry, None )
21
+ }
22
+
23
+ fn resolve_with_config (
24
+ pkg : & PackageId ,
25
+ deps : Vec < Dependency > ,
26
+ registry : & [ Summary ] ,
27
+ config : Option < & Config > ,
15
28
) -> CargoResult < Vec < PackageId > > {
16
29
struct MyRegistry < ' a > ( & ' a [ Summary ] ) ;
17
30
impl < ' a > Registry for MyRegistry < ' a > {
@@ -38,7 +51,7 @@ fn resolve(
38
51
& [ ] ,
39
52
& mut registry,
40
53
& HashSet :: new ( ) ,
41
- None ,
54
+ config ,
42
55
false ,
43
56
) ?;
44
57
let res = resolve. iter ( ) . cloned ( ) . collect ( ) ;
@@ -327,6 +340,87 @@ fn test_resolving_maximum_version_with_transitive_deps() {
327
340
assert_that ( & res, is_not ( contains ( names ( & [ ( "util" , "1.1.1" ) ] ) ) ) ) ;
328
341
}
329
342
343
+ #[ test]
344
+ fn test_resolving_minimum_version_with_transitive_deps ( ) {
345
+ // When the minimal-versions config option is specified then the lowest
346
+ // possible version of a package should be selected. "util 1.0.0" can't be
347
+ // selected because of the requirements of "bar", so the minimum version
348
+ // must be 1.1.1.
349
+ let reg = registry ( vec ! [
350
+ pkg!( ( "util" , "1.2.2" ) ) ,
351
+ pkg!( ( "util" , "1.0.0" ) ) ,
352
+ pkg!( ( "util" , "1.1.1" ) ) ,
353
+ pkg!( "foo" => [ dep_req( "util" , "1.0.0" ) ] ) ,
354
+ pkg!( "bar" => [ dep_req( "util" , ">=1.0.1" ) ] ) ,
355
+ ] ) ;
356
+
357
+ let mut config = Config :: default ( ) . unwrap ( ) ;
358
+ config
359
+ . configure (
360
+ 1 ,
361
+ None ,
362
+ & None ,
363
+ false ,
364
+ false ,
365
+ & [ "minimal-versions" . to_string ( ) ] ,
366
+ )
367
+ . unwrap ( ) ;
368
+
369
+ let res = resolve_with_config (
370
+ & pkg_id ( "root" ) ,
371
+ vec ! [ dep_req( "foo" , "1.0.0" ) , dep_req( "bar" , "1.0.0" ) ] ,
372
+ & reg,
373
+ Some ( & config) ,
374
+ ) . unwrap ( ) ;
375
+
376
+ assert_that (
377
+ & res,
378
+ contains ( names ( & [
379
+ ( "root" , "1.0.0" ) ,
380
+ ( "foo" , "1.0.0" ) ,
381
+ ( "bar" , "1.0.0" ) ,
382
+ ( "util" , "1.1.1" ) ,
383
+ ] ) ) ,
384
+ ) ;
385
+ assert_that ( & res, is_not ( contains ( names ( & [ ( "util" , "1.2.2" ) ] ) ) ) ) ;
386
+ assert_that ( & res, is_not ( contains ( names ( & [ ( "util" , "1.0.0" ) ] ) ) ) ) ;
387
+ }
388
+
389
+ // Ensure that the "-Z minimal-versions" CLI option works and the minimal
390
+ // version of a dependency ends up in the lock file.
391
+ #[ test]
392
+ fn minimal_version_cli ( ) {
393
+ Package :: new ( "dep" , "1.0.0" ) . publish ( ) ;
394
+ Package :: new ( "dep" , "1.1.0" ) . publish ( ) ;
395
+
396
+ let p = project ( "foo" )
397
+ . file (
398
+ "Cargo.toml" ,
399
+ r#"
400
+ [package]
401
+ name = "foo"
402
+ authors = []
403
+ version = "0.0.1"
404
+
405
+ [dependencies]
406
+ dep = "1.0"
407
+ "# ,
408
+ )
409
+ . file ( "src/main.rs" , "fn main() {}" )
410
+ . build ( ) ;
411
+
412
+ assert_that (
413
+ p. cargo ( "generate-lockfile" )
414
+ . masquerade_as_nightly_cargo ( )
415
+ . arg ( "-Zminimal-versions" ) ,
416
+ execs ( ) . with_status ( 0 ) ,
417
+ ) ;
418
+
419
+ let lock = p. read_lockfile ( ) ;
420
+
421
+ assert ! ( lock. contains( "dep 1.0.0" ) ) ;
422
+ }
423
+
330
424
#[ test]
331
425
fn resolving_incompat_versions ( ) {
332
426
let reg = registry ( vec ! [
0 commit comments