@@ -950,173 +950,170 @@ impl<'cfg, 'a> DistOptions<'cfg, 'a> {
950950
951951 self
952952 }
953- }
954-
955- // Installs or updates a toolchain from a dist server. If an initial
956- // install then it will be installed with the default components. If
957- // an upgrade then all the existing components will be upgraded.
958- //
959- // Returns the manifest's hash if anything changed.
960- #[ tracing:: instrument( level = "trace" , err( level = "trace" ) , skip_all, fields( profile = ?opts. profile, prefix = %prefix. path( ) . display( ) ) ) ]
961- pub ( crate ) async fn update_from_dist (
962- prefix : & InstallPrefix ,
963- opts : & DistOptions < ' _ , ' _ > ,
964- ) -> Result < Option < String > > {
965- let fresh_install = !prefix. path ( ) . exists ( ) ;
966- // fresh_install means the toolchain isn't present, but hash_exists means there is a stray hash file
967- if fresh_install && opts. update_hash . exists ( ) {
968- warn ! (
969- "removing stray hash file in order to continue: {}" ,
970- opts. update_hash. display( )
971- ) ;
972- std:: fs:: remove_file ( & opts. update_hash ) ?;
973- }
974953
975- let mut fetched = String :: new ( ) ;
976- let mut first_err = None ;
977- let backtrack = opts. toolchain . channel == Channel :: Nightly && opts. toolchain . date . is_none ( ) ;
978- // We want to limit backtracking if we do not already have a toolchain
979- let mut backtrack_limit: Option < i32 > = if opts. toolchain . date . is_some ( ) {
980- None
981- } else {
982- // We limit the backtracking to 21 days by default (half a release cycle).
983- // The limit of 21 days is an arbitrary selection, so we let the user override it.
984- const BACKTRACK_LIMIT_DEFAULT : i32 = 21 ;
985- let provided = opts
986- . dl_cfg
987- . process
988- . var ( "RUSTUP_BACKTRACK_LIMIT" )
989- . ok ( )
990- . and_then ( |v| v. parse ( ) . ok ( ) )
991- . unwrap_or ( BACKTRACK_LIMIT_DEFAULT ) ;
992- Some ( if provided < 1 { 1 } else { provided } )
993- } ;
994-
995- // In case there is no allow-downgrade option set
996- // we never want to backtrack further back than the nightly that's already installed.
997- //
998- // If no nightly is installed, it makes no sense to backtrack beyond the first ever manifest,
999- // which is 2014-12-20 according to
1000- // https://static.rust-lang.org/cargo-dist/index.html.
954+ // Installs or updates a toolchain from a dist server. If an initial
955+ // install then it will be installed with the default components. If
956+ // an upgrade then all the existing components will be upgraded.
1001957 //
1002- // We could arguably use the date of the first rustup release here, but that would break a
1003- // bunch of the tests, which (inexplicably) use 2015-01-01 as their manifest dates.
1004- let first_manifest = date_from_manifest_date ( "2014-12-20" ) . unwrap ( ) ;
1005- let old_manifest = opts
1006- . old_date_version
1007- . as_ref ( )
1008- . and_then ( |( d, _) | date_from_manifest_date ( d) )
1009- . unwrap_or ( first_manifest) ;
1010- let last_manifest = if opts. allow_downgrade {
1011- first_manifest
1012- } else {
1013- old_manifest
1014- } ;
958+ // Returns the manifest's hash if anything changed.
959+ #[ tracing:: instrument( level = "trace" , err( level = "trace" ) , skip_all, fields( profile = ?self . profile, prefix = %prefix. path( ) . display( ) ) ) ]
960+ pub ( crate ) async fn install_into ( & self , prefix : & InstallPrefix ) -> Result < Option < String > > {
961+ let fresh_install = !prefix. path ( ) . exists ( ) ;
962+ // fresh_install means the toolchain isn't present, but hash_exists means there is a stray hash file
963+ if fresh_install && self . update_hash . exists ( ) {
964+ warn ! (
965+ "removing stray hash file in order to continue: {}" ,
966+ self . update_hash. display( )
967+ ) ;
968+ std:: fs:: remove_file ( & self . update_hash ) ?;
969+ }
1015970
1016- let current_manifest = {
1017- let manifestation = Manifestation :: open ( prefix. clone ( ) , opts. toolchain . target . clone ( ) ) ?;
1018- manifestation. load_manifest ( ) ?
1019- } ;
971+ let mut fetched = String :: new ( ) ;
972+ let mut first_err = None ;
973+ let backtrack = self . toolchain . channel == Channel :: Nightly && self . toolchain . date . is_none ( ) ;
974+ // We want to limit backtracking if we do not already have a toolchain
975+ let mut backtrack_limit: Option < i32 > = if self . toolchain . date . is_some ( ) {
976+ None
977+ } else {
978+ // We limit the backtracking to 21 days by default (half a release cycle).
979+ // The limit of 21 days is an arbitrary selection, so we let the user override it.
980+ const BACKTRACK_LIMIT_DEFAULT : i32 = 21 ;
981+ let provided = self
982+ . dl_cfg
983+ . process
984+ . var ( "RUSTUP_BACKTRACK_LIMIT" )
985+ . ok ( )
986+ . and_then ( |v| v. parse ( ) . ok ( ) )
987+ . unwrap_or ( BACKTRACK_LIMIT_DEFAULT ) ;
988+ Some ( if provided < 1 { 1 } else { provided } )
989+ } ;
1020990
1021- let mut toolchain = opts. toolchain . clone ( ) ;
1022- let res = loop {
1023- let result = try_update_from_dist_ (
1024- & opts. dl_cfg ,
1025- & opts. update_hash ,
1026- & toolchain,
1027- match opts. exists {
1028- false => Some ( opts. profile ) ,
1029- true => None ,
1030- } ,
1031- prefix,
1032- opts. force ,
1033- opts. components ,
1034- opts. targets ,
1035- & mut fetched,
1036- opts. cfg ,
1037- )
1038- . await ;
991+ // In case there is no allow-downgrade option set
992+ // we never want to backtrack further back than the nightly that's already installed.
993+ //
994+ // If no nightly is installed, it makes no sense to backtrack beyond the first ever manifest,
995+ // which is 2014-12-20 according to
996+ // https://static.rust-lang.org/cargo-dist/index.html.
997+ //
998+ // We could arguably use the date of the first rustup release here, but that would break a
999+ // bunch of the tests, which (inexplicably) use 2015-01-01 as their manifest dates.
1000+ let first_manifest = date_from_manifest_date ( "2014-12-20" ) . unwrap ( ) ;
1001+ let old_manifest = self
1002+ . old_date_version
1003+ . as_ref ( )
1004+ . and_then ( |( d, _) | date_from_manifest_date ( d) )
1005+ . unwrap_or ( first_manifest) ;
1006+ let last_manifest = if self . allow_downgrade {
1007+ first_manifest
1008+ } else {
1009+ old_manifest
1010+ } ;
10391011
1040- let e = match result {
1041- Ok ( v) => break Ok ( v) ,
1042- Err ( e) if !backtrack => break Err ( e) ,
1043- Err ( e) => e,
1012+ let current_manifest = {
1013+ let manifestation = Manifestation :: open ( prefix. clone ( ) , self . toolchain . target . clone ( ) ) ?;
1014+ manifestation. load_manifest ( ) ?
10441015 } ;
10451016
1046- let cause = e. downcast_ref :: < DistError > ( ) ;
1047- match cause {
1048- Some ( DistError :: ToolchainComponentsMissing ( components, manifest, ..) ) => {
1049- let plural = if components. len ( ) > 1 { "s" } else { "" } ;
1050- let manifest = current_manifest. as_ref ( ) . unwrap_or ( manifest) ;
1051- let components = components
1052- . iter ( )
1053- . map (
1054- |component| match component. target . as_ref ( ) == Some ( & toolchain. target ) {
1055- true => component. short_name ( manifest) ,
1056- false => component. name ( manifest) ,
1057- } ,
1058- )
1059- . join ( ", " ) ;
1060- info ! ( "skipping nightly with missing component{plural}: {components}" ) ;
1017+ let mut toolchain = self . toolchain . clone ( ) ;
1018+ let res = loop {
1019+ let result = try_update_from_dist_ (
1020+ & self . dl_cfg ,
1021+ & self . update_hash ,
1022+ & toolchain,
1023+ match self . exists {
1024+ false => Some ( self . profile ) ,
1025+ true => None ,
1026+ } ,
1027+ prefix,
1028+ self . force ,
1029+ self . components ,
1030+ self . targets ,
1031+ & mut fetched,
1032+ self . cfg ,
1033+ )
1034+ . await ;
1035+
1036+ let e = match result {
1037+ Ok ( v) => break Ok ( v) ,
1038+ Err ( e) if !backtrack => break Err ( e) ,
1039+ Err ( e) => e,
1040+ } ;
10611041
1062- if first_err. is_none ( ) {
1063- first_err = Some ( e) ;
1042+ let cause = e. downcast_ref :: < DistError > ( ) ;
1043+ match cause {
1044+ Some ( DistError :: ToolchainComponentsMissing ( components, manifest, ..) ) => {
1045+ let plural = if components. len ( ) > 1 { "s" } else { "" } ;
1046+ let manifest = current_manifest. as_ref ( ) . unwrap_or ( manifest) ;
1047+ let components = components
1048+ . iter ( )
1049+ . map ( |component| {
1050+ match component. target . as_ref ( ) == Some ( & toolchain. target ) {
1051+ true => component. short_name ( manifest) ,
1052+ false => component. name ( manifest) ,
1053+ }
1054+ } )
1055+ . join ( ", " ) ;
1056+ info ! ( "skipping nightly with missing component{plural}: {components}" ) ;
1057+
1058+ if first_err. is_none ( ) {
1059+ first_err = Some ( e) ;
1060+ }
1061+ // We decrement the backtrack count only on unavailable component errors
1062+ // so that the limit only applies to nightlies that were indeed available,
1063+ // and ignores missing ones.
1064+ backtrack_limit = backtrack_limit. map ( |n| n - 1 ) ;
10641065 }
1065- // We decrement the backtrack count only on unavailable component errors
1066- // so that the limit only applies to nightlies that were indeed available,
1067- // and ignores missing ones.
1068- backtrack_limit = backtrack_limit. map ( |n| n - 1 ) ;
1069- }
10701066
1071- Some ( DistError :: MissingReleaseForToolchain ( ..) ) => {
1072- // no need to even print anything for missing nightlies,
1073- // since we don't really "skip" them
1067+ Some ( DistError :: MissingReleaseForToolchain ( ..) ) => {
1068+ // no need to even print anything for missing nightlies,
1069+ // since we don't really "skip" them
1070+ }
1071+ _ => {
1072+ // All other errors break the loop
1073+ break Err ( e) ;
1074+ }
1075+ } ;
1076+
1077+ if let Some ( backtrack_limit) = backtrack_limit
1078+ && backtrack_limit < 1
1079+ {
1080+ // This unwrap is safe because we can only hit this if we've
1081+ // had a chance to set first_err
1082+ break Err ( first_err. unwrap ( ) ) ;
10741083 }
1075- _ => {
1076- // All other errors break the loop
1077- break Err ( e) ;
1084+
1085+ // The user asked to update their nightly, but the latest nightly does not have all
1086+ // the components that the user currently has installed. Let's try the previous
1087+ // nightlies in reverse chronological order until we find a nightly that does,
1088+ // starting at one date earlier than the current manifest's date.
1089+ let toolchain_date = toolchain. date . as_ref ( ) . unwrap_or ( & fetched) ;
1090+ let try_next = date_from_manifest_date ( toolchain_date)
1091+ . unwrap_or_else ( || panic ! ( "Malformed manifest date: {toolchain_date:?}" ) )
1092+ . pred_opt ( )
1093+ . unwrap ( ) ;
1094+
1095+ if try_next < last_manifest {
1096+ // Wouldn't be an update if we go further back than the user's current nightly.
1097+ if let Some ( e) = first_err {
1098+ break Err ( e) ;
1099+ } else {
1100+ // In this case, all newer nightlies are missing, which means there are no
1101+ // updates, so the user is already at the latest nightly.
1102+ break Ok ( None ) ;
1103+ }
10781104 }
1079- } ;
10801105
1081- if let Some ( backtrack_limit) = backtrack_limit
1082- && backtrack_limit < 1
1083- {
1084- // This unwrap is safe because we can only hit this if we've
1085- // had a chance to set first_err
1086- break Err ( first_err. unwrap ( ) ) ;
1087- }
1106+ toolchain. date = Some ( try_next. format ( "%Y-%m-%d" ) . to_string ( ) ) ;
1107+ } ;
10881108
1089- // The user asked to update their nightly, but the latest nightly does not have all
1090- // the components that the user currently has installed. Let's try the previous
1091- // nightlies in reverse chronological order until we find a nightly that does,
1092- // starting at one date earlier than the current manifest's date.
1093- let toolchain_date = toolchain. date . as_ref ( ) . unwrap_or ( & fetched) ;
1094- let try_next = date_from_manifest_date ( toolchain_date)
1095- . unwrap_or_else ( || panic ! ( "Malformed manifest date: {toolchain_date:?}" ) )
1096- . pred_opt ( )
1097- . unwrap ( ) ;
1098-
1099- if try_next < last_manifest {
1100- // Wouldn't be an update if we go further back than the user's current nightly.
1101- if let Some ( e) = first_err {
1102- break Err ( e) ;
1103- } else {
1104- // In this case, all newer nightlies are missing, which means there are no
1105- // updates, so the user is already at the latest nightly.
1106- break Ok ( None ) ;
1107- }
1109+ // Don't leave behind an empty / broken installation directory
1110+ if res. is_err ( ) && fresh_install {
1111+ // FIXME Ignoring cascading errors
1112+ let _ = utils:: remove_dir ( "toolchain" , prefix. path ( ) ) ;
11081113 }
11091114
1110- toolchain. date = Some ( try_next. format ( "%Y-%m-%d" ) . to_string ( ) ) ;
1111- } ;
1112-
1113- // Don't leave behind an empty / broken installation directory
1114- if res. is_err ( ) && fresh_install {
1115- // FIXME Ignoring cascading errors
1116- let _ = utils:: remove_dir ( "toolchain" , prefix. path ( ) ) ;
1115+ res
11171116 }
1118-
1119- res
11201117}
11211118
11221119#[ allow( clippy:: too_many_arguments) ]
0 commit comments