commit
3c60328df8
@ -17,7 +17,7 @@
|
||||
extern crate env_logger;
|
||||
extern crate getopts;
|
||||
|
||||
use rustfmt::{WriteMode, run};
|
||||
use rustfmt::{WriteMode, run, run_from_stdin};
|
||||
use rustfmt::config::Config;
|
||||
|
||||
use std::env;
|
||||
@ -35,6 +35,8 @@ enum Operation {
|
||||
Help,
|
||||
/// Invalid program input, including reason.
|
||||
InvalidInput(String),
|
||||
/// No file specified, read from stdin
|
||||
Stdin(String, WriteMode),
|
||||
}
|
||||
|
||||
/// Try to find a project file in the input file directory and its parents.
|
||||
@ -75,7 +77,7 @@ fn execute() -> i32 {
|
||||
opts.optflag("h", "help", "show this message");
|
||||
opts.optopt("",
|
||||
"write-mode",
|
||||
"mode to write in",
|
||||
"mode to write in (not usable when piping from stdin)",
|
||||
"[replace|overwrite|display|diff|coverage]");
|
||||
|
||||
let operation = determine_operation(&opts, env::args().skip(1));
|
||||
@ -89,6 +91,18 @@ fn execute() -> i32 {
|
||||
print_usage(&opts, "");
|
||||
0
|
||||
}
|
||||
Operation::Stdin(input, write_mode) => {
|
||||
// try to read config from local directory
|
||||
let config = match lookup_and_read_project_file(&Path::new(".")) {
|
||||
Ok((path, toml)) => {
|
||||
Config::from_toml(&toml)
|
||||
}
|
||||
Err(_) => Default::default(),
|
||||
};
|
||||
|
||||
run_from_stdin(input, write_mode, &config);
|
||||
0
|
||||
}
|
||||
Operation::Format(file, write_mode) => {
|
||||
let config = match lookup_and_read_project_file(&file) {
|
||||
Ok((path, toml)) => {
|
||||
@ -138,6 +152,19 @@ fn determine_operation<I>(opts: &Options, args: I) -> Operation
|
||||
return Operation::Help;
|
||||
}
|
||||
|
||||
// if no file argument is supplied, read from stdin
|
||||
if matches.free.len() == 0 {
|
||||
|
||||
let mut buffer = String::new();
|
||||
match io::stdin().read_to_string(&mut buffer) {
|
||||
Ok(..) => (),
|
||||
Err(e) => return Operation::InvalidInput(e.to_string()),
|
||||
}
|
||||
|
||||
// WriteMode is always plain for Stdin
|
||||
return Operation::Stdin(buffer, WriteMode::Plain);
|
||||
}
|
||||
|
||||
let write_mode = match matches.opt_str("write-mode") {
|
||||
Some(mode) => {
|
||||
match mode.parse() {
|
||||
@ -148,9 +175,5 @@ fn determine_operation<I>(opts: &Options, args: I) -> Operation
|
||||
None => WriteMode::Replace,
|
||||
};
|
||||
|
||||
if matches.free.len() != 1 {
|
||||
return Operation::InvalidInput("Please provide one file to format".into());
|
||||
}
|
||||
|
||||
Operation::Format(PathBuf::from(&matches.free[0]), write_mode)
|
||||
}
|
||||
|
@ -46,11 +46,11 @@ pub fn write_all_files(file_map: &FileMap,
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn write_file(text: &StringBuffer,
|
||||
filename: &str,
|
||||
mode: WriteMode,
|
||||
config: &Config)
|
||||
-> Result<Option<String>, io::Error> {
|
||||
pub fn write_file(text: &StringBuffer,
|
||||
filename: &str,
|
||||
mode: WriteMode,
|
||||
config: &Config)
|
||||
-> Result<Option<String>, io::Error> {
|
||||
|
||||
// prints all newlines either as `\n` or as `\r\n`
|
||||
fn write_system_newlines<T>(mut writer: T,
|
||||
@ -100,11 +100,16 @@ fn write_system_newlines<T>(mut writer: T,
|
||||
let file = try!(File::create(&filename));
|
||||
try!(write_system_newlines(file, text, config));
|
||||
}
|
||||
WriteMode::Plain => {
|
||||
let stdout = stdout();
|
||||
let stdout = stdout.lock();
|
||||
try!(write_system_newlines(stdout, text, config));
|
||||
}
|
||||
WriteMode::Display | WriteMode::Coverage => {
|
||||
println!("{}:\n", filename);
|
||||
let stdout = stdout();
|
||||
let stdout_lock = stdout.lock();
|
||||
try!(write_system_newlines(stdout_lock, text, config));
|
||||
let stdout = stdout.lock();
|
||||
try!(write_system_newlines(stdout, text, config));
|
||||
}
|
||||
WriteMode::Diff => {
|
||||
println!("Diff of {}:\n", filename);
|
||||
|
42
src/lib.rs
42
src/lib.rs
@ -193,6 +193,8 @@ pub enum WriteMode {
|
||||
Return,
|
||||
// Display how much of the input file was processed
|
||||
Coverage,
|
||||
// Unfancy stdout
|
||||
Plain,
|
||||
}
|
||||
|
||||
impl FromStr for WriteMode {
|
||||
@ -205,6 +207,7 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
"overwrite" => Ok(WriteMode::Overwrite),
|
||||
"diff" => Ok(WriteMode::Diff),
|
||||
"coverage" => Ok(WriteMode::Coverage),
|
||||
"plain" => Ok(WriteMode::Plain),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@ -386,6 +389,33 @@ pub fn fmt_lines(file_map: &mut FileMap, config: &Config) -> FormatReport {
|
||||
report
|
||||
}
|
||||
|
||||
pub fn format_string(input: String, config: &Config, mode: WriteMode) -> FileMap {
|
||||
let path = "stdin";
|
||||
let mut parse_session = ParseSess::new();
|
||||
let krate = parse::parse_crate_from_source_str(path.to_owned(),
|
||||
input,
|
||||
Vec::new(),
|
||||
&parse_session);
|
||||
|
||||
// Suppress error output after parsing.
|
||||
let emitter = Box::new(EmitterWriter::new(Box::new(Vec::new()), None));
|
||||
parse_session.span_diagnostic.handler = Handler::with_emitter(false, emitter);
|
||||
|
||||
// FIXME: we still use a FileMap even though we only have
|
||||
// one file, because fmt_lines requires a FileMap
|
||||
let mut file_map = FileMap::new();
|
||||
|
||||
// do the actual formatting
|
||||
let mut visitor = FmtVisitor::from_codemap(&parse_session, config, Some(mode));
|
||||
visitor.format_separate_mod(&krate.module, path);
|
||||
|
||||
// append final newline
|
||||
visitor.buffer.push_str("\n");
|
||||
file_map.insert(path.to_owned(), visitor.buffer);
|
||||
|
||||
return file_map;
|
||||
}
|
||||
|
||||
pub fn format(file: &Path, config: &Config, mode: WriteMode) -> FileMap {
|
||||
let mut parse_session = ParseSess::new();
|
||||
let krate = parse::parse_crate_from_file(file, Vec::new(), &parse_session);
|
||||
@ -418,3 +448,15 @@ pub fn run(file: &Path, write_mode: WriteMode, config: &Config) {
|
||||
println!("Error writing files: {}", msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Similar to run, but takes an input String instead of a file to format
|
||||
pub fn run_from_stdin(input: String, mode: WriteMode, config: &Config) {
|
||||
let mut result = format_string(input, config, mode);
|
||||
fmt_lines(&mut result, config);
|
||||
|
||||
let write_result = filemap::write_file(&result["stdin"], "stdin", mode, config);
|
||||
|
||||
if let Err(msg) = write_result {
|
||||
panic!("Error writing to stdout: {}", msg);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user