@@ -4,6 +4,9 @@ use std::io;
44use std:: path:: { Path , PathBuf } ;
55use std:: sync:: { Arc , Mutex } ;
66
7+ use build_helper:: ci:: CiEnv ;
8+ use build_helper:: git:: { GitConfig , get_closest_upstream_commit} ;
9+ use build_helper:: stage0_parser:: { Stage0Config , parse_stage0_file} ;
710use termcolor:: Color ;
811
912/// CLI flags used by tidy.
@@ -28,25 +31,47 @@ impl TidyFlags {
2831pub struct TidyCtx {
2932 tidy_flags : TidyFlags ,
3033 diag_ctx : Arc < Mutex < DiagCtxInner > > ,
34+ ci_env : CiEnv ,
35+ pub base_commit : Option < String > ,
3136}
3237
3338impl TidyCtx {
34- pub fn new ( root_path : & Path , verbose : bool , tidy_flags : TidyFlags ) -> Self {
35- Self {
39+ pub fn new (
40+ root_path : & Path ,
41+ verbose : bool ,
42+ ci_flag : Option < bool > ,
43+ tidy_flags : TidyFlags ,
44+ ) -> Self {
45+ let ci_env = match ci_flag {
46+ Some ( true ) => CiEnv :: GitHubActions ,
47+ Some ( false ) => CiEnv :: None ,
48+ None => CiEnv :: current ( ) ,
49+ } ;
50+
51+ let mut tidy_ctx = Self {
3652 diag_ctx : Arc :: new ( Mutex :: new ( DiagCtxInner {
3753 running_checks : Default :: default ( ) ,
3854 finished_checks : Default :: default ( ) ,
3955 root_path : root_path. to_path_buf ( ) ,
4056 verbose,
4157 } ) ) ,
4258 tidy_flags,
43- }
59+ ci_env,
60+ base_commit : None ,
61+ } ;
62+ tidy_ctx. base_commit = find_base_commit ( & tidy_ctx) ;
63+
64+ tidy_ctx
4465 }
4566
4667 pub fn is_bless_enabled ( & self ) -> bool {
4768 self . tidy_flags . bless
4869 }
4970
71+ pub fn is_running_on_ci ( & self ) -> bool {
72+ self . ci_env . is_running_in_ci ( )
73+ }
74+
5075 pub fn start_check < Id : Into < CheckId > > ( & self , id : Id ) -> RunningCheck {
5176 let mut id = id. into ( ) ;
5277
@@ -75,6 +100,46 @@ impl TidyCtx {
75100 }
76101}
77102
103+ fn find_base_commit ( tidy_ctx : & TidyCtx ) -> Option < String > {
104+ let mut check = tidy_ctx. start_check ( "CI history" ) ;
105+
106+ let stage0 = parse_stage0_file ( ) ;
107+ let Stage0Config { nightly_branch, git_merge_commit_email, .. } = stage0. config ;
108+
109+ let base_commit = match get_closest_upstream_commit (
110+ None ,
111+ & GitConfig {
112+ nightly_branch : & nightly_branch,
113+ git_merge_commit_email : & git_merge_commit_email,
114+ } ,
115+ tidy_ctx. ci_env ,
116+ ) {
117+ Ok ( Some ( commit) ) => Some ( commit) ,
118+ Ok ( None ) => {
119+ error_if_in_ci ( "no base commit found" , tidy_ctx. is_running_on_ci ( ) , & mut check) ;
120+ None
121+ }
122+ Err ( error) => {
123+ error_if_in_ci (
124+ & format ! ( "failed to retrieve base commit: {error}" ) ,
125+ tidy_ctx. is_running_on_ci ( ) ,
126+ & mut check,
127+ ) ;
128+ None
129+ }
130+ } ;
131+
132+ base_commit
133+ }
134+
135+ fn error_if_in_ci ( msg : & str , is_ci : bool , check : & mut RunningCheck ) {
136+ if is_ci {
137+ check. error ( msg) ;
138+ } else {
139+ check. warning ( format ! ( "{msg}. Some checks will be skipped." ) ) ;
140+ }
141+ }
142+
78143struct DiagCtxInner {
79144 running_checks : HashSet < CheckId > ,
80145 finished_checks : HashSet < FinishedCheck > ,
@@ -175,7 +240,7 @@ impl RunningCheck {
175240 /// Useful if you want to run some functions from tidy without configuring
176241 /// diagnostics.
177242 pub fn new_noop ( ) -> Self {
178- let ctx = TidyCtx :: new ( Path :: new ( "" ) , false , TidyFlags :: default ( ) ) ;
243+ let ctx = TidyCtx :: new ( Path :: new ( "" ) , false , None , TidyFlags :: default ( ) ) ;
179244 ctx. start_check ( "noop" )
180245 }
181246
0 commit comments