Formatter: Detect line endings (#7054)

This commit is contained in:
Micha Reiser 2023-09-04 08:09:31 +02:00 committed by GitHub
parent 834566f34f
commit 93ca8ebbc0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 8 deletions

1
Cargo.lock generated
View file

@ -2369,6 +2369,7 @@ dependencies = [
"similar",
"smallvec",
"thiserror",
"tracing",
"unicode-width",
]

View file

@ -12,7 +12,6 @@ use log::{debug, warn};
use rayon::iter::Either::{Left, Right};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use thiserror::Error;
use tracing::{span, Level};
use ruff::fs;
use ruff::logging::LogLevel;
@ -20,6 +19,7 @@ use ruff::warn_user_once;
use ruff_formatter::LineWidth;
use ruff_python_ast::{PySourceType, SourceType};
use ruff_python_formatter::{format_module, FormatModuleError, PyFormatOptions};
use ruff_source_file::{find_newline, LineEnding};
use ruff_workspace::resolver::python_files_in_path;
use crate::args::{FormatArguments, Overrides};
@ -140,12 +140,18 @@ fn format_path(
) -> Result<FormatCommandResult, FormatCommandError> {
let unformatted = std::fs::read_to_string(path)
.map_err(|err| FormatCommandError::Read(Some(path.to_path_buf()), err))?;
let formatted = {
let span = span!(Level::TRACE, "format_path_without_io", path = %path.display());
let _enter = span.enter();
format_module(&unformatted, options)
.map_err(|err| FormatCommandError::FormatModule(Some(path.to_path_buf()), err))?
let line_ending = match find_newline(&unformatted) {
Some((_, LineEnding::Lf)) | None => ruff_formatter::printer::LineEnding::LineFeed,
Some((_, LineEnding::Cr)) => ruff_formatter::printer::LineEnding::CarriageReturn,
Some((_, LineEnding::CrLf)) => ruff_formatter::printer::LineEnding::CarriageReturnLineFeed,
};
let options = options.with_line_ending(line_ending);
let formatted = format_module(&unformatted, options)
.map_err(|err| FormatCommandError::FormatModule(Some(path.to_path_buf()), err))?;
let formatted = formatted.as_code();
if formatted.len() == unformatted.len() && formatted == unformatted {
Ok(FormatCommandResult::Unchanged)

View file

@ -124,7 +124,8 @@ impl SourceMapGeneration {
}
#[allow(dead_code)]
#[derive(Clone, Debug, Eq, PartialEq, Default)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LineEnding {
/// Line Feed only (\n), common on Linux and macOS as well as inside git repos
#[default]

View file

@ -31,6 +31,7 @@ rustc-hash = { workspace = true }
serde = { workspace = true, optional = true }
smallvec = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
unicode-width = { workspace = true }
[dev-dependencies]

View file

@ -1,4 +1,5 @@
use thiserror::Error;
use tracing::Level;
use ruff_formatter::prelude::*;
use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, SourceCode};
@ -119,6 +120,7 @@ impl From<ParseError> for FormatModuleError {
}
}
#[tracing::instrument(level=Level::TRACE, skip_all, err)]
pub fn format_module(
contents: &str,
options: PyFormatOptions,

View file

@ -28,6 +28,8 @@ pub struct PyFormatOptions {
#[cfg_attr(feature = "serde", serde(default = "default_tab_width"))]
tab_width: TabWidth,
line_ending: LineEnding,
/// The preferred quote style to use (single vs double quotes).
quote_style: QuoteStyle,
@ -59,6 +61,7 @@ impl Default for PyFormatOptions {
line_width: default_line_width(),
tab_width: default_tab_width(),
quote_style: QuoteStyle::default(),
line_ending: LineEnding::default(),
magic_trailing_comma: MagicTrailingComma::default(),
source_map_generation: SourceMapGeneration::default(),
}
@ -94,6 +97,10 @@ impl PyFormatOptions {
self.source_map_generation
}
pub fn line_ending(&self) -> LineEnding {
self.line_ending
}
#[must_use]
pub fn with_tab_width(mut self, tab_width: TabWidth) -> Self {
self.tab_width = tab_width;
@ -123,6 +130,12 @@ impl PyFormatOptions {
self.line_width = line_width;
self
}
#[must_use]
pub fn with_line_ending(mut self, line_ending: LineEnding) -> Self {
self.line_ending = line_ending;
self
}
}
impl FormatOptions for PyFormatOptions {
@ -142,7 +155,7 @@ impl FormatOptions for PyFormatOptions {
PrinterOptions {
tab_width: self.tab_width,
line_width: self.line_width,
line_ending: LineEnding::LineFeed,
line_ending: self.line_ending,
indent_style: self.indent_style,
source_map_generation: self.source_map_generation,
}