]> git.lizzy.rs Git - rust.git/commitdiff
fix: handling of newline_style conflicts (#3850)
authorCaleb Cartwright <calebcartwright@users.noreply.github.com>
Sat, 19 Oct 2019 08:15:13 +0000 (03:15 -0500)
committerSeiichi Uchida <seuchida@gmail.com>
Sat, 19 Oct 2019 08:15:13 +0000 (17:15 +0900)
src/emitter/diff.rs
src/formatting.rs
src/source_file.rs

index 462a80946ee71e0b61d75c2f7b97c53921afa20c..9be4fb28f993ffdc986a48118867d9a3fad85ef2 100644 (file)
@@ -36,6 +36,13 @@ fn emit_formatted_file(
                     &self.config,
                 );
             }
+        } else if original_text != formatted_text {
+            // This occurs when the only difference between the original and formatted values
+            // is the newline style. This happens because The make_diff function compares the
+            // original and formatted values line by line, independent of line endings.
+            let file_path = ensure_real_path(filename);
+            writeln!(output, "Incorrect newline style in {}", file_path.display())?;
+            return Ok(EmitterResult { has_diff: true });
         }
 
         return Ok(EmitterResult { has_diff });
@@ -107,4 +114,25 @@ fn prints_file_names_when_config_is_enabled() {
             format!("{}\n{}\n", bin_file, lib_file),
         )
     }
+
+    #[test]
+    fn prints_newline_message_with_only_newline_style_diff() {
+        let mut writer = Vec::new();
+        let config = Config::default();
+        let mut emitter = DiffEmitter::new(config);
+        let _ = emitter
+            .emit_formatted_file(
+                &mut writer,
+                FormattedFile {
+                    filename: &FileName::Real(PathBuf::from("src/lib.rs")),
+                    original_text: "fn empty() {}\n",
+                    formatted_text: "fn empty() {}\r\n",
+                },
+            )
+            .unwrap();
+        assert_eq!(
+            String::from_utf8(writer).unwrap(),
+            String::from("Incorrect newline style in src/lib.rs\n")
+        );
+    }
 }
index eec33e6ba7945170f7b07054d2f8f2008acce788..2822a331260b31b9f592d03e2718c50122d15ce0 100644 (file)
@@ -243,8 +243,14 @@ fn handle_formatted_file(
         report: &mut FormatReport,
     ) -> Result<(), ErrorKind> {
         if let Some(ref mut out) = self.out {
-            match source_file::write_file(Some(source_map), &path, &result, out, &mut *self.emitter)
-            {
+            match source_file::write_file(
+                Some(source_map),
+                &path,
+                &result,
+                out,
+                &mut *self.emitter,
+                self.config.newline_style(),
+            ) {
                 Ok(ref result) if result.has_diff => report.add_diff(),
                 Err(e) => {
                     // Create a new error with path_str to help users see which files failed
index 28366ca2485c16f1adadbc3f8d787f16a5efd0a5..b6764ee7464337d5c99802c884b25d71f76b8929 100644 (file)
@@ -6,6 +6,7 @@
 
 use crate::config::FileName;
 use crate::emitter::{self, Emitter};
+use crate::NewlineStyle;
 
 #[cfg(test)]
 use crate::config::Config;
@@ -32,7 +33,14 @@ pub(crate) fn write_all_files<T>(
 
     emitter.emit_header(out)?;
     for &(ref filename, ref text) in source_file {
-        write_file(None, filename, text, out, &mut *emitter)?;
+        write_file(
+            None,
+            filename,
+            text,
+            out,
+            &mut *emitter,
+            config.newline_style(),
+        )?;
     }
     emitter.emit_footer(out)?;
 
@@ -45,6 +53,7 @@ pub(crate) fn write_file<T>(
     formatted_text: &str,
     out: &mut T,
     emitter: &mut dyn Emitter,
+    newline_style: NewlineStyle,
 ) -> Result<emitter::EmitterResult, io::Error>
 where
     T: Write,
@@ -65,15 +74,25 @@ fn from(filename: &FileName) -> syntax_pos::FileName {
         }
     }
 
-    // If parse session is around (cfg(not(test))) then try getting source from
-    // there instead of hitting the file system. This also supports getting
+    // SourceFile's in the SourceMap will always have Unix-style line endings
+    // See: https://github.com/rust-lang/rustfmt/issues/3850
+    // So if the user has explicitly overridden the rustfmt `newline_style`
+    // config and `filename` is FileName::Real, then we must check the file system
+    // to get the original file value in order to detect newline_style conflicts.
+    // Otherwise, parse session is around (cfg(not(test))) and newline_style has been
+    // left as the default value, then try getting source from the parse session
+    // source map 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))?,
+    let original_text = if newline_style != NewlineStyle::Auto && *filename != FileName::Stdin {
+        fs::read_to_string(ensure_real_path(filename))?
+    } else {
+        match source_map
+            .and_then(|x| x.get_source_file(&filename.into()))
+            .and_then(|x| x.src.as_ref().map(ToString::to_string))
+        {
+            Some(ori) => ori,
+            None => fs::read_to_string(ensure_real_path(filename))?,
+        }
     };
 
     let formatted_file = emitter::FormattedFile {