@@ -18,7 +18,9 @@ extern crate log;
1818extern crate pbr;
1919#[ cfg( test) ]
2020extern crate quickcheck;
21+ extern crate regex;
2122extern crate reqwest;
23+ extern crate rustc_version;
2224extern crate structopt;
2325extern crate tar;
2426extern crate tee;
@@ -35,13 +37,15 @@ use std::path::{Path, PathBuf};
3537use std:: process:: { self , Command , Stdio } ;
3638use std:: str:: FromStr ;
3739
38- use chrono:: { Date , Duration , Utc } ;
40+ use chrono:: { Date , Duration , naive , Utc } ;
3941use dialoguer:: Select ;
4042use failure:: Error ;
4143use flate2:: read:: GzDecoder ;
4244use pbr:: { ProgressBar , Units } ;
45+ use regex:: Regex ;
4346use reqwest:: header:: CONTENT_LENGTH ;
4447use reqwest:: { Client , Response } ;
48+ use rustc_version:: Channel ;
4549use structopt:: StructOpt ;
4650use tar:: Archive ;
4751use tee:: TeeReader ;
@@ -464,10 +468,47 @@ enum TestOutcome {
464468}
465469
466470impl Toolchain {
471+ /// This returns the date of the default toolchain, if it is a nightly toolchain.
472+ /// Returns `None` if the installed toolchain is not a nightly toolchain.
473+ fn default_nightly ( ) -> Option < Date < Utc > > {
474+ let version_meta = rustc_version:: version_meta ( ) . unwrap ( ) ;
475+
476+ if let Channel :: Nightly = version_meta. channel {
477+ if let Some ( str_date) = version_meta. commit_date {
478+ let regex = Regex :: new ( r"(?m)^(\d{4})-(\d{2})-(\d{2})$" ) . unwrap ( ) ;
479+ if let Some ( cap) = regex. captures ( & str_date) {
480+ let year = cap. get ( 1 ) ?. as_str ( ) . parse :: < i32 > ( ) . ok ( ) ?;
481+ let month = cap. get ( 2 ) ?. as_str ( ) . parse :: < u32 > ( ) . ok ( ) ?;
482+ let day = cap. get ( 3 ) ?. as_str ( ) . parse :: < u32 > ( ) . ok ( ) ?;
483+
484+ return Some ( Date :: from_utc (
485+ naive:: NaiveDate :: from_ymd ( year, month, day) ,
486+ Utc ,
487+ ) ) ;
488+ }
489+ }
490+ }
491+
492+ None
493+ }
494+
495+ fn is_current_nightly ( & self ) -> bool {
496+ if let ToolchainSpec :: Nightly { date } = self . spec {
497+ if let Some ( default_date) = Self :: default_nightly ( ) {
498+ return default_date == date;
499+ }
500+ }
501+
502+ false
503+ }
504+
467505 fn remove ( & self , dl_params : & DownloadParams ) -> Result < ( ) , Error > {
468- eprintln ! ( "uninstalling {}" , self ) ;
469- let dir = dl_params. install_dir . join ( self . rustup_name ( ) ) ;
470- fs:: remove_dir_all ( & dir) ?;
506+ if !self . is_current_nightly ( ) {
507+ eprintln ! ( "uninstalling {}" , self ) ;
508+ let dir = dl_params. install_dir . join ( self . rustup_name ( ) ) ;
509+ fs:: remove_dir_all ( & dir) ?;
510+ }
511+
471512 Ok ( ( ) )
472513 }
473514
@@ -551,6 +592,11 @@ impl Toolchain {
551592 }
552593
553594 fn install ( & self , client : & Client , dl_params : & DownloadParams ) -> Result < ( ) , InstallError > {
595+ if self . is_current_nightly ( ) {
596+ // pre existing installation
597+ return Ok ( ( ) ) ;
598+ }
599+
554600 debug ! ( "installing {}" , self ) ;
555601 let tmpdir = TempDir :: new_in ( & dl_params. tmp_dir , & self . rustup_name ( ) )
556602 . map_err ( InstallError :: TempDir ) ?;
@@ -847,8 +893,18 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
847893 let mut last_failure = if let Some ( Bound :: Date ( date) ) = cfg. args . end {
848894 date
849895 } else {
850- today
896+ if let Some ( date) = Toolchain :: default_nightly ( ) {
897+ // start date must be prior to end date
898+ if !has_start {
899+ nightly_date = date;
900+ }
901+
902+ date
903+ } else {
904+ today
905+ }
851906 } ;
907+
852908 while nightly_date > end_at {
853909 let mut t = Toolchain {
854910 spec : ToolchainSpec :: Nightly { date : nightly_date } ,
@@ -857,7 +913,12 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
857913 } ;
858914 t. std_targets . sort ( ) ;
859915 t. std_targets . dedup ( ) ;
860- eprintln ! ( "checking {}" , t) ;
916+ if t. is_current_nightly ( ) {
917+ eprintln ! ( "checking {} from the currently installed default nightly \
918+ toolchain as the last failure", t) ;
919+ } else {
920+ eprintln ! ( "checking {}" , t) ;
921+ }
861922 match t. install ( client, & dl_spec) {
862923 Ok ( ( ) ) => {
863924 let outcome = t. test ( & cfg, & dl_spec) ;
0 commit comments