-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Properly reject NuGet newline-only changes. #10332
Changes from 5 commits
ec6bac4
cf59003
f4ca9a3
6743e98
f834d5c
aa6369d
31e7974
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -161,22 +161,6 @@ def intercept_native_tools(discovery_content_hash:) | |
) | ||
end | ||
end | ||
|
||
context "when the file has only deleted lines" do | ||
before do | ||
allow(File).to receive(:read) | ||
.and_call_original | ||
allow(File).to receive(:read) | ||
.with("#{repo_contents_path}/Proj1/Proj1/Proj1.csproj") | ||
.and_return("") | ||
end | ||
|
||
it "does not update the project" do | ||
run_update_test do |updater| | ||
expect(updater.updated_dependency_files.map(&:name)).to be_empty | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test case was wrong; it was the case where a file was updated and a trailing newline was removed and it was erroneously detected as just deleting the trailing newline, which wasn't correct because the contents actually changed. This scenario is covered in the new tests below. |
||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
|
@@ -262,4 +246,151 @@ def intercept_native_tools(discovery_content_hash:) | |
end | ||
end | ||
end | ||
|
||
describe "#differs_in_more_than_blank_lines?" do | ||
subject(:result) { described_class.differs_in_more_than_blank_lines?(original_content, updated_content) } | ||
|
||
context "when the original content is `nil` and updated is empty" do | ||
let(:original_content) { nil } | ||
let(:updated_content) { "" } | ||
|
||
it { is_expected.to be(false) } | ||
end | ||
|
||
context "when the original content is `nil` and updated is non-empty" do | ||
let(:original_content) { nil } | ||
let(:updated_content) { "line1\nline2" } | ||
|
||
it { is_expected.to be(true) } | ||
end | ||
|
||
context "when there is a difference with no blank lines" do | ||
let(:original_content) do | ||
<<~TEXT | ||
original-line-1 | ||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
let(:updated_content) do | ||
<<~TEXT | ||
original-line-1 | ||
UPDATED-LINE-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
|
||
it { is_expected.to be(true) } | ||
end | ||
|
||
context "when there is a difference with blank lines" do | ||
let(:original_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
let(:updated_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
UPDATED-LINE-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
|
||
it { is_expected.to be(true) } | ||
end | ||
|
||
context "when a blank line was added" do | ||
let(:original_content) do | ||
<<~TEXT | ||
original-line-1 | ||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
let(:updated_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
|
||
it { is_expected.to be(false) } | ||
end | ||
|
||
context "when a blank line was removed, but no other changes" do | ||
let(:original_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
let(:updated_content) do | ||
<<~TEXT | ||
original-line-1 | ||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
|
||
it { is_expected.to be(false) } | ||
end | ||
|
||
context "when a blank line was removed and another was changed" do | ||
let(:original_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
let(:updated_content) do | ||
<<~TEXT | ||
original-line-1 | ||
UPDATED-LINE-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
|
||
it { is_expected.to be(true) } | ||
end | ||
|
||
context "when a line was added and blank lines are present" do | ||
let(:original_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
original-line-2 | ||
original-line-3 | ||
TEXT | ||
end | ||
let(:updated_content) do | ||
<<~TEXT | ||
original-line-1 | ||
|
||
original-line-2 | ||
SOME-NEW-LINE | ||
original-line-3 | ||
TEXT | ||
end | ||
|
||
it { is_expected.to be(true) } | ||
end | ||
|
||
context "when the only difference is a trailing newline" do | ||
let(:original_content) { "line-1\nline-2\n" } | ||
let(:updated_content) { "line-1\nline-2" } | ||
|
||
it { is_expected.to be(false) } | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the original scenario (#9162) still pass here?
Maybe there needs to be a test for this as well, unless there are other checks elsewhere to deal with this problem now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, that was a test case I missed. I just pushed a commit that adds this test case if you want to double check I understood the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-reading your comment I think there is a separate issue to address; what if a package is removed? I think that should be handled in the C# code that actually checks the file content. This part of the code is to handle silliness around empty lines. There's likely a bigger work item to ensure that a dependency isn't removed, but we have better unit tests in the C# code for that. Do you have a scenario where a package was removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding of the description in #9162 is that if you had a project like this:
And NuGetUpdater attempted to update "DependencyA" to "2.0.0" but failed and rolled back e.g.
It would remove the dependency entirely and result in a project file like:
In this scenario, the file is different, but it is different in a way that the PR should not be created because the change isn't desired. I could be misunderstanding this problem though.
Maybe the original issue shouldn't have been solved in
file_updater
and instead the "rollback" warning should be escalated as an error by the native NuGet updater instead? Maybe this scenario isn't even valid anymore, in which case, ignore me.I'll let you decide what is correct here as you understand this all better than me.
Ultimately this change solves my specific problem, so I'm happy with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say the scenario you presented should be handled purely in C#. Let's take this PR as is, because it does fix a class of errors that we're currently seeing and I'll look at the rollback scenario tomorrow and see if I can nail down what might cause that. There appears to be enough information in the linked issue to sort it out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhyskoedijk I filed issue #10342 to track this other scenario and I'm working on it now. Rough ETA, sometime next week. I think the best mechanism to prevent this kind of error is to only report available package upgrades if all transitive dependencies can be resolved so that we never try to update when it's not fully resolvable (the base scenario that #9162 was trying to address).