mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 14:52:01 +00:00
Show per-cell diffs when analyzing notebooks over stdin
(#7789)
## Summary The implementation here differs from the non-`stdin` version -- this is now more consistent. ## Test Plan ``` ❯ cat Untitled.ipynb | cargo run -p ruff_cli -- check --stdin-filename Untitled.ipynb --diff -n Finished dev [unoptimized + debuginfo] target(s) in 0.11s Running `target/debug/ruff check --stdin-filename Untitled.ipynb --diff -n` --- Untitled.ipynb:cell 2 +++ Untitled.ipynb:cell 2 @@ -1 +0,0 @@ -import os --- Untitled.ipynb:cell 4 +++ Untitled.ipynb:cell 4 @@ -1 +0,0 @@ -import sys ```
This commit is contained in:
parent
600471e45f
commit
e674e87d1b
1 changed files with 71 additions and 13 deletions
|
@ -428,20 +428,78 @@ pub(crate) fn lint_stdin(
|
|||
flags::FixMode::Diff => {
|
||||
// But only write a diff if it's non-empty.
|
||||
if !fixed.is_empty() {
|
||||
let text_diff = TextDiff::from_lines(
|
||||
source_kind.source_code(),
|
||||
transformed.source_code(),
|
||||
);
|
||||
let mut unified_diff = text_diff.unified_diff();
|
||||
if let Some(path) = path {
|
||||
unified_diff
|
||||
.header(&fs::relativize_path(path), &fs::relativize_path(path));
|
||||
}
|
||||
match transformed.as_ref() {
|
||||
SourceKind::Python(_) => {
|
||||
let text_diff = TextDiff::from_lines(
|
||||
source_kind.source_code(),
|
||||
transformed.source_code(),
|
||||
);
|
||||
let mut unified_diff = text_diff.unified_diff();
|
||||
if let Some(path) = path {
|
||||
unified_diff.header(
|
||||
&fs::relativize_path(path),
|
||||
&fs::relativize_path(path),
|
||||
);
|
||||
}
|
||||
|
||||
let mut stdout = io::stdout().lock();
|
||||
unified_diff.to_writer(&mut stdout)?;
|
||||
stdout.write_all(b"\n")?;
|
||||
stdout.flush()?;
|
||||
let mut stdout = io::stdout().lock();
|
||||
unified_diff.to_writer(&mut stdout)?;
|
||||
stdout.write_all(b"\n")?;
|
||||
stdout.flush()?;
|
||||
}
|
||||
SourceKind::IpyNotebook(dst_notebook) => {
|
||||
let src_notebook = source_kind.as_ipy_notebook().unwrap();
|
||||
let mut stdout = io::stdout().lock();
|
||||
// Cell indices are 1-based.
|
||||
for ((idx, src_cell), dest_cell) in (1u32..)
|
||||
.zip(src_notebook.cells().iter())
|
||||
.zip(dst_notebook.cells().iter())
|
||||
{
|
||||
let (Cell::Code(src_code_cell), Cell::Code(dest_code_cell)) =
|
||||
(src_cell, dest_cell)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let src_source_code = src_code_cell.source.to_string();
|
||||
let dest_source_code = dest_code_cell.source.to_string();
|
||||
let text_diff =
|
||||
TextDiff::from_lines(&src_source_code, &dest_source_code);
|
||||
let mut unified_diff = text_diff.unified_diff();
|
||||
|
||||
// Jupyter notebook cells don't necessarily have a newline
|
||||
// at the end. For example,
|
||||
//
|
||||
// ```python
|
||||
// print("hello")
|
||||
// ```
|
||||
//
|
||||
// For a cell containing the above code, there'll only be one line,
|
||||
// and it won't have a newline at the end. If it did, there'd be
|
||||
// two lines, and the second line would be empty:
|
||||
//
|
||||
// ```python
|
||||
// print("hello")
|
||||
//
|
||||
// ```
|
||||
unified_diff.missing_newline_hint(false);
|
||||
|
||||
if let Some(path) = path {
|
||||
unified_diff.header(
|
||||
&format!("{}:cell {}", &fs::relativize_path(path), idx),
|
||||
&format!("{}:cell {}", &fs::relativize_path(path), idx),
|
||||
);
|
||||
} else {
|
||||
unified_diff
|
||||
.header(&format!("cell {idx}"), &format!("cell {idx}"));
|
||||
};
|
||||
|
||||
unified_diff.to_writer(&mut stdout)?;
|
||||
}
|
||||
stdout.write_all(b"\n")?;
|
||||
stdout.flush()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
flags::FixMode::Generate => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue