mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
Formatter: Detect line endings (#7054)
This commit is contained in:
parent
834566f34f
commit
93ca8ebbc0
6 changed files with 32 additions and 8 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2369,6 +2369,7 @@ dependencies = [
|
||||||
"similar",
|
"similar",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tracing",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ use log::{debug, warn};
|
||||||
use rayon::iter::Either::{Left, Right};
|
use rayon::iter::Either::{Left, Right};
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::{span, Level};
|
|
||||||
|
|
||||||
use ruff::fs;
|
use ruff::fs;
|
||||||
use ruff::logging::LogLevel;
|
use ruff::logging::LogLevel;
|
||||||
|
@ -20,6 +19,7 @@ use ruff::warn_user_once;
|
||||||
use ruff_formatter::LineWidth;
|
use ruff_formatter::LineWidth;
|
||||||
use ruff_python_ast::{PySourceType, SourceType};
|
use ruff_python_ast::{PySourceType, SourceType};
|
||||||
use ruff_python_formatter::{format_module, FormatModuleError, PyFormatOptions};
|
use ruff_python_formatter::{format_module, FormatModuleError, PyFormatOptions};
|
||||||
|
use ruff_source_file::{find_newline, LineEnding};
|
||||||
use ruff_workspace::resolver::python_files_in_path;
|
use ruff_workspace::resolver::python_files_in_path;
|
||||||
|
|
||||||
use crate::args::{FormatArguments, Overrides};
|
use crate::args::{FormatArguments, Overrides};
|
||||||
|
@ -140,12 +140,18 @@ fn format_path(
|
||||||
) -> Result<FormatCommandResult, FormatCommandError> {
|
) -> Result<FormatCommandResult, FormatCommandError> {
|
||||||
let unformatted = std::fs::read_to_string(path)
|
let unformatted = std::fs::read_to_string(path)
|
||||||
.map_err(|err| FormatCommandError::Read(Some(path.to_path_buf()), err))?;
|
.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 line_ending = match find_newline(&unformatted) {
|
||||||
let _enter = span.enter();
|
Some((_, LineEnding::Lf)) | None => ruff_formatter::printer::LineEnding::LineFeed,
|
||||||
format_module(&unformatted, options)
|
Some((_, LineEnding::Cr)) => ruff_formatter::printer::LineEnding::CarriageReturn,
|
||||||
.map_err(|err| FormatCommandError::FormatModule(Some(path.to_path_buf()), err))?
|
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();
|
let formatted = formatted.as_code();
|
||||||
if formatted.len() == unformatted.len() && formatted == unformatted {
|
if formatted.len() == unformatted.len() && formatted == unformatted {
|
||||||
Ok(FormatCommandResult::Unchanged)
|
Ok(FormatCommandResult::Unchanged)
|
||||||
|
|
|
@ -124,7 +124,8 @@ impl SourceMapGeneration {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[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 {
|
pub enum LineEnding {
|
||||||
/// Line Feed only (\n), common on Linux and macOS as well as inside git repos
|
/// Line Feed only (\n), common on Linux and macOS as well as inside git repos
|
||||||
#[default]
|
#[default]
|
||||||
|
|
|
@ -31,6 +31,7 @@ rustc-hash = { workspace = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
smallvec = { workspace = true }
|
smallvec = { workspace = true }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
tracing = { workspace = true }
|
||||||
unicode-width = { workspace = true }
|
unicode-width = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
use ruff_formatter::prelude::*;
|
use ruff_formatter::prelude::*;
|
||||||
use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, SourceCode};
|
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(
|
pub fn format_module(
|
||||||
contents: &str,
|
contents: &str,
|
||||||
options: PyFormatOptions,
|
options: PyFormatOptions,
|
||||||
|
|
|
@ -28,6 +28,8 @@ pub struct PyFormatOptions {
|
||||||
#[cfg_attr(feature = "serde", serde(default = "default_tab_width"))]
|
#[cfg_attr(feature = "serde", serde(default = "default_tab_width"))]
|
||||||
tab_width: TabWidth,
|
tab_width: TabWidth,
|
||||||
|
|
||||||
|
line_ending: LineEnding,
|
||||||
|
|
||||||
/// The preferred quote style to use (single vs double quotes).
|
/// The preferred quote style to use (single vs double quotes).
|
||||||
quote_style: QuoteStyle,
|
quote_style: QuoteStyle,
|
||||||
|
|
||||||
|
@ -59,6 +61,7 @@ impl Default for PyFormatOptions {
|
||||||
line_width: default_line_width(),
|
line_width: default_line_width(),
|
||||||
tab_width: default_tab_width(),
|
tab_width: default_tab_width(),
|
||||||
quote_style: QuoteStyle::default(),
|
quote_style: QuoteStyle::default(),
|
||||||
|
line_ending: LineEnding::default(),
|
||||||
magic_trailing_comma: MagicTrailingComma::default(),
|
magic_trailing_comma: MagicTrailingComma::default(),
|
||||||
source_map_generation: SourceMapGeneration::default(),
|
source_map_generation: SourceMapGeneration::default(),
|
||||||
}
|
}
|
||||||
|
@ -94,6 +97,10 @@ impl PyFormatOptions {
|
||||||
self.source_map_generation
|
self.source_map_generation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn line_ending(&self) -> LineEnding {
|
||||||
|
self.line_ending
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_tab_width(mut self, tab_width: TabWidth) -> Self {
|
pub fn with_tab_width(mut self, tab_width: TabWidth) -> Self {
|
||||||
self.tab_width = tab_width;
|
self.tab_width = tab_width;
|
||||||
|
@ -123,6 +130,12 @@ impl PyFormatOptions {
|
||||||
self.line_width = line_width;
|
self.line_width = line_width;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_line_ending(mut self, line_ending: LineEnding) -> Self {
|
||||||
|
self.line_ending = line_ending;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatOptions for PyFormatOptions {
|
impl FormatOptions for PyFormatOptions {
|
||||||
|
@ -142,7 +155,7 @@ impl FormatOptions for PyFormatOptions {
|
||||||
PrinterOptions {
|
PrinterOptions {
|
||||||
tab_width: self.tab_width,
|
tab_width: self.tab_width,
|
||||||
line_width: self.line_width,
|
line_width: self.line_width,
|
||||||
line_ending: LineEnding::LineFeed,
|
line_ending: self.line_ending,
|
||||||
indent_style: self.indent_style,
|
indent_style: self.indent_style,
|
||||||
source_map_generation: self.source_map_generation,
|
source_map_generation: self.source_map_generation,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue