11//! Runs rustfmt on the repository.
22
33use crate :: builder:: Builder ;
4- use crate :: util:: { output, program_out_of_date, t} ;
4+ use crate :: util:: { output, output_result, program_out_of_date, t} ;
5+ use build_helper:: git:: updated_master_branch;
56use ignore:: WalkBuilder ;
67use std:: collections:: VecDeque ;
78use std:: path:: { Path , PathBuf } ;
@@ -78,50 +79,24 @@ fn update_rustfmt_version(build: &Builder<'_>) {
7879/// rust-lang/master and what is now on the disk.
7980///
8081/// Returns `None` if all files should be formatted.
81- fn get_modified_rs_files ( build : & Builder < ' _ > ) -> Option < Vec < String > > {
82- let Ok ( remote) = get_rust_lang_rust_remote ( ) else { return None ; } ;
82+ fn get_modified_rs_files ( build : & Builder < ' _ > ) -> Result < Option < Vec < String > > , String > {
83+ let Ok ( updated_master) = updated_master_branch ( Some ( & build. config . src ) ) else { return Ok ( None ) ; } ;
84+
8385 if !verify_rustfmt_version ( build) {
84- return None ;
86+ return Ok ( None ) ;
8587 }
8688
8789 let merge_base =
88- output ( build. config . git ( ) . arg ( "merge-base" ) . arg ( & format ! ( "{remote}/master" ) ) . arg ( "HEAD" ) ) ;
89- Some (
90- output ( build. config . git ( ) . arg ( "diff-index" ) . arg ( "--name-only" ) . arg ( merge_base. trim ( ) ) )
91- . lines ( )
92- . map ( |s| s. trim ( ) . to_owned ( ) )
93- . filter ( |f| Path :: new ( f) . extension ( ) . map_or ( false , |ext| ext == "rs" ) )
94- . collect ( ) ,
95- )
96- }
97-
98- /// Finds the remote for rust-lang/rust.
99- /// For example for these remotes it will return `upstream`.
100- /// ```text
101- /// origin https://github.com/Nilstrieb/rust.git (fetch)
102- /// origin https://github.com/Nilstrieb/rust.git (push)
103- /// upstream https://github.com/rust-lang/rust (fetch)
104- /// upstream https://github.com/rust-lang/rust (push)
105- /// ```
106- fn get_rust_lang_rust_remote ( ) -> Result < String , String > {
107- let mut git = Command :: new ( "git" ) ;
108- git. args ( [ "config" , "--local" , "--get-regex" , "remote\\ ..*\\ .url" ] ) ;
109-
110- let output = git. output ( ) . map_err ( |err| format ! ( "{err:?}" ) ) ?;
111- if !output. status . success ( ) {
112- return Err ( "failed to execute git config command" . to_owned ( ) ) ;
113- }
114-
115- let stdout = String :: from_utf8 ( output. stdout ) . map_err ( |err| format ! ( "{err:?}" ) ) ?;
116-
117- let rust_lang_remote = stdout
90+ output_result ( build. config . git ( ) . arg ( "merge-base" ) . arg ( & updated_master) . arg ( "HEAD" ) ) ?;
91+ Ok ( Some (
92+ output_result (
93+ build. config . git ( ) . arg ( "diff-index" ) . arg ( "--name-only" ) . arg ( merge_base. trim ( ) ) ,
94+ ) ?
11895 . lines ( )
119- . find ( |remote| remote. contains ( "rust-lang" ) )
120- . ok_or_else ( || "rust-lang/rust remote not found" . to_owned ( ) ) ?;
121-
122- let remote_name =
123- rust_lang_remote. split ( '.' ) . nth ( 1 ) . ok_or_else ( || "remote name not found" . to_owned ( ) ) ?;
124- Ok ( remote_name. into ( ) )
96+ . map ( |s| s. trim ( ) . to_owned ( ) )
97+ . filter ( |f| Path :: new ( f) . extension ( ) . map_or ( false , |ext| ext == "rs" ) )
98+ . collect ( ) ,
99+ ) )
125100}
126101
127102#[ derive( serde:: Deserialize ) ]
@@ -158,6 +133,9 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
158133 Ok ( status) => status. success ( ) ,
159134 Err ( _) => false ,
160135 } ;
136+
137+ let mut paths = paths. to_vec ( ) ;
138+
161139 if git_available {
162140 let in_working_tree = match build
163141 . config
@@ -191,10 +169,21 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
191169 ignore_fmt. add ( & format ! ( "!/{}" , untracked_path) ) . expect ( & untracked_path) ;
192170 }
193171 if !check && paths. is_empty ( ) {
194- if let Some ( files) = get_modified_rs_files ( build) {
195- for file in files {
196- println ! ( "formatting modified file {file}" ) ;
197- ignore_fmt. add ( & format ! ( "/{file}" ) ) . expect ( & file) ;
172+ match get_modified_rs_files ( build) {
173+ Ok ( Some ( files) ) => {
174+ for file in files {
175+ println ! ( "formatting modified file {file}" ) ;
176+ ignore_fmt. add ( & format ! ( "/{file}" ) ) . expect ( & file) ;
177+ }
178+ }
179+ Ok ( None ) => { }
180+ Err ( err) => {
181+ println ! (
182+ "WARN: Something went wrong when running git commands:\n {err}\n \
183+ Falling back to formatting all files."
184+ ) ;
185+ // Something went wrong when getting the version. Just format all the files.
186+ paths. push ( "." . into ( ) ) ;
198187 }
199188 }
200189 }
@@ -204,6 +193,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
204193 } else {
205194 println ! ( "Could not find usable git. Skipping git-aware format checks" ) ;
206195 }
196+
207197 let ignore_fmt = ignore_fmt. build ( ) . unwrap ( ) ;
208198
209199 let rustfmt_path = build. initial_rustfmt ( ) . unwrap_or_else ( || {
0 commit comments