diff --git a/Cargo.lock b/Cargo.lock index d3f20f8b759..66061bd1e25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6 +4,7 @@ version = "0.0.1" dependencies = [ "diff 0.1.7 (git+https://github.com/utkarshkukreti/diff.rs.git)", "env_logger 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -41,6 +42,11 @@ dependencies = [ "regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "getopts" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "kernel32-sys" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index 60df8ac6904..ebd4e8e7f1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,5 +19,6 @@ diff = { git = "https://github.com/utkarshkukreti/diff.rs.git" } syntex_syntax = { git = "https://github.com/serde-rs/syntex" } log = "0.3.2" env_logger = "0.3.1" +getopts = "0.2" [dev-dependencies] diff --git a/src/bin/rustfmt.rs b/src/bin/rustfmt.rs index 40f55d61154..6b3405aa936 100644 --- a/src/bin/rustfmt.rs +++ b/src/bin/rustfmt.rs @@ -15,6 +15,7 @@ extern crate log; extern crate rustfmt; extern crate toml; extern crate env_logger; +extern crate getopts; use rustfmt::{WriteMode, run}; use rustfmt::config::Config; @@ -23,7 +24,8 @@ use std::env; use std::fs::{self, File}; use std::io::{self, Read}; use std::path::PathBuf; -use std::str::FromStr; + +use getopts::Options; // Try to find a project file in the current directory and its parents. fn lookup_project_file() -> io::Result { @@ -52,7 +54,7 @@ fn lookup_and_read_project_file() -> io::Result<(PathBuf, String)> { } fn execute() -> i32 { - let (args, write_mode) = match determine_params(std::env::args()) { + let (file, write_mode) = match determine_params(std::env::args().skip(1)) { Some(params) => params, None => return 1, }; @@ -65,7 +67,7 @@ fn execute() -> i32 { Err(_) => Default::default(), }; - run(args, write_mode, &config); + run(&file, write_mode, &config); 0 } @@ -83,50 +85,52 @@ fn main() { std::process::exit(exit_code); } -fn print_usage>(reason: S) { - println!("{}\n\r usage: rustfmt [-h Help] [--write-mode=[replace|overwrite|display|diff]] \ - ", - reason.into()); +fn print_usage(opts: &Options, reason: &str) { + let reason = format!("{}\nusage: {} [options] ", + reason, + env::current_exe().unwrap().display()); + println!("{}", opts.usage(&reason)); Config::print_docs(); } -fn determine_params(args: I) -> Option<(Vec, WriteMode)> +fn determine_params(args: I) -> Option<(PathBuf, WriteMode)> where I: Iterator { - let arg_prefix = "-"; - let write_mode_prefix = "--write-mode="; - let help_mode = "-h"; - let long_help_mode = "--help"; - let mut write_mode = WriteMode::Replace; - let mut rustc_args = Vec::new(); + let mut opts = Options::new(); + opts.optflag("h", "help", "show this message"); + opts.optopt("", + "write-mode", + "mode to write in", + "[replace|overwrite|display|diff]"); + let matches = match opts.parse(args) { + Ok(m) => m, + Err(e) => { + print_usage(&opts, &e.to_string()); + return None; + } + }; - // The NewFile option currently isn't supported because it requires another - // parameter, but it can be added later. - for arg in args { - if arg.starts_with(write_mode_prefix) { - match FromStr::from_str(&arg[write_mode_prefix.len()..]) { - Ok(mode) => write_mode = mode, - Err(_) => { - print_usage("Unrecognized write mode"); + if matches.opt_present("h") { + print_usage(&opts, ""); + } + + let write_mode = match matches.opt_str("write-mode") { + Some(mode) => { + match mode.parse() { + Ok(mode) => mode, + Err(..) => { + print_usage(&opts, "Unrecognized write mode"); return None; } } - } else if arg.starts_with(help_mode) || arg.starts_with(long_help_mode) { - print_usage(""); - return None; - } else if arg.starts_with(arg_prefix) { - print_usage("Invalid argument"); - return None; - } else { - // Pass everything else to rustc - rustc_args.push(arg); } - } + None => WriteMode::Replace, + }; - if rustc_args.len() < 2 { - print_usage("Please provide a file to be formatted"); + if matches.free.len() != 1 { + print_usage(&opts, "Please provide one file to format"); return None; } - Some((rustc_args, write_mode)) + Some((PathBuf::from(&matches.free[0]), write_mode)) }