@@ -18,7 +18,9 @@ extern crate log;
18
18
extern crate pbr;
19
19
#[ cfg( test) ]
20
20
extern crate quickcheck;
21
+ extern crate regex;
21
22
extern crate reqwest;
23
+ extern crate rustc_version;
22
24
extern crate structopt;
23
25
extern crate tar;
24
26
extern crate tee;
@@ -35,13 +37,15 @@ use std::path::{Path, PathBuf};
35
37
use std:: process:: { self , Command , Stdio } ;
36
38
use std:: str:: FromStr ;
37
39
38
- use chrono:: { Date , Duration , Utc } ;
40
+ use chrono:: { Date , Duration , naive , Utc } ;
39
41
use dialoguer:: Select ;
40
42
use failure:: Error ;
41
43
use flate2:: read:: GzDecoder ;
42
44
use pbr:: { ProgressBar , Units } ;
45
+ use regex:: Regex ;
43
46
use reqwest:: header:: CONTENT_LENGTH ;
44
47
use reqwest:: { Client , Response } ;
48
+ use rustc_version:: Channel ;
45
49
use structopt:: StructOpt ;
46
50
use tar:: Archive ;
47
51
use tee:: TeeReader ;
@@ -464,10 +468,47 @@ enum TestOutcome {
464
468
}
465
469
466
470
impl 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
+
467
505
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
+
471
512
Ok ( ( ) )
472
513
}
473
514
@@ -551,6 +592,11 @@ impl Toolchain {
551
592
}
552
593
553
594
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
+
554
600
debug ! ( "installing {}" , self ) ;
555
601
let tmpdir = TempDir :: new_in ( & dl_params. tmp_dir , & self . rustup_name ( ) )
556
602
. map_err ( InstallError :: TempDir ) ?;
@@ -847,8 +893,18 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
847
893
let mut last_failure = if let Some ( Bound :: Date ( date) ) = cfg. args . end {
848
894
date
849
895
} 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
+ }
851
906
} ;
907
+
852
908
while nightly_date > end_at {
853
909
let mut t = Toolchain {
854
910
spec : ToolchainSpec :: Nightly { date : nightly_date } ,
@@ -857,7 +913,12 @@ fn bisect_nightlies(cfg: &Config, client: &Client) -> Result<BisectionResult, Er
857
913
} ;
858
914
t. std_targets . sort ( ) ;
859
915
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
+ }
861
922
match t. install ( client, & dl_spec) {
862
923
Ok ( ( ) ) => {
863
924
let outcome = t. test ( & cfg, & dl_spec) ;
0 commit comments