@@ -433,6 +433,7 @@ fn create_input_str_for_pkg_info_dependencies(
433
433
pkg_info : & PkgInfo ,
434
434
dumped_pkgs_info : & mut HashSet < PkgBasicInfo > ,
435
435
all_candidates : & HashMap < PkgTypeAndName , HashMap < PkgBasicInfo , PkgInfo > > ,
436
+ max_latest_versions : i32 ,
436
437
) -> Result < ( ) > {
437
438
// If this package has already been dumped, skip it.
438
439
if dumped_pkgs_info. contains ( & pkg_info. into ( ) ) {
@@ -470,13 +471,33 @@ fn create_input_str_for_pkg_info_dependencies(
470
471
if let Some ( candidates) = candidates {
471
472
let mut found_matched = false ;
472
473
473
- for candidate in candidates {
474
+ let mut candidates_vec: Vec < & PkgInfo > =
475
+ candidates. values ( ) . collect ( ) ;
476
+
477
+ // The sorting below places the larger versions at the front,
478
+ // thus having smaller indexes. This is correct because, in the
479
+ // Clingo solver, our optimization strategy is to minimize the
480
+ // overall weight, and we prefer larger version numbers.
481
+ // Therefore, larger version numbers have smaller weights, and
482
+ // the index here is equivalent to the concept of weight in the
483
+ // Clingo solver.
484
+ candidates_vec. sort_by ( |a, b| {
485
+ b. manifest . version . cmp ( & a. manifest . version )
486
+ } ) ;
487
+
488
+ for ( idx, candidate) in candidates_vec. into_iter ( ) . enumerate ( ) {
489
+ if max_latest_versions >= 0
490
+ && idx >= max_latest_versions as usize
491
+ {
492
+ break ;
493
+ }
494
+
474
495
// Get version requirement from dependency.
475
496
let version_matches = match dependency {
476
497
ManifestDependency :: RegistryDependency {
477
498
version_req,
478
499
..
479
- } => version_req. matches ( & candidate. 1 . manifest . version ) ,
500
+ } => version_req. matches ( & candidate. manifest . version ) ,
480
501
ManifestDependency :: LocalDependency { .. } => {
481
502
// For local dependencies, just return true to
482
503
// match all versions.
@@ -491,31 +512,35 @@ fn create_input_str_for_pkg_info_dependencies(
491
512
pkg_info. manifest. type_and_name. pkg_type,
492
513
pkg_info. manifest. type_and_name. name,
493
514
pkg_info. manifest. version,
494
- candidate. 1 . manifest. type_and_name. pkg_type,
495
- candidate. 1 . manifest. type_and_name. name,
496
- candidate. 1 . manifest. version,
515
+ candidate. manifest. type_and_name. pkg_type,
516
+ candidate. manifest. type_and_name. name,
517
+ candidate. manifest. version,
497
518
) ) ;
498
519
499
520
create_input_str_for_pkg_info_dependencies (
500
521
input_str,
501
- candidate. 1 ,
522
+ candidate,
502
523
dumped_pkgs_info,
503
524
all_candidates,
525
+ max_latest_versions,
504
526
) ?;
505
527
506
528
found_matched = true ;
507
529
}
508
530
}
509
531
510
- if !found_matched {
532
+ if max_latest_versions < 0 && !found_matched {
511
533
return Err ( anyhow ! (
512
534
"Failed to find candidates for {}" ,
513
535
match dependency {
514
536
ManifestDependency :: RegistryDependency {
515
537
pkg_type,
516
538
name,
517
539
version_req,
518
- } => format!( "[{pkg_type}]{name} ({version_req})" ) ,
540
+ } => format!(
541
+ "[{pkg_type}]{name}
542
+ ({version_req})"
543
+ ) ,
519
544
ManifestDependency :: LocalDependency {
520
545
path,
521
546
..
@@ -546,14 +571,14 @@ fn create_input_str_for_pkg_info_dependencies(
546
571
547
572
fn create_input_str_for_pkg_info_without_dependencies (
548
573
input_str : & mut String ,
549
- pkg_info : & PkgBasicInfo ,
574
+ pkg_info : & PkgInfo ,
550
575
weight : & usize ,
551
576
) -> Result < ( ) > {
552
577
input_str. push_str ( & format ! (
553
578
"version_declared(\" {}\" , \" {}\" , \" {}\" , {}).\n " ,
554
- pkg_info. type_and_name. pkg_type,
555
- pkg_info. type_and_name. name,
556
- pkg_info. version,
579
+ pkg_info. manifest . type_and_name. pkg_type,
580
+ pkg_info. manifest . type_and_name. name,
581
+ pkg_info. manifest . version,
557
582
weight
558
583
) ) ;
559
584
@@ -564,18 +589,19 @@ fn create_input_str_for_all_possible_pkgs_info(
564
589
input_str : & mut String ,
565
590
all_candidates : & HashMap < PkgTypeAndName , HashMap < PkgBasicInfo , PkgInfo > > ,
566
591
locked_pkgs : Option < & HashMap < PkgTypeAndName , PkgInfo > > ,
592
+ max_latest_versions : i32 ,
567
593
) -> Result < ( ) > {
568
594
for candidates in all_candidates {
569
- let mut candidates_vec: Vec < PkgBasicInfo > =
570
- candidates. 1 . values ( ) . map ( |pkg_info| pkg_info. into ( ) ) . collect ( ) ;
595
+ let mut candidates_vec: Vec < & PkgInfo > = candidates. 1 . values ( ) . collect ( ) ;
571
596
572
597
// The sorting below places the larger versions at the front, thus
573
598
// having smaller indexes. This is correct because, in the Clingo
574
599
// solver, our optimization strategy is to minimize the overall weight,
575
600
// and we prefer larger version numbers. Therefore, larger version
576
601
// numbers have smaller weights, and the index here is equivalent to the
577
602
// concept of weight in the Clingo solver.
578
- candidates_vec. sort_by ( |a, b| b. cmp ( a) ) ;
603
+ candidates_vec
604
+ . sort_by ( |a, b| b. manifest . version . cmp ( & a. manifest . version ) ) ;
579
605
580
606
// Check if the locked package exists in the candidates. If it does,
581
607
// move it to the front of the candidates_vec so that it has a smaller
@@ -588,26 +614,31 @@ fn create_input_str_for_all_possible_pkgs_info(
588
614
// dependency, do not prioritize any candidate packages.
589
615
if !locked_pkg. is_local_dependency {
590
616
let idx = candidates_vec. iter ( ) . position ( |pkg_info| {
591
- locked_pkg. manifest . version == pkg_info. version
617
+ locked_pkg. manifest . version == pkg_info. manifest . version
592
618
} ) ;
593
619
594
620
if let Some ( idx) = idx {
595
621
candidates_vec. remove ( idx) ;
596
- candidates_vec. insert ( 0 , locked_pkg. into ( ) ) ;
622
+ candidates_vec. insert ( 0 , locked_pkg) ;
597
623
}
598
624
}
599
625
}
600
626
601
627
for ( idx, candidate) in candidates_vec. into_iter ( ) . enumerate ( ) {
628
+ if max_latest_versions >= 0 && idx >= max_latest_versions as usize {
629
+ break ;
630
+ }
631
+
602
632
create_input_str_for_pkg_info_without_dependencies (
603
- input_str, & candidate, & idx,
633
+ input_str, candidate, & idx,
604
634
) ?;
605
635
}
606
636
}
607
637
608
638
Ok ( ( ) )
609
639
}
610
640
641
+ #[ allow( clippy:: too_many_arguments) ]
611
642
async fn create_input_str (
612
643
tman_config : Arc < tokio:: sync:: RwLock < TmanConfig > > ,
613
644
pkg_type : & PkgType ,
@@ -616,6 +647,7 @@ async fn create_input_str(
616
647
all_candidates : & HashMap < PkgTypeAndName , HashMap < PkgBasicInfo , PkgInfo > > ,
617
648
locked_pkgs : Option < & HashMap < PkgTypeAndName , PkgInfo > > ,
618
649
out : Arc < Box < dyn TmanOutput > > ,
650
+ max_latest_versions : i32 ,
619
651
) -> Result < String > {
620
652
let mut input_str = String :: new ( ) ;
621
653
@@ -627,6 +659,7 @@ async fn create_input_str(
627
659
& mut input_str,
628
660
all_candidates,
629
661
locked_pkgs,
662
+ max_latest_versions,
630
663
) ?;
631
664
632
665
create_input_str_for_dependency_relationship (
@@ -644,6 +677,7 @@ async fn create_input_str(
644
677
candidate. 1 ,
645
678
& mut dumped_pkgs_info,
646
679
all_candidates,
680
+ max_latest_versions,
647
681
) ?;
648
682
}
649
683
}
@@ -655,6 +689,7 @@ async fn create_input_str(
655
689
Ok ( input_str)
656
690
}
657
691
692
+ #[ allow( clippy:: too_many_arguments) ]
658
693
pub async fn solve_all (
659
694
tman_config : Arc < tokio:: sync:: RwLock < TmanConfig > > ,
660
695
pkg_type : & PkgType ,
@@ -663,6 +698,7 @@ pub async fn solve_all(
663
698
all_candidates : & HashMap < PkgTypeAndName , HashMap < PkgBasicInfo , PkgInfo > > ,
664
699
locked_pkgs : Option < & HashMap < PkgTypeAndName , PkgInfo > > ,
665
700
out : Arc < Box < dyn TmanOutput > > ,
701
+ max_latest_versions : i32 ,
666
702
) -> SolveResult {
667
703
let input_str = create_input_str (
668
704
tman_config. clone ( ) ,
@@ -672,6 +708,7 @@ pub async fn solve_all(
672
708
all_candidates,
673
709
locked_pkgs,
674
710
out. clone ( ) ,
711
+ max_latest_versions,
675
712
)
676
713
. await ?;
677
714
solve ( tman_config, & input_str, out) . await
0 commit comments