rust/src/source_file.rs

134 lines
4.3 KiB
Rust
Raw Normal View History

use std::fs;
use std::io::{self, Write};
use std::path::Path;
use syntax::source_map::SourceMap;
2019-02-04 13:30:43 +03:00
use crate::checkstyle::output_checkstyle_file;
use crate::config::{Config, EmitMode, FileName, Verbosity};
use crate::rustfmt_diff::{make_diff, print_diff, ModifiedLines};
#[cfg(test)]
2019-02-04 13:30:43 +03:00
use crate::formatting::FileRecord;
// Append a newline to the end of each file.
2019-05-09 20:37:51 +02:00
pub(crate) fn append_newline(s: &mut String) {
s.push_str("\n");
}
#[cfg(test)]
pub(crate) fn write_all_files<T>(
source_file: &[FileRecord],
2017-11-30 15:04:19 +01:00
out: &mut T,
config: &Config,
) -> Result<(), io::Error>
where
T: Write,
{
if config.emit_mode() == EmitMode::Checkstyle {
2019-02-04 13:30:43 +03:00
write!(out, "{}", crate::checkstyle::header())?;
}
for &(ref filename, ref text) in source_file {
write_file(None, filename, text, out, config)?;
}
if config.emit_mode() == EmitMode::Checkstyle {
2019-02-04 13:30:43 +03:00
write!(out, "{}", crate::checkstyle::footer())?;
}
Ok(())
}
2019-05-09 20:37:51 +02:00
pub(crate) fn write_file<T>(
source_map: Option<&SourceMap>,
filename: &FileName,
formatted_text: &str,
out: &mut T,
config: &Config,
) -> Result<bool, io::Error>
where
T: Write,
{
fn ensure_real_path(filename: &FileName) -> &Path {
match *filename {
FileName::Real(ref path) => path,
_ => panic!("cannot format `{}` and emit to files", filename),
}
}
impl From<&FileName> for syntax_pos::FileName {
fn from(filename: &FileName) -> syntax_pos::FileName {
match filename {
FileName::Real(path) => syntax_pos::FileName::Real(path.to_owned()),
FileName::Stdin => syntax_pos::FileName::Custom("stdin".to_owned()),
}
}
}
// If parse session is around (cfg(not(test))) then try getting source from
// there instead of hitting the file system. This also supports getting
// original text for `FileName::Stdin`.
let original_text = source_map
.and_then(|x| x.get_source_file(&filename.into()))
.and_then(|x| x.src.as_ref().map(ToString::to_string));
let original_text = match original_text {
Some(ori) => ori,
None => fs::read_to_string(ensure_real_path(filename))?,
};
match config.emit_mode() {
EmitMode::Files if config.make_backup() => {
let filename = ensure_real_path(filename);
if original_text != 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)?;
}
}
EmitMode::Files => {
// Write text directly over original file if there is a diff.
let filename = ensure_real_path(filename);
if original_text != formatted_text {
fs::write(filename, formatted_text)?;
}
2015-08-18 21:10:30 +02:00
}
EmitMode::Stdout | EmitMode::Coverage => {
if config.verbose() != Verbosity::Quiet {
println!("{}:\n", filename);
}
write!(out, "{}", formatted_text)?;
2015-08-18 21:10:30 +02:00
}
EmitMode::ModifiedLines => {
let mismatch = make_diff(&original_text, formatted_text, 0);
let has_diff = !mismatch.is_empty();
write!(out, "{}", ModifiedLines::from(mismatch))?;
return Ok(has_diff);
Add a new get_modified_lines() API to get only the new changed lines from rustfmting. Squashed commit of the following: commit e90f9da64bbdb640b8c9ee61c3ad395617d8b4da Author: Chris Emerson <github@mail.nosreme.org> Date: Sat Jan 20 20:10:16 2018 +0000 Fix tests after merging with master. commit c3af0042769fe459b0c9c94a0934605ea4b40e40 Merge: 03868583 e0e3e222 Author: Chris Emerson <github@mail.nosreme.org> Date: Sat Jan 20 17:45:05 2018 +0000 Merge remote-tracking branch 'origin/master' into HEAD commit 03868583f8555aae30bdfb5839a82afd3704f4cb Author: Chris Emerson <github@mail.nosreme.org> Date: Mon Nov 20 01:57:56 2017 +0000 Fix some warnings. commit 162b13463e44c782394d418db5ca5710931beb7a Author: Chris Emerson <github@mail.nosreme.org> Date: Mon Nov 20 01:48:02 2017 +0000 Remove unneeded import. commit 20cce3cbfd0f386d92b80bf4c7b83ab4d78a73e7 Merge: 81e98147 fa794f58 Author: Chris Emerson <github@mail.nosreme.org> Date: Mon Nov 20 01:07:17 2017 +0000 Merge branch 'master' into difflines_mode commit 81e981472ceb3a0938d6f050edf8dcd5ebff8e33 Author: Chris Emerson <github@mail.nosreme.org> Date: Mon Nov 20 01:02:50 2017 +0000 Add a simple "modified lines" test. commit 018390ced3523ca9fdd5384a6c1004cdb99174a9 Author: Chris Emerson <github@mail.nosreme.org> Date: Thu Nov 2 23:06:21 2017 +0000 Update test output. commit 7909f4986ed21999aff7b3d075332e686ac464ff Author: Chris Emerson <github@mail.nosreme.org> Date: Thu Nov 2 23:03:22 2017 +0000 Rerun rustfmt. commit 6275f1a8da52db1df36c4b7432996cdbb94ca463 Merge: 7a66d286 175c0c6f Author: Chris Emerson <github@mail.nosreme.org> Date: Thu Nov 2 21:40:29 2017 +0000 Merge remote-tracking branch 'origin/master' into difflines_mode commit 7a66d2866432c430b046938bb37bf5efc03fa9da Author: Chris Emerson <github@mail.nosreme.org> Date: Thu Nov 2 21:36:40 2017 +0000 WIP: Add a separate API to get changed lines. Currently calls format_input() and adjusts the output. commit c8163a923c7d9ae42fd8078cd9b2b51c6f73e36e Author: Chris Emerson <github@mail.nosreme.org> Date: Fri Oct 27 22:53:33 2017 +0100 Remove "modified" from the documentation again. commit 94041fa115a6f428afe40e01d41bf2fe603f70bb Merge: acaa3c7c 2adf7eec Author: Chris Emerson <github@mail.nosreme.org> Date: Fri Oct 27 22:47:05 2017 +0100 Merge branch 'master' into difflines_mode commit acaa3c7ce446297cd3fe5c9610763629a2d8537c Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 23:34:14 2017 +0100 Update the Modified write mode to use `out` instead of just prinln!(). This means we can test it more easily, so do so. commit 9f1bbca1f3c12d933ea823918cc548e69b438b1e Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 23:11:55 2017 +0100 Add "Modified" to the various lists of modes. commit e12f023756cf3daf202dcaa02bd6492b0d2a0455 Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 22:57:33 2017 +0100 Rerun cargo fmt. commit 0f8a43630fa1548e95dcb1c0933708f9c11ae135 Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 22:46:26 2017 +0100 Add `line_number_orig` to instances of `Mismatch` in tests. commit d432a7061f74dbc159584f08470c64985a4b41d9 Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 22:41:40 2017 +0100 Add a `line_number_orig` field to `Mismatch` to track the pre-format line number. Use that for the write-mode=modified output. commit bdb7d1d23f02f7b8f18e7073a65be88ff94cdbb3 Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 22:35:50 2017 +0100 First basic --write-mode=modified implementation. commit ea1433dae0c32879a31182c11be08b1bf53fbf31 Author: Chris Emerson <github@mail.nosreme.org> Date: Fri Oct 20 00:04:16 2017 +0100 WIP on new "modified" mode. commit 27ee9483cf937a11a0e115f54de0afcc3f9ceb44 Merge: e48dd81a 2a84352d Author: Chris Emerson <github@mail.nosreme.org> Date: Tue Oct 24 21:56:44 2017 +0100 Merge remote-tracking branch 'jc/diff_zero_context' into difflines_mode
2018-01-20 20:23:25 +00:00
}
EmitMode::Checkstyle => {
let filename = ensure_real_path(filename);
let diff = make_diff(&original_text, formatted_text, 3);
2017-05-08 13:13:49 +09:00
output_checkstyle_file(out, filename, diff)?;
}
EmitMode::Diff => {
let mismatch = make_diff(&original_text, formatted_text, 3);
let has_diff = !mismatch.is_empty();
print_diff(
mismatch,
|line_num| format!("Diff in {} at line {}:", filename, line_num),
config,
);
return Ok(has_diff);
}
2015-08-18 21:10:30 +02:00
}
// when we are not in diff mode, don't indicate differing files
Ok(false)
}