Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1b02746

Browse files
authored
Merge pull request rust-lang#3582 from sphynx/master
Use structopt for rustfmt-format-diff arguments parsing
2 parents e066466 + 8443262 commit 1b02746

File tree

1 file changed

+95
-39
lines changed

1 file changed

+95
-39
lines changed

src/format-diff/main.rs

Lines changed: 95 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use env_logger;
88
#[macro_use]
99
extern crate failure;
10-
use getopts;
1110
#[macro_use]
1211
extern crate log;
1312
use regex;
@@ -16,10 +15,13 @@ use serde_json as json;
1615

1716
use std::collections::HashSet;
1817
use std::io::{self, BufRead};
19-
use std::{env, process};
18+
use std::process;
2019

2120
use regex::Regex;
2221

22+
use structopt::clap::AppSettings;
23+
use structopt::StructOpt;
24+
2325
/// The default pattern of files to format.
2426
///
2527
/// We only want to format rust files by default.
@@ -53,26 +55,40 @@ impl From<io::Error> for FormatDiffError {
5355
}
5456
}
5557

56-
fn main() {
57-
env_logger::init();
58+
#[derive(StructOpt, Debug)]
59+
#[structopt(
60+
name = "rustfmt-format-diff",
61+
author = "",
62+
about = "",
63+
raw(setting = "AppSettings::DisableVersion"),
64+
raw(setting = "AppSettings::NextLineHelp")
65+
)]
66+
pub struct Opts {
67+
/// Skip the smallest prefix containing NUMBER slashes
68+
#[structopt(
69+
short = "p",
70+
long = "skip-prefix",
71+
value_name = "NUMBER",
72+
default_value = "0"
73+
)]
74+
skip_prefix: u32,
5875

59-
let mut opts = getopts::Options::new();
60-
opts.optflag("h", "help", "show this message");
61-
opts.optopt(
62-
"p",
63-
"skip-prefix",
64-
"skip the smallest prefix containing NUMBER slashes",
65-
"NUMBER",
66-
);
67-
opts.optopt(
68-
"f",
69-
"filter",
70-
"custom pattern selecting file paths to reformat",
71-
"PATTERN",
72-
);
76+
/// Custom pattern selecting file paths to reformat
77+
#[structopt(
78+
short = "f",
79+
long = "filter",
80+
value_name = "PATTERN",
81+
raw(default_value = "DEFAULT_PATTERN")
82+
)]
83+
filter: String,
84+
}
7385

74-
if let Err(e) = run(&opts) {
75-
println!("{}", opts.usage(&e.to_string()));
86+
fn main() {
87+
env_logger::init();
88+
let opts = Opts::from_args();
89+
if let Err(e) = run(opts) {
90+
println!("{}", e);
91+
Opts::clap().print_help().expect("cannot write to stdout");
7692
process::exit(1);
7793
}
7894
}
@@ -83,25 +99,8 @@ struct Range {
8399
range: [u32; 2],
84100
}
85101

86-
fn run(opts: &getopts::Options) -> Result<(), FormatDiffError> {
87-
let matches = opts.parse(env::args().skip(1))?;
88-
89-
if matches.opt_present("h") {
90-
println!("{}", opts.usage("usage: "));
91-
return Ok(());
92-
}
93-
94-
let filter = matches
95-
.opt_str("f")
96-
.unwrap_or_else(|| DEFAULT_PATTERN.to_owned());
97-
98-
let skip_prefix = matches
99-
.opt_str("p")
100-
.and_then(|p| p.parse::<u32>().ok())
101-
.unwrap_or(0);
102-
103-
let (files, ranges) = scan_diff(io::stdin(), skip_prefix, &filter)?;
104-
102+
fn run(opts: Opts) -> Result<(), FormatDiffError> {
103+
let (files, ranges) = scan_diff(io::stdin(), opts.skip_prefix, &opts.filter)?;
105104
run_rustfmt(&files, &ranges)
106105
}
107106

@@ -238,3 +237,60 @@ fn scan_simple_git_diff() {
238237
]
239238
);
240239
}
240+
241+
#[cfg(test)]
242+
mod cmd_line_tests {
243+
use super::*;
244+
245+
#[test]
246+
fn default_options() {
247+
let empty: Vec<String> = vec![];
248+
let o = Opts::from_iter(&empty);
249+
assert_eq!(DEFAULT_PATTERN, o.filter);
250+
assert_eq!(0, o.skip_prefix);
251+
}
252+
253+
#[test]
254+
fn good_options() {
255+
let o = Opts::from_iter(&["test", "-p", "10", "-f", r".*\.hs"]);
256+
assert_eq!(r".*\.hs", o.filter);
257+
assert_eq!(10, o.skip_prefix);
258+
}
259+
260+
#[test]
261+
fn unexpected_option() {
262+
assert!(
263+
Opts::clap()
264+
.get_matches_from_safe(&["test", "unexpected"])
265+
.is_err()
266+
);
267+
}
268+
269+
#[test]
270+
fn unexpected_flag() {
271+
assert!(
272+
Opts::clap()
273+
.get_matches_from_safe(&["test", "--flag"])
274+
.is_err()
275+
);
276+
}
277+
278+
#[test]
279+
fn overridden_option() {
280+
assert!(
281+
Opts::clap()
282+
.get_matches_from_safe(&["test", "-p", "10", "-p", "20"])
283+
.is_err()
284+
);
285+
}
286+
287+
#[test]
288+
fn negative_filter() {
289+
assert!(
290+
Opts::clap()
291+
.get_matches_from_safe(&["test", "-p", "-1"])
292+
.is_err()
293+
);
294+
}
295+
296+
}

0 commit comments

Comments
 (0)