@@ -17,7 +17,7 @@ use crate::ops::{self, CompileFilter, CompileOptions};
17
17
use crate :: sources:: PathSource ;
18
18
use crate :: util:: errors:: CargoResult ;
19
19
use crate :: util:: interning:: InternedString ;
20
- use crate :: util:: Config ;
20
+ use crate :: util:: { Config , OptVersionReq } ;
21
21
use crate :: util:: { FileLock , Filesystem } ;
22
22
23
23
/// On-disk tracking for which package installed which binary.
@@ -522,25 +522,6 @@ pub fn path_source(source_id: SourceId, config: &Config) -> CargoResult<PathSour
522
522
Ok ( PathSource :: new ( & path, source_id, config) )
523
523
}
524
524
525
- fn is_package_name_a_git_url ( package_name : & InternedString ) -> bool {
526
- if let Ok ( url) = Url :: parse ( package_name) {
527
- if let Some ( domain) = url. domain ( ) {
528
- // REVIEW
529
- // Are there any other git services without "git"
530
- // in the domain?
531
- // bitbucket?
532
- // Is it possible to ask the cargo/crates team for
533
- // some stats where crates projects are currently hosted on
534
- return domain. contains ( "git" ) ;
535
- }
536
- }
537
- false
538
- }
539
-
540
- fn was_git_url_miscategorised_as_a_registry_dep ( dep : & Dependency ) -> bool {
541
- return dep. source_id ( ) . is_registry ( ) && is_package_name_a_git_url ( & dep. package_name ( ) ) ;
542
- }
543
-
544
525
/// Gets a Package based on command-line requirements.
545
526
pub fn select_dep_pkg < T > (
546
527
source : & mut T ,
@@ -566,47 +547,115 @@ where
566
547
Poll :: Pending => source. block_until_ready ( ) ?,
567
548
}
568
549
} ;
569
- match deps. iter ( ) . map ( |p| p. package_id ( ) ) . max ( ) {
570
- Some ( pkgid) => {
571
- let pkg = Box :: new ( source) . download_now ( pkgid, config) ?;
572
- Ok ( pkg)
550
+ if let Some ( pkgid) = deps. iter ( ) . map ( |p| p. package_id ( ) ) . max ( ) {
551
+ let pkg = Box :: new ( source) . download_now ( pkgid, config) ?;
552
+ Ok ( pkg)
553
+ } else {
554
+ let spe = SelectPackageError :: new ( dep, source) ;
555
+ bail ! ( anyhow:: Error :: from( spe) )
556
+ }
557
+ }
558
+
559
+ struct YankedInfo {
560
+ package_name : InternedString ,
561
+ source_id : SourceId ,
562
+ }
563
+
564
+ struct PackageNotFound {
565
+ package_name : InternedString ,
566
+ source_id : SourceId ,
567
+ // REVIEW make it a reference or is cloning ok?
568
+ version_req : OptVersionReq ,
569
+ }
570
+
571
+ enum SelectPackageError {
572
+ /// Return when the Package had been yanked from the Registry
573
+ Yanked ( YankedInfo ) ,
574
+ // Return when someone accidentally passed a git(hub|lab|ea) URL as the package name
575
+ UrlTreatedAsPackageName ( PackageNotFound ) ,
576
+ // Catch-all variant for all other errors
577
+ CouldntFindInRegistry ( PackageNotFound ) ,
578
+ }
579
+
580
+ fn is_package_name_a_git_url ( package_name : & InternedString ) -> bool {
581
+ if let Ok ( url) = Url :: parse ( package_name) {
582
+ if let Some ( domain) = url. domain ( ) {
583
+ // REVIEW
584
+ // Are there any other git services without "git"
585
+ // in the domain?
586
+ // bitbucket?
587
+ // Is it possible to ask the cargo/crates team for
588
+ // some stats where crates projects are currently hosted on
589
+ return domain. contains ( "git" ) ;
573
590
}
574
- None => {
575
- let is_yanked: bool = if dep. version_req ( ) . is_exact ( ) {
576
- let version: String = dep. version_req ( ) . to_string ( ) ;
577
- PackageId :: new ( dep. package_name ( ) , & version[ 1 ..] , source. source_id ( ) )
578
- . map_or ( false , |pkg_id| source. is_yanked ( pkg_id) . unwrap_or ( false ) )
579
- } else {
580
- false
581
- } ;
582
- if is_yanked {
583
- bail ! (
584
- "cannot install package `{}`, it has been yanked from {}" ,
585
- dep. package_name( ) ,
586
- source. source_id( )
587
- )
591
+ }
592
+ false
593
+ }
594
+
595
+ fn was_git_url_miscategorised_as_a_registry_dep ( dep : & Dependency ) -> bool {
596
+ return dep. source_id ( ) . is_registry ( ) && is_package_name_a_git_url ( & dep. package_name ( ) ) ;
597
+ }
598
+
599
+ impl SelectPackageError {
600
+ fn new < T > ( dep : Dependency , source : & mut T ) -> Self
601
+ where
602
+ T : Source ,
603
+ {
604
+ let is_yanked: bool = if dep. version_req ( ) . is_exact ( ) {
605
+ let version: String = dep. version_req ( ) . to_string ( ) ;
606
+ PackageId :: new ( dep. package_name ( ) , & version[ 1 ..] , source. source_id ( ) )
607
+ . map_or ( false , |pkg_id| source. is_yanked ( pkg_id) . unwrap_or ( false ) )
608
+ } else {
609
+ false
610
+ } ;
611
+ if is_yanked {
612
+ SelectPackageError :: Yanked ( YankedInfo {
613
+ package_name : dep. package_name ( ) ,
614
+ source_id : source. source_id ( ) ,
615
+ } )
616
+ } else {
617
+ if was_git_url_miscategorised_as_a_registry_dep ( & dep) {
618
+ SelectPackageError :: UrlTreatedAsPackageName ( PackageNotFound {
619
+ package_name : dep. package_name ( ) ,
620
+ source_id : source. source_id ( ) ,
621
+ version_req : dep. version_req ( ) . clone ( ) ,
622
+ } )
588
623
} else {
589
- if was_git_url_miscategorised_as_a_registry_dep ( & dep) {
590
- bail ! (
591
- "could not find `{}` in {} with version `{}`. Try adding `--git {}`" ,
592
- dep. package_name( ) ,
593
- source. source_id( ) ,
594
- dep. version_req( ) ,
595
- dep. package_name( ) ,
596
- )
597
- } else {
598
- bail ! (
599
- "could not find `{}` in {} with version `{}`" ,
600
- dep. package_name( ) ,
601
- source. source_id( ) ,
602
- dep. version_req( ) ,
603
- )
604
- }
624
+ SelectPackageError :: CouldntFindInRegistry ( PackageNotFound {
625
+ package_name : dep. package_name ( ) ,
626
+ source_id : source. source_id ( ) ,
627
+ version_req : dep. version_req ( ) . clone ( ) ,
628
+ } )
605
629
}
606
630
}
607
631
}
608
632
}
609
633
634
+ impl From < SelectPackageError > for anyhow:: Error {
635
+ fn from ( err : SelectPackageError ) -> Self {
636
+ match err {
637
+ SelectPackageError :: Yanked ( info) => anyhow:: anyhow!(
638
+ "cannot install package `{}`, it has been yanked from {}" ,
639
+ info. package_name,
640
+ info. source_id
641
+ ) ,
642
+ SelectPackageError :: UrlTreatedAsPackageName ( pkg_not_found) => anyhow:: anyhow!(
643
+ "could not find `{}` in {} with version `{}`. Try adding `--git {}`" ,
644
+ pkg_not_found. package_name,
645
+ pkg_not_found. source_id,
646
+ pkg_not_found. version_req,
647
+ pkg_not_found. package_name,
648
+ ) ,
649
+ SelectPackageError :: CouldntFindInRegistry ( pkg_not_found) => anyhow:: anyhow!(
650
+ "could not find `{}` in {} with version `{}`" ,
651
+ pkg_not_found. package_name,
652
+ pkg_not_found. source_id,
653
+ pkg_not_found. version_req,
654
+ ) ,
655
+ }
656
+ }
657
+ }
658
+
610
659
pub fn select_pkg < T , F > (
611
660
source : & mut T ,
612
661
dep : Option < Dependency > ,
0 commit comments