@@ -45,7 +45,7 @@ use super::markdown::md;
4545use super :: term2;
4646use crate :: dist:: dist:: { self , Profile , TargetTriple } ;
4747use crate :: process;
48- use crate :: toolchain:: DistributableToolchain ;
48+ use crate :: toolchain:: { DistributableToolchain , Toolchain } ;
4949use crate :: utils:: utils;
5050use crate :: utils:: Notification ;
5151use crate :: { Cfg , UpdateStatus } ;
@@ -721,6 +721,39 @@ fn maybe_install_rust(
721721 quiet : bool ,
722722) -> Result < ( ) > {
723723 let mut cfg = common:: set_globals ( verbose, quiet) ?;
724+
725+ let toolchain = _install_selection (
726+ & mut cfg,
727+ toolchain,
728+ profile_str,
729+ default_host_triple,
730+ update_existing_toolchain,
731+ components,
732+ targets,
733+ ) ?;
734+ if let Some ( toolchain) = toolchain {
735+ if toolchain. exists ( ) {
736+ warn ! ( "Updating existing toolchain, profile choice will be ignored" ) ;
737+ }
738+ let distributable = DistributableToolchain :: new ( & toolchain) ?;
739+ let status = distributable. install_from_dist ( true , false , components, targets) ?;
740+ let toolchain_str = toolchain. name ( ) . to_owned ( ) ;
741+ toolchain. cfg ( ) . set_default ( & toolchain_str) ?;
742+ writeln ! ( process( ) . stdout( ) ) ?;
743+ common:: show_channel_update ( & toolchain. cfg ( ) , & toolchain_str, Ok ( status) ) ?;
744+ }
745+ Ok ( ( ) )
746+ }
747+
748+ fn _install_selection < ' a > (
749+ cfg : & ' a mut Cfg ,
750+ toolchain_opt : Option < & str > ,
751+ profile_str : & str ,
752+ default_host_triple : Option < & str > ,
753+ update_existing_toolchain : bool ,
754+ components : & [ & str ] ,
755+ targets : & [ & str ] ,
756+ ) -> Result < Option < Toolchain < ' a > > > {
724757 cfg. set_profile ( profile_str) ?;
725758
726759 if let Some ( default_host_triple) = default_host_triple {
@@ -731,7 +764,7 @@ fn maybe_install_rust(
731764 info ! ( "default host triple is {}" , cfg. get_default_host_triple( ) ?) ;
732765 }
733766
734- let user_specified_something = toolchain . is_some ( )
767+ let user_specified_something = toolchain_opt . is_some ( )
735768 || !targets. is_empty ( )
736769 || !components. is_empty ( )
737770 || update_existing_toolchain;
@@ -741,7 +774,7 @@ fn maybe_install_rust(
741774 // a toolchain (updating if it's already present) and then if neither of
742775 // those are true, we have a user who doesn't mind, and already has an
743776 // install, so we leave their setup alone.
744- if toolchain == Some ( "none" ) {
777+ Ok ( if toolchain_opt == Some ( "none" ) {
745778 info ! ( "skipping toolchain installation" ) ;
746779 if !components. is_empty ( ) {
747780 warn ! (
@@ -758,28 +791,20 @@ fn maybe_install_rust(
758791 ) ;
759792 }
760793 writeln ! ( process( ) . stdout( ) ) ?;
794+ None
761795 } else if user_specified_something || cfg. find_default ( ) ?. is_none ( ) {
762- let ( toolchain_str , toolchain ) = match toolchain {
763- Some ( s) => ( s . to_owned ( ) , cfg. get_toolchain ( s, false ) ?) ,
796+ Some ( match toolchain_opt {
797+ Some ( s) => cfg. get_toolchain ( s, false ) ?,
764798 None => match cfg. find_default ( ) ? {
765- Some ( t) => ( t . name ( ) . to_owned ( ) , t ) ,
766- None => ( "stable" . to_owned ( ) , cfg. get_toolchain ( "stable" , false ) ?) ,
799+ Some ( t) => t ,
800+ None => cfg. get_toolchain ( "stable" , false ) ?,
767801 } ,
768- } ;
769- if toolchain. exists ( ) {
770- warn ! ( "Updating existing toolchain, profile choice will be ignored" ) ;
771- }
772- let distributable = DistributableToolchain :: new ( & toolchain) ?;
773- let status = distributable. install_from_dist ( true , false , components, targets) ?;
774- cfg. set_default ( & toolchain_str) ?;
775- writeln ! ( process( ) . stdout( ) ) ?;
776- common:: show_channel_update ( & cfg, & toolchain_str, Ok ( status) ) ?;
802+ } )
777803 } else {
778804 info ! ( "updating existing rustup installation - leaving toolchains alone" ) ;
779805 writeln ! ( process( ) . stdout( ) ) ?;
780- }
781-
782- Ok ( ( ) )
806+ None
807+ } )
783808}
784809
785810pub fn uninstall ( no_prompt : bool ) -> Result < utils:: ExitCode > {
@@ -1060,3 +1085,59 @@ pub fn cleanup_self_updater() -> Result<()> {
10601085
10611086 Ok ( ( ) )
10621087}
1088+
1089+ #[ cfg( test) ]
1090+ mod test {
1091+ use std:: collections:: HashMap ;
1092+
1093+ use crate :: cli:: common;
1094+ use crate :: dist:: dist:: ToolchainDesc ;
1095+ use crate :: test:: with_rustup_home;
1096+ use crate :: { currentprocess, for_host} ;
1097+
1098+ #[ test]
1099+ fn default_toolchain_is_stable ( ) {
1100+ with_rustup_home ( |home| {
1101+ let mut vars = HashMap :: new ( ) ;
1102+ home. apply ( & mut vars) ;
1103+ let tp = Box :: new ( currentprocess:: TestProcess {
1104+ vars,
1105+ ..Default :: default ( )
1106+ } ) ;
1107+ currentprocess:: with ( tp. clone ( ) , || -> anyhow:: Result < ( ) > {
1108+ // TODO: we could pass in a custom cfg to get notification
1109+ // callbacks rather than output to the tp sink.
1110+ let mut cfg = common:: set_globals ( false , false ) . unwrap ( ) ;
1111+ assert_eq ! (
1112+ "stable" ,
1113+ super :: _install_selection(
1114+ & mut cfg,
1115+ None , // No toolchain specified
1116+ "default" , // default profile
1117+ None ,
1118+ false ,
1119+ & [ ] ,
1120+ & [ ] ,
1121+ )
1122+ . unwrap( ) // result
1123+ . unwrap( ) // option
1124+ . name( )
1125+ . parse:: <ToolchainDesc >( )
1126+ . unwrap( )
1127+ . channel
1128+ ) ;
1129+ Ok ( ( ) )
1130+ } ) ?;
1131+ assert_eq ! (
1132+ for_host!(
1133+ r"info: profile set to 'default'
1134+ info: default host triple is {0}
1135+ "
1136+ ) ,
1137+ & String :: from_utf8( tp. get_stderr( ) ) . unwrap( )
1138+ ) ;
1139+ Ok ( ( ) )
1140+ } )
1141+ . unwrap ( ) ;
1142+ }
1143+ }
0 commit comments