mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +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",
|
||||
"smallvec",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue