-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Include the name of the conflicting assembly as a part of warning MSB3277 #2379
Include the name of the conflicting assembly as a part of warning MSB3277 #2379
Conversation
@theunrepentantgeek, It will cover your contributions to all .NET Foundation-managed open source projects. |
@theunrepentantgeek, thanks for signing the contribution license agreement. We will now validate the agreement and then the pull request. |
👍 Note, this will increase the number of warnings a given project will have, so there is a theoretical break here if the developer has something that baselines warnings and fails if they increase. /warnaserror usage will be fine because they have the same code. This is a great start, it the next step (not this PR) would be actually include the conflicts; similar to how NuGet has package conflicts in 15.3. |
foundAtLeastOneUnresolvableConflict = true; | ||
// This warning is logged regardless of AutoUnify since it means a conflict existed where the reference | ||
// chosen was not the conflict victor in a version comparison, in other words it was older. | ||
Log.LogWarningWithCodeFromResources("ResolveAssemblyReference.FoundConflicts", idealRemappingPartialAssemblyName.Name); |
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.
If I'm reading this right, this is inside both the for-i
and for-j
loops. idealRemappingPartialAssemblyName
only seems to depend on i
, but not j
.
I think maybe it's better to keep the bool foundAtLeastOneUnresolvableConflict
, and set it to true as before, but log the warning outside of for-j
but inside the for-i
loop, so that it is output only once per each assembly name.
I didn't test my theory, it's all just from reading the code and psychic debugging. It'd be great to have unit-tests support or deny this.
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 think you're right.
Noting that conflictVictims
is also invariant across the for-j
loop, I've promoted both variable and warning message out of the loop.
I tried to create a unit test that generated multiple identical messages but didn't manage to find a way.
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.
This looks great, but I'd really like to see a unit test.
That is apparently pretty complicated. I'm looking at writing one myself (since I think that's almost exactly the same amount of effort required to suggest how you could do it).
Totally onboard with the desire for a unit test. I've made some progress on getting one written - I think I largely have my head around the way But, every scenario that I've tried ends up giving me a different error ( |
@theunrepentantgeek I was running into very similar problems. This is what I got: https://github.com/rainersigwald/msbuild/tree/force-msb3277-test But it doesn't seem to emit any warnings, and I'm not entirely sure why. |
I've had a look at your branch @rainersigwald and I suspect we're trying to test different things. Unless I'm reading them incorrectly (always a possibility), your tests are trying to generate a MSB3277 warning so you can check the message is the expected one. Is this right? Instead of writing a new test, I found two existing tests ( What I've been unable to do is to write a test where |
I found this old bug: #1996 It mentions that you can trigger this if the primary reference has the lower version than the victim one. Hope this helps?? |
It's not possible for the property foreach (AssemblyNameReference assemblyNameReference in assemblyNamesList)
{
DependentAssembly remapping = new DependentAssembly();
remapping.PartialAssemblyName = assemblyNameReference.assemblyName.AssemblyName;
BindingRedirect bindingRedirect = new BindingRedirect();
bindingRedirect.OldVersionLow = new Version("0.0.0.0");
bindingRedirect.OldVersionHigh = assemblyNameReference.assemblyName.AssemblyName.Version;
bindingRedirect.NewVersion = assemblyNameReference.assemblyName.AssemblyName.Version;
// Populate BindingRedirects with a single element array
remapping.BindingRedirects = new BindingRedirect[] { bindingRedirect };
idealRemappingsList.Add(remapping);
} While moving the log message out of the Arguably, this likely also means that the array property I have added an explicit test on the message in MSB3277 which you can see in commit b50c788. |
Awesome detective work, thanks! I found only one other location here where it's being assigned an array with potentially multiple elements, however I'm not sure that code ever runs: Yeah I think you're right and it's impossible to get that message multiple times, so don't worry about testing that part I think. All changes look good to me. |
I also just found this, not sure if relevant: |
@KirillOsenkov: I had a look at your test, and I have a suggestion. In
I suspect this would cause the second reference to merge with the first (same name, same version), leaving no conflict. What happens if you mark the first as |
I've read through the build logs for the failing build on Windows and can't see what the problem might be - looks like a problem writing a file rather than my code change. |
@dotnet-bot test Windows_NT Build for Full please Agreed, that doesn't look related to your change. |
Is there anything more you want done on this PR @rainersigwald ? |
Sorry, this got a bit lost in my to-do list. What does the new test you created add over the ones that you modified? What I was hoping for is a test that shows this warning being emitted for all of the assembly names that are in this state (each That's why I was trying to construct a new set of references; the current set has two versions of |
No concerns at all, @rainersigwald. I've added a new test The comment I made above ("It's not possible for the property idealRemapping.BindingRedirects to contain more than one item") refers to the collection within each |
Found some tests that I'd broken by adding the new dependency in the fixture metadata - have updated those to pass. Also fixed a dumbass compilation error on my part. |
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.
Awesome! I'm now waiting only on explanation/clarification of the additional reference returned in a few tests.
@@ -3538,7 +3538,7 @@ public void ConflictBetweenNonCopyLocalDependencies() | |||
|
|||
Execute(t); | |||
|
|||
Assert.Equal(2, t.ResolvedDependencyFiles.Length); | |||
Assert.Equal(3, t.ResolvedDependencyFiles.Length); |
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.
Is the new one here G
, added for the new test? Please add an assert for it as "documentation".
/// References - D, version 1 | ||
/// References - G, version 1 | ||
/// | ||
/// All of Dv1, Dv2, Gv1 and Gv2 are CopyLocal. We should get two conflict warnings, one for D and one for G. |
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.
Nice!
I've added assertions to the affected tests to ensure that BTW - I spotted a bug in the test |
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.
Very awesome. Thanks!
@AndyGerlicher @jeffkl @cdmihai Is there anything holding this from getting merged? |
Thanks for bringing this back to the top @davkean. I think everything is addressed. And perf looks good: Evaluation: Time (ms)
Evaluation: Memory (bytes)
|
Thanks for the contribution! |
…3277 (dotnet#2379) * Modify ResolveAssemblyReference to include assembly name in the message * Modify tests that trigger MSB3277 to verify the message * Promote check outside of inner loop * Add new test to explicitly test the message in MSB3277 * Add unit test to ensure multiple conflicts are correctly reported
Modify the message MSB3277 to include the name of the conflicting assembly - a partial resolution of #608 . The message will be repeated once for each distinct assembly that is experiencing conflicts.
Old message:
New message (sample):
I found two unit tests that trigger this warning -
ConflictWithBackVersionPrimary()
andConflictWithBackVersionPrimaryWithAutoUnify()
, both found insrc\Tasks.UnitTests\AssemblyDependency\Miscellaneous.cs
; both tests have been modified to assert the correct message exists in the log.