@@ -529,30 +529,21 @@ impl<'a> DistributableToolchain<'a> {
529
529
530
530
// Installed only.
531
531
pub ( crate ) fn add_component ( & self , mut component : Component ) -> Result < ( ) > {
532
- if !self . 0 . exists ( ) {
533
- return Err ( RustupError :: ToolchainNotInstalled ( self . 0 . name . to_owned ( ) ) . into ( ) ) ;
534
- }
535
-
536
- let toolchain = & self . 0 . name ;
537
- let toolchain = ToolchainDesc :: from_str ( toolchain) . expect ( "must be valid" ) ;
538
-
539
- let prefix = InstallPrefix :: from ( self . 0 . path . to_owned ( ) ) ;
540
- let manifestation = Manifestation :: open ( prefix, toolchain. target . clone ( ) ) ?;
541
-
542
- if let Some ( manifest) = manifestation. load_manifest ( ) ? {
532
+ if let Some ( desc) = self . get_toolchain_desc_with_manifest ( ) ? {
543
533
// Rename the component if necessary.
544
- if let Some ( c) = manifest. rename_component ( & component) {
534
+ if let Some ( c) = desc . manifest . rename_component ( & component) {
545
535
component = c;
546
536
}
547
537
548
538
// Validate the component name
549
- let rust_pkg = manifest
539
+ let rust_pkg = desc
540
+ . manifest
550
541
. packages
551
542
. get ( "rust" )
552
543
. expect ( "manifest should contain a rust package" ) ;
553
544
let targ_pkg = rust_pkg
554
545
. targets
555
- . get ( & toolchain. target )
546
+ . get ( & desc . toolchain . target )
556
547
. expect ( "installed manifest should have a known target" ) ;
557
548
558
549
if !targ_pkg. components . contains ( & component) {
@@ -562,8 +553,12 @@ impl<'a> DistributableToolchain<'a> {
562
553
} else {
563
554
return Err ( RustupError :: UnknownComponent {
564
555
name : self . 0 . name . to_string ( ) ,
565
- component : component. description ( & manifest) ,
566
- suggestion : self . get_component_suggestion ( & component, & manifest, false ) ,
556
+ component : component. description ( & desc. manifest ) ,
557
+ suggestion : self . get_component_suggestion (
558
+ & component,
559
+ & desc. manifest ,
560
+ false ,
561
+ ) ,
567
562
}
568
563
. into ( ) ) ;
569
564
}
@@ -574,13 +569,13 @@ impl<'a> DistributableToolchain<'a> {
574
569
remove_components : vec ! [ ] ,
575
570
} ;
576
571
577
- manifestation. update (
578
- & manifest,
572
+ desc . manifestation . update (
573
+ & desc . manifest ,
579
574
changes,
580
575
false ,
581
576
& self . download_cfg ( ) ,
582
577
& self . download_cfg ( ) . notify_handler ,
583
- & toolchain. manifest_name ( ) ,
578
+ & desc . toolchain . manifest_name ( ) ,
584
579
false ,
585
580
) ?;
586
581
@@ -737,17 +732,7 @@ impl<'a> DistributableToolchain<'a> {
737
732
738
733
// Installed only.
739
734
pub ( crate ) fn get_manifest ( & self ) -> Result < Option < Manifest > > {
740
- if !self . 0 . exists ( ) {
741
- bail ! ( RustupError :: ToolchainNotInstalled ( self . 0 . name( ) . to_owned( ) ) ) ;
742
- }
743
-
744
- let toolchain = & self . 0 . name ( ) ;
745
- let toolchain = ToolchainDesc :: from_str ( toolchain) ?;
746
-
747
- let prefix = InstallPrefix :: from ( self . 0 . path ( ) . to_owned ( ) ) ;
748
- let manifestation = Manifestation :: open ( prefix, toolchain. target ) ?;
749
-
750
- manifestation. load_manifest ( )
735
+ Ok ( self . get_toolchain_desc_with_manifest ( ) ?. map ( |d| d. manifest ) )
751
736
}
752
737
753
738
// Not installed only?
@@ -802,102 +787,53 @@ impl<'a> DistributableToolchain<'a> {
802
787
}
803
788
}
804
789
805
- // Installed only.
806
- pub fn list_components ( & self ) -> Result < Vec < ComponentStatus > > {
790
+ pub ( crate ) fn get_toolchain_desc_with_manifest (
791
+ & self ,
792
+ ) -> Result < Option < ToolchainDescWithManifest > > {
807
793
if !self . 0 . exists ( ) {
808
794
bail ! ( RustupError :: ToolchainNotInstalled ( self . 0 . name. to_owned( ) ) ) ;
809
795
}
810
-
811
796
let toolchain = & self . 0 . name ;
812
797
let toolchain = ToolchainDesc :: from_str ( toolchain)
813
798
. context ( RustupError :: ComponentsUnsupported ( self . 0 . name . to_string ( ) ) ) ?;
814
799
815
800
let prefix = InstallPrefix :: from ( self . 0 . path . to_owned ( ) ) ;
816
801
let manifestation = Manifestation :: open ( prefix, toolchain. target . clone ( ) ) ?;
802
+ Ok ( manifestation
803
+ . load_manifest ( ) ?
804
+ . map ( |manifest| ToolchainDescWithManifest {
805
+ toolchain,
806
+ manifestation,
807
+ manifest,
808
+ } ) )
809
+ }
817
810
818
- if let Some ( manifest) = manifestation. load_manifest ( ) ? {
819
- let config = manifestation. read_config ( ) ?;
820
-
821
- // Return all optional components of the "rust" package for the
822
- // toolchain's target triple.
823
- let mut res = Vec :: new ( ) ;
824
-
825
- let rust_pkg = manifest
826
- . packages
827
- . get ( "rust" )
828
- . expect ( "manifest should contain a rust package" ) ;
829
- let targ_pkg = rust_pkg
830
- . targets
831
- . get ( & toolchain. target )
832
- . expect ( "installed manifest should have a known target" ) ;
833
-
834
- for component in & targ_pkg. components {
835
- let installed = config
836
- . as_ref ( )
837
- . map ( |c| component. contained_within ( & c. components ) )
838
- . unwrap_or ( false ) ;
839
-
840
- let component_target = TargetTriple :: new ( & component. target ( ) ) ;
841
-
842
- // Get the component so we can check if it is available
843
- let component_pkg = manifest
844
- . get_package ( component. short_name_in_manifest ( ) )
845
- . unwrap_or_else ( |_| {
846
- panic ! (
847
- "manifest should contain component {}" ,
848
- & component. short_name( & manifest)
849
- )
850
- } ) ;
851
- let component_target_pkg = component_pkg
852
- . targets
853
- . get ( & component_target)
854
- . expect ( "component should have target toolchain" ) ;
855
-
856
- res. push ( ComponentStatus {
857
- component : component. clone ( ) ,
858
- name : component. name ( & manifest) ,
859
- installed,
860
- available : component_target_pkg. available ( ) ,
861
- } ) ;
862
- }
863
-
864
- res. sort_by ( |a, b| a. component . cmp ( & b. component ) ) ;
865
-
866
- Ok ( res)
811
+ pub fn list_components ( & self ) -> Result < Vec < ComponentStatus > > {
812
+ if let Some ( toolchain) = self . get_toolchain_desc_with_manifest ( ) ? {
813
+ toolchain. list_components ( )
867
814
} else {
868
815
Err ( RustupError :: ComponentsUnsupported ( self . 0 . name . to_string ( ) ) . into ( ) )
869
816
}
870
817
}
871
818
872
819
// Installed only.
873
820
pub ( crate ) fn remove_component ( & self , mut component : Component ) -> Result < ( ) > {
874
- // Overlapping code with get_manifest :/.
875
- if !self . 0 . exists ( ) {
876
- return Err ( RustupError :: ToolchainNotInstalled ( self . 0 . name . to_owned ( ) ) . into ( ) ) ;
877
- }
878
-
879
- let toolchain = & self . 0 . name ;
880
- let toolchain = ToolchainDesc :: from_str ( toolchain) . expect ( "must be valid" ) ;
881
-
882
- let prefix = InstallPrefix :: from ( self . 0 . path . to_owned ( ) ) ;
883
- let manifestation = Manifestation :: open ( prefix, toolchain. target . clone ( ) ) ?;
884
-
885
- if let Some ( manifest) = manifestation. load_manifest ( ) ? {
821
+ if let Some ( desc) = self . get_toolchain_desc_with_manifest ( ) ? {
886
822
// Rename the component if necessary.
887
- if let Some ( c) = manifest. rename_component ( & component) {
823
+ if let Some ( c) = desc . manifest . rename_component ( & component) {
888
824
component = c;
889
825
}
890
826
891
- let dist_config = manifestation. read_config ( ) ?. unwrap ( ) ;
827
+ let dist_config = desc . manifestation . read_config ( ) ?. unwrap ( ) ;
892
828
if !dist_config. components . contains ( & component) {
893
829
let wildcard_component = component. wildcard ( ) ;
894
830
if dist_config. components . contains ( & wildcard_component) {
895
831
component = wildcard_component;
896
832
} else {
897
833
return Err ( RustupError :: UnknownComponent {
898
834
name : self . 0 . name . to_string ( ) ,
899
- component : component. description ( & manifest) ,
900
- suggestion : self . get_component_suggestion ( & component, & manifest, true ) ,
835
+ component : component. description ( & desc . manifest ) ,
836
+ suggestion : self . get_component_suggestion ( & component, & desc . manifest , true ) ,
901
837
}
902
838
. into ( ) ) ;
903
839
}
@@ -908,13 +844,13 @@ impl<'a> DistributableToolchain<'a> {
908
844
remove_components : vec ! [ component] ,
909
845
} ;
910
846
911
- manifestation. update (
912
- & manifest,
847
+ desc . manifestation . update (
848
+ & desc . manifest ,
913
849
changes,
914
850
false ,
915
851
& self . download_cfg ( ) ,
916
852
& self . download_cfg ( ) . notify_handler ,
917
- & toolchain. manifest_name ( ) ,
853
+ & desc . toolchain . manifest_name ( ) ,
918
854
false ,
919
855
) ?;
920
856
@@ -972,6 +908,68 @@ impl<'a> DistributableToolchain<'a> {
972
908
}
973
909
}
974
910
911
+ /// Helper type to avoid parsing a manifest more than once
912
+ pub ( crate ) struct ToolchainDescWithManifest {
913
+ toolchain : ToolchainDesc ,
914
+ manifestation : Manifestation ,
915
+ pub manifest : Manifest ,
916
+ }
917
+
918
+ impl ToolchainDescWithManifest {
919
+ pub ( crate ) fn list_components ( & self ) -> Result < Vec < ComponentStatus > > {
920
+ let config = self . manifestation . read_config ( ) ?;
921
+
922
+ // Return all optional components of the "rust" package for the
923
+ // toolchain's target triple.
924
+ let mut res = Vec :: new ( ) ;
925
+
926
+ let rust_pkg = self
927
+ . manifest
928
+ . packages
929
+ . get ( "rust" )
930
+ . expect ( "manifest should contain a rust package" ) ;
931
+ let targ_pkg = rust_pkg
932
+ . targets
933
+ . get ( & self . toolchain . target )
934
+ . expect ( "installed manifest should have a known target" ) ;
935
+
936
+ for component in & targ_pkg. components {
937
+ let installed = config
938
+ . as_ref ( )
939
+ . map ( |c| component. contained_within ( & c. components ) )
940
+ . unwrap_or ( false ) ;
941
+
942
+ let component_target = TargetTriple :: new ( & component. target ( ) ) ;
943
+
944
+ // Get the component so we can check if it is available
945
+ let component_pkg = self
946
+ . manifest
947
+ . get_package ( component. short_name_in_manifest ( ) )
948
+ . unwrap_or_else ( |_| {
949
+ panic ! (
950
+ "manifest should contain component {}" ,
951
+ & component. short_name( & self . manifest)
952
+ )
953
+ } ) ;
954
+ let component_target_pkg = component_pkg
955
+ . targets
956
+ . get ( & component_target)
957
+ . expect ( "component should have target toolchain" ) ;
958
+
959
+ res. push ( ComponentStatus {
960
+ component : component. clone ( ) ,
961
+ name : component. name ( & self . manifest ) ,
962
+ installed,
963
+ available : component_target_pkg. available ( ) ,
964
+ } ) ;
965
+ }
966
+
967
+ res. sort_by ( |a, b| a. component . cmp ( & b. component ) ) ;
968
+
969
+ Ok ( res)
970
+ }
971
+ }
972
+
975
973
impl < ' a > InstalledToolchain < ' a > for DistributableToolchain < ' a > {
976
974
fn installed_paths ( & self ) -> Result < Vec < InstalledPath < ' a > > > {
977
975
let path = & self . 0 . path ;
0 commit comments