@@ -41,6 +41,10 @@ pub struct Opts {
4141 #[ structopt( short = "p" , long = "package" , value_name = "package" ) ]
4242 packages : Vec < String > ,
4343
44+ /// Specify path to Cargo.toml
45+ #[ structopt( long = "manifest-path" , value_name = "manifest-path" ) ]
46+ manifest_path : Option < String > ,
47+
4448 /// Options passed to rustfmt
4549 // 'raw = true' to make `--` explicit.
4650 #[ structopt( name = "rustfmt_options" , raw( raw = "true" ) ) ]
@@ -90,7 +94,27 @@ fn execute() -> i32 {
9094
9195 let strategy = CargoFmtStrategy :: from_opts ( & opts) ;
9296
93- handle_command_status ( format_crate ( verbosity, & strategy, opts. rustfmt_options ) )
97+ if opts. manifest_path . is_some ( ) {
98+ let specified_manifest_path = opts. manifest_path . unwrap ( ) ;
99+ if !specified_manifest_path. ends_with ( "Cargo.toml" ) {
100+ print_usage_to_stderr ( "the manifest-path must be a path to a Cargo.toml file" ) ;
101+ return FAILURE ;
102+ }
103+ let manifest_path = PathBuf :: from ( specified_manifest_path) ;
104+ handle_command_status ( format_crate (
105+ verbosity,
106+ & strategy,
107+ opts. rustfmt_options ,
108+ Some ( & manifest_path) ,
109+ ) )
110+ } else {
111+ handle_command_status ( format_crate (
112+ verbosity,
113+ & strategy,
114+ opts. rustfmt_options ,
115+ None ,
116+ ) )
117+ }
94118}
95119
96120fn print_usage_to_stderr ( reason : & str ) {
@@ -142,14 +166,15 @@ fn format_crate(
142166 verbosity : Verbosity ,
143167 strategy : & CargoFmtStrategy ,
144168 rustfmt_args : Vec < String > ,
169+ manifest_path : Option < & Path > ,
145170) -> Result < i32 , io:: Error > {
146171 let targets = if rustfmt_args
147172 . iter ( )
148173 . any ( |s| [ "--print-config" , "-h" , "--help" , "-V" , "--version" ] . contains ( & s. as_str ( ) ) )
149174 {
150175 BTreeSet :: new ( )
151176 } else {
152- get_targets ( strategy) ?
177+ get_targets ( strategy, manifest_path ) ?
153178 } ;
154179
155180 // Currently only bin and lib files get formatted.
@@ -227,13 +252,20 @@ impl CargoFmtStrategy {
227252}
228253
229254/// Based on the specified `CargoFmtStrategy`, returns a set of main source files.
230- fn get_targets ( strategy : & CargoFmtStrategy ) -> Result < BTreeSet < Target > , io:: Error > {
255+ fn get_targets (
256+ strategy : & CargoFmtStrategy ,
257+ manifest_path : Option < & Path > ,
258+ ) -> Result < BTreeSet < Target > , io:: Error > {
231259 let mut targets = BTreeSet :: new ( ) ;
232260
233261 match * strategy {
234- CargoFmtStrategy :: Root => get_targets_root_only ( & mut targets) ?,
235- CargoFmtStrategy :: All => get_targets_recursive ( None , & mut targets, & mut BTreeSet :: new ( ) ) ?,
236- CargoFmtStrategy :: Some ( ref hitlist) => get_targets_with_hitlist ( hitlist, & mut targets) ?,
262+ CargoFmtStrategy :: Root => get_targets_root_only ( manifest_path, & mut targets) ?,
263+ CargoFmtStrategy :: All => {
264+ get_targets_recursive ( manifest_path, & mut targets, & mut BTreeSet :: new ( ) ) ?
265+ }
266+ CargoFmtStrategy :: Some ( ref hitlist) => {
267+ get_targets_with_hitlist ( manifest_path, hitlist, & mut targets) ?
268+ }
237269 }
238270
239271 if targets. is_empty ( ) {
@@ -246,12 +278,22 @@ fn get_targets(strategy: &CargoFmtStrategy) -> Result<BTreeSet<Target>, io::Erro
246278 }
247279}
248280
249- fn get_targets_root_only ( targets : & mut BTreeSet < Target > ) -> Result < ( ) , io:: Error > {
250- let metadata = get_cargo_metadata ( None , false ) ?;
251- let current_dir = env:: current_dir ( ) ?. canonicalize ( ) ?;
252- let current_dir_manifest = current_dir. join ( "Cargo.toml" ) ;
281+ fn get_targets_root_only (
282+ manifest_path : Option < & Path > ,
283+ targets : & mut BTreeSet < Target > ,
284+ ) -> Result < ( ) , io:: Error > {
285+ let metadata = get_cargo_metadata ( manifest_path, false ) ?;
253286 let workspace_root_path = PathBuf :: from ( & metadata. workspace_root ) . canonicalize ( ) ?;
254- let in_workspace_root = workspace_root_path == current_dir;
287+ let ( in_workspace_root, current_dir_manifest) = if manifest_path. is_some ( ) {
288+ let target_manifest = manifest_path. unwrap ( ) . canonicalize ( ) ?;
289+ ( workspace_root_path == target_manifest, target_manifest)
290+ } else {
291+ let current_dir = env:: current_dir ( ) ?. canonicalize ( ) ?;
292+ (
293+ workspace_root_path == current_dir,
294+ current_dir. join ( "Cargo.toml" ) ,
295+ )
296+ } ;
255297
256298 let package_targets = match metadata. packages . len ( ) {
257299 1 => metadata. packages . into_iter ( ) . next ( ) . unwrap ( ) . targets ,
@@ -319,10 +361,11 @@ fn get_targets_recursive(
319361}
320362
321363fn get_targets_with_hitlist (
364+ manifest_path : Option < & Path > ,
322365 hitlist : & [ String ] ,
323366 targets : & mut BTreeSet < Target > ,
324367) -> Result < ( ) , io:: Error > {
325- let metadata = get_cargo_metadata ( None , false ) ?;
368+ let metadata = get_cargo_metadata ( manifest_path , false ) ?;
326369
327370 let mut workspace_hitlist: BTreeSet < & String > = BTreeSet :: from_iter ( hitlist) ;
328371
0 commit comments