Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(diff): better handling of text with only line ending differences #11212

Merged

Conversation

dsherret
Copy link
Member

@dsherret dsherret commented Jul 1, 2021

Also fixed a few additional bugs like:

  1. It not displaying a diff when one text had a trailing newline and the other didn't.
  2. Edge case where the line number width could be incorrect if the original text had say 99 lines and the edit text had 100 lines.

I commented everywhere in the PR that actually changed other than the refactor to make the borrow checker happy without duplicating code.

Closes #8118

/// Diff format is loosely based on Github diff formatting.
pub fn diff(orig_text: &str, edit_text: &str) -> String {
let lines = edit_text.split('\n').count();
let line_number_width = lines.to_string().chars().count();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug here fixed in new code. Should take into account the max of orig_text and edit_text line count.

}
if !text2.ends_with('\n') {
text2.push('\n');
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug here. Should not do this because it should display a diff for when one has a trailing newline and the other doesn't.

orig: String,
edit: String,
has_changes: bool,
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I had to change the function to a struct in order to make the borrow checker happy and not duplicate a lot of code with the new flush_changes method.

let edit_text = edit_text.replace("\r\n", "\n");

if orig_text == edit_text {
return " | Text differed by line endings.\n".to_string();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix here. This is what I do in dprint. It prevents entire files from being spammed.

let line_count = std::cmp::max(
orig_text.split('\n').count(),
edit_text.split('\n').count(),
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix here to use max.

}
}

self.flush_changes();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix here to flush the changes here as well.

/// Print diff of the same file_path, before and after formatting.
///
/// Diff format is loosely based on Github diff formatting.
pub fn diff(orig_text: &str, edit_text: &str) -> String {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, the diff here wasn't going to be pretty no matter what, so I took the liberty of reorganizing the file. For the most part it's largely the same other than a few fixes. I've commented everywhere that's changed.

@dsherret dsherret marked this pull request as ready for review July 1, 2021 16:53
Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines +172 to +200
run_test(
"console.log('Hello World')",
"console.log(\"Hello World\");",
concat!(
"1 | -console.log('Hello World')\n",
"1 | +console.log(\"Hello World\");\n",
),
);

let line_number_unfmt = "\n\n\n\nconsole.log(\n'Hello World'\n)";
let line_number_fmt = "console.log(\n\"Hello World\"\n);";
run_test(
"\n\n\n\nconsole.log(\n'Hello World'\n)",
"console.log(\n\"Hello World\"\n);",
concat!(
"1 | -\n",
"2 | -\n",
"3 | -\n",
"4 | -\n",
"5 | -console.log(\n",
"1 | +console.log(\n",
"6 | -'Hello World'\n",
"2 | +\"Hello World\"\n",
"7 | -)\n3 | +);\n",
),
);
}

#[test]
fn test_eof_newline_missing() {
run_test(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice tests 👍

@dsherret dsherret merged commit 68b4d60 into denoland:main Jul 2, 2021
@dsherret dsherret deleted the diff-better-handle-line-ending-differences branch July 2, 2021 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

deno fmt --check should not show entire file when only line endings differ
2 participants