Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions src/bin/rustfmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern crate toml;
extern crate env_logger;
extern crate getopts;

use rustfmt::{run, run_from_stdin};
use rustfmt::{run, run_from_stdin, check};
use rustfmt::config::{Config, WriteMode};

use std::env;
Expand Down Expand Up @@ -54,6 +54,11 @@ enum Operation {
InvalidInput {
reason: String,
},
/// Check for any style issues, returning non-zero error code if any problems are found
Check {
files: Vec<PathBuf>,
config_path: Option<PathBuf>,
},
/// No file specified, read from stdin
Stdin {
input: String,
Expand Down Expand Up @@ -147,6 +152,7 @@ fn execute() -> i32 {
opts.optflag("h", "help", "show this message");
opts.optflag("V", "version", "show version information");
opts.optflag("v", "verbose", "show progress");
opts.optflag("c", "check", "check for style errors, don't modify files");
opts.optopt("",
"write-mode",
"mode to write in (not usable when piping from stdin)",
Expand Down Expand Up @@ -200,11 +206,12 @@ fn execute() -> i32 {
run_from_stdin(input, &config);
0
}
Operation::Format { files, config_path } => {
Operation::Format { ref files, ref config_path } |
Operation::Check { ref files, ref config_path } => {
let mut config = Config::default();
let mut path = None;
// Load the config path file if provided
if let Some(config_file) = config_path {
if let Some(ref config_file) = *config_path {
let (cfg_tmp, path_tmp) = resolve_config(config_file.as_ref())
.expect(&format!("Error resolving config for {:?}",
config_file));
Expand All @@ -214,6 +221,9 @@ fn execute() -> i32 {
if let Some(path) = path.as_ref() {
msg!("Using rustfmt config file {}", path.display());
}

let mut error_result: i32 = 0;

for file in files {
// Check the file directory if the config-path could not be read or not provided
if path.is_none() {
Expand All @@ -233,9 +243,15 @@ fn execute() -> i32 {
print_usage(&opts, &e);
return 1;
}
run(&file, &config);

if let Operation::Check { files: _, config_path: _ } = operation {
error_result += check(&file, &config);
} else {
run(&file, &config);
}
}
0

error_result
}
}
}
Expand Down Expand Up @@ -309,6 +325,13 @@ fn determine_operation(matches: &Matches) -> Operation {

let files: Vec<_> = matches.free.iter().map(PathBuf::from).collect();

if matches.opt_present("check") {
return Operation::Check {
files: files,
config_path: config_path,
};
}

Operation::Format {
files: files,
config_path: config_path,
Expand Down
67 changes: 45 additions & 22 deletions src/filemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,35 +80,58 @@ pub fn write_system_newlines<T>(writer: T,
}
}

fn source_and_formatted_text(text: &StringBuffer,
filename: &str,
config: &Config)
-> Result<(String, String), io::Error> {
let mut f = try!(File::open(filename));
let mut ori_text = String::new();
try!(f.read_to_string(&mut ori_text));
let mut v = Vec::new();
try!(write_system_newlines(&mut v, text, config));
let fmt_text = String::from_utf8(v).unwrap();
Ok((ori_text, fmt_text))
}

fn create_diff(filename: &str,
text: &StringBuffer,
config: &Config)
-> Result<Vec<Mismatch>, io::Error> {
let (ori, fmt) = try!(source_and_formatted_text(text, filename, config));
Ok(make_diff(&ori, &fmt, 3))
}

pub fn check_all_files<T>(file_map: &FileMap, mut out: T, config: &Config) -> usize
where T: Write
{
let mut error_count = 0;
for filename in file_map.keys() {
let diff = create_diff(filename, &file_map[filename], config);
match diff {
Ok(result) => {
let file_errors = result.len();
if file_errors > 0 {
error_count += file_errors;
let _ = write!(out, "{} contains {} errors\n", filename, file_errors);
}
}
Err(error) => {
error_count += 1;
let _ = write!(out, "Error processing {}: {}", filename, error);
}
};
}

error_count
}

pub fn write_file<T>(text: &StringBuffer,
filename: &str,
out: &mut T,
config: &Config)
-> Result<Option<String>, io::Error>
where T: Write
{

fn source_and_formatted_text(text: &StringBuffer,
filename: &str,
config: &Config)
-> Result<(String, String), io::Error> {
let mut f = try!(File::open(filename));
let mut ori_text = String::new();
try!(f.read_to_string(&mut ori_text));
let mut v = Vec::new();
try!(write_system_newlines(&mut v, text, config));
let fmt_text = String::from_utf8(v).unwrap();
Ok((ori_text, fmt_text))
}

fn create_diff(filename: &str,
text: &StringBuffer,
config: &Config)
-> Result<Vec<Mismatch>, io::Error> {
let (ori, fmt) = try!(source_and_formatted_text(text, filename, config));
Ok(make_diff(&ori, &fmt, 3))
}

match config.write_mode {
WriteMode::Replace => {
if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) {
Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,13 @@ pub fn run(file: &Path, config: &Config) {
}
}

pub fn check(file: &Path, config: &Config) -> i32 {
let mut result = format(file, config);
print!("{}", fmt_lines(&mut result, config));
let out = stdout();
filemap::check_all_files(&result, out, config) as i32
}

// Similar to run, but takes an input String instead of a file to format
pub fn run_from_stdin(input: String, config: &Config) {
let mut result = format_string(input, config);
Expand Down