X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Ffilemap.rs;h=201403210328b31a87e4ced4cdc059001520fb24;hb=fc3ea494ac73aee782a903849c09bb011fe18e37;hp=68e06f5c9acbfda7f0d639b35b366c9195cfe195;hpb=414a99592623df7f0cb4c80d69d735462f3027c3;p=rust.git diff --git a/src/filemap.rs b/src/filemap.rs index 68e06f5c9ac..20140321032 100644 --- a/src/filemap.rs +++ b/src/filemap.rs @@ -8,26 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// TODO: add tests +use std::fs; +use std::io::{self, Write}; -use std::fs::{self, File}; -use std::io::{self, BufWriter, Read, Write}; +use checkstyle::output_checkstyle_file; +use config::{Config, EmitMode, FileName, Verbosity}; +use rustfmt_diff::{make_diff, output_modified, print_diff}; -use checkstyle::{output_checkstyle_file, output_footer, output_header}; -use config::{Config, NewlineStyle, WriteMode}; -use rustfmt_diff::{make_diff, print_diff, Mismatch}; - -// A map of the files of a crate, with their new content -pub type FileMap = Vec; - -pub type FileRecord = (String, String); +#[cfg(test)] +use formatting::FileRecord; // Append a newline to the end of each file. pub fn append_newline(s: &mut String) { s.push_str("\n"); } -pub fn write_all_files( +#[cfg(test)] +pub(crate) fn write_all_files( file_map: &[FileRecord], out: &mut T, config: &Config, @@ -35,132 +32,89 @@ pub fn write_all_files( where T: Write, { - output_header(out, config.write_mode()).ok(); + if config.emit_mode() == EmitMode::Checkstyle { + write!(out, "{}", ::checkstyle::header())?; + } for &(ref filename, ref text) in file_map { write_file(text, filename, out, config)?; } - output_footer(out, config.write_mode()).ok(); + if config.emit_mode() == EmitMode::Checkstyle { + write!(out, "{}", ::checkstyle::footer())?; + } Ok(()) } -// Prints all newlines either as `\n` or as `\r\n`. -pub fn write_system_newlines(writer: T, text: &String, config: &Config) -> Result<(), io::Error> -where - T: Write, -{ - // Buffer output, since we're writing a since char at a time. - let mut writer = BufWriter::new(writer); - - let style = if config.newline_style() == NewlineStyle::Native { - if cfg!(windows) { - NewlineStyle::Windows - } else { - NewlineStyle::Unix - } - } else { - config.newline_style() - }; - - match style { - NewlineStyle::Unix => write!(writer, "{}", text), - NewlineStyle::Windows => { - for c in text.chars() { - match c { - '\n' => write!(writer, "\r\n")?, - '\r' => continue, - c => write!(writer, "{}", c)?, - } - } - Ok(()) - } - NewlineStyle::Native => unreachable!(), - } -} - pub fn write_file( - text: &String, - filename: &str, + formatted_text: &str, + filename: &FileName, out: &mut T, config: &Config, ) -> Result where T: Write, { - fn source_and_formatted_text( - text: &String, - filename: &str, - config: &Config, - ) -> Result<(String, String), io::Error> { - let mut f = File::open(filename)?; - let mut ori_text = String::new(); - f.read_to_string(&mut ori_text)?; - let mut v = Vec::new(); - 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: &String, - config: &Config, - ) -> Result, io::Error> { - let (ori, fmt) = 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) { - if fmt != ori { - // Do a little dance to make writing safer - write to a temp file - // rename the original to a .bk, then rename the temp file to the - // original. - let tmp_name = filename.to_owned() + ".tmp"; - let bk_name = filename.to_owned() + ".bk"; - { - // Write text to temp file - let tmp_file = File::create(&tmp_name)?; - write_system_newlines(tmp_file, text, config)?; - } + let filename_to_path = || match *filename { + FileName::Real(ref path) => path, + _ => panic!("cannot format `{}` and emit to files", filename), + }; - fs::rename(filename, bk_name)?; - fs::rename(tmp_name, filename)?; - } + match config.emit_mode() { + EmitMode::Files if config.make_backup() => { + let filename = filename_to_path(); + let ori = fs::read_to_string(filename)?; + if ori != formatted_text { + // Do a little dance to make writing safer - write to a temp file + // rename the original to a .bk, then rename the temp file to the + // original. + let tmp_name = filename.with_extension("tmp"); + let bk_name = filename.with_extension("bk"); + + fs::write(&tmp_name, formatted_text)?; + fs::rename(filename, bk_name)?; + fs::rename(tmp_name, filename)?; } } - WriteMode::Overwrite => { + EmitMode::Files => { // Write text directly over original file if there is a diff. - let (source, formatted) = source_and_formatted_text(text, filename, config)?; - if source != formatted { - let file = File::create(filename)?; - write_system_newlines(file, text, config)?; + let filename = filename_to_path(); + let ori = fs::read_to_string(filename)?; + if ori != formatted_text { + fs::write(filename, formatted_text)?; } } - WriteMode::Plain => { - write_system_newlines(out, text, config)?; - } - WriteMode::Display | WriteMode::Coverage => { - println!("{}:\n", filename); - write_system_newlines(out, text, config)?; - } - WriteMode::Diff => { - if let Ok((ori, fmt)) = source_and_formatted_text(text, filename, config) { - let mismatch = make_diff(&ori, &fmt, 3); - let has_diff = !mismatch.is_empty(); - print_diff( - mismatch, - |line_num| format!("Diff in {} at line {}:", filename, line_num), - config.color(), - ); - return Ok(has_diff); + EmitMode::Stdout | EmitMode::Coverage => { + if config.verbose() != Verbosity::Quiet { + println!("{}:\n", filename); } + write!(out, "{}", formatted_text)?; + } + EmitMode::ModifiedLines => { + let filename = filename_to_path(); + let ori = fs::read_to_string(filename)?; + let mismatch = make_diff(&ori, formatted_text, 0); + let has_diff = !mismatch.is_empty(); + output_modified(out, mismatch); + return Ok(has_diff); } - WriteMode::Checkstyle => { - let diff = create_diff(filename, text, config)?; + EmitMode::Checkstyle => { + let filename = filename_to_path(); + let ori = fs::read_to_string(filename)?; + let diff = make_diff(&ori, formatted_text, 3); output_checkstyle_file(out, filename, diff)?; } + EmitMode::Diff => { + let filename = filename_to_path(); + let ori = fs::read_to_string(filename)?; + let mismatch = make_diff(&ori, formatted_text, 3); + let has_diff = !mismatch.is_empty(); + print_diff( + mismatch, + |line_num| format!("Diff in {} at line {}:", filename.display(), line_num), + config, + ); + return Ok(has_diff); + } } // when we are not in diff mode, don't indicate differing files