-
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
Only log properties and items on evaluation if ALL loggers support it #6514
Conversation
I've hit a complication with this logic: The failing test is https://source.dot.net/#Microsoft.Build.Engine.UnitTests/ConsoleLogger_Tests.cs,033182bb824cc88e This logic relies on properties being logged on each ProjectStarted as it uses the ProjectContextId as the key in the dictionary, such that later error events can look up the property by their ProjectContextId. Since we now log properties at evaluation, there isn't any ProjectContextId to speak of during ProjectEvaluationFinished. This is a great exercise for me to do what I tell others to do: "just update your loggers to use ProjectEvaluationFinished instead". It appears to be not as trivial and will require some thinking. I'll continue on this tomorrow. Perhaps the best thing would be to change the |
This is a reasonable plan, I think. One note: the failing test that's trying to disambiguate TFs of the same project is not actually turned on in the SDK at the moment (dotnet/sdk#12030). But we'd like to get that in at some point. However, maybe we should take from this that the change is more impactful than we hoped :( |
Yes, I agree we had a hole where the console loggers didn't properly look up items from ProjectEvaluationFinished. I've found a relatively simple way to plug that hole. Now we're going to store the results for an evaluation if we find them, and copy them to each project (since the project now points back to its evaluation). We could still ship this one PR, or I could split it into just the |
Someone please revoke my coding license. Changing var a = Array.Empty<DictionaryEntry>().Any(d => d.Value != null); // false
var b = Array.Empty<DictionaryEntry>().All(d => d.Value != null); // true |
Ugh, this suddenly spiraled way out of control. I'll continue on this tomorrow. |
Filed #6518 to look closer into
|
@@ -725,7 +746,7 @@ internal static void BuildProjectExpectSuccess | |||
params ILogger[] loggers | |||
) | |||
{ | |||
Project project = CreateInMemoryProject(projectContents, logger: null); // logger is null so we take care of loggers ourselves |
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.
Since we were explicitly nulling out the logger here, we were dropping all evaluation events.
setColor(ConsoleColor.DarkGray); | ||
foreach (ITaskItem item in itemTypeList) |
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.
Earlier we only used to get items of type ITaskItem
(from ProjectStartedEventArgs
). Now we can also get instances of ProjectItem
(from ProjectEvaluationFinishedEventArgs
), which don't implement either ITaskItem
or IMetadataContainer
. Hence some ugly pattern-matching and special-casing. Made me wonder whether ProjectItem
should implement ITaskItem
and/or IMetadataContainer
.
Also this behavior seems to break the test TestItemsWithUnexpandableMetadata
(#6518)
{ | ||
var sinks = _eventSinkDictionary.Values.OfType<EventSourceSink>(); | ||
// .All() on an empty list defaults to true, we want to default to false | ||
_includeEvaluationPropertiesAndItems = sinks.Any() && sinks.All(sink => sink.IncludeEvaluationPropertiesAndItems); |
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.
Can't just switch Any
to All
without inverting the default for empty dictionaries.
Ugh, more issues in
|
That's bad news for the rest of us! Since this is pretty complicated, should we change the direction of the escape hatch for 16.10 and revert it to prior behavior in (almost all) cases? Then we can take some time to figure out a path forward. |
I've created a more targeted fix in a separate PR here: I'll continue using this PR to properly enlighten the console loggers and the test infrastructure. |
I'm now wading through the test infrastructure and noticing systemic issues with how loggers are passed to the build. Filed #6521 to clean all of that debt up. |
The more I peel off the more I discover: |
Well, I think I got the tests to pass. But this PR is a mess. I'll be cleaning it up next week. |
Write(new TaskItemData( | ||
iitem.EvaluatedInclude, | ||
iitem.Metadata.ToDictionary(m => m.Name, m => m.EvaluatedValue)), writeMetadata); | ||
} |
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 still don't understand why this suddenly became necessary.
project.Build(loggers).ShouldBeTrue(); | ||
Project project = CreateInMemoryProjectWithLoggers(projectContents, loggers); | ||
project.Build().ShouldBeTrue(); | ||
project.ProjectCollection.Dispose(); |
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.
Ugh, I'm really not sure this is how it's supposed to be.
Opt in serial and parallel console loggers to the new behavior. This should fix an inadvertent regression when a legacy logger is present that relies on either Properties or Items on ProjectStartedEventArgs to be not null, together with the binary logger that switches on the new behavior.
Using the .All() predicate on an empty sequence returns true, which is a breaking change from .Any() (which returns false). I think we should default to the old (legacy) behavior if no sinks are present in the list.
Now that OutputItems can be called for items provided by ProjectEvaluationFinished, add proper support for iterating these items and printing including all metadata.
This ensures we don't lose evaluation messages in some unit-tests.
…ectStarted. Enable the old behavior of passing properties on ProjectStartedEventArgs instead of ProjectEvaluationFinishedEventArgs (since the latter always passes all properties, so the test is not applicable).
Filed #6518 to clarify the expected behavior.
Under some conditions (in tests) we see ProjectItem instances in ProjectEvaluationFinished. Support writing those too.
…the base method instead.
Since the loggers are on the ProjectCollection already, no need to pass them again. But now we have to dispose of the ProjectCollection() to clean up the loggers.
f6adaa2
to
751a67f
Compare
This PR is a mess, so I'm closing it and starting over at #6535 |
Opt in serial and parallel console loggers to the new behavior.
This should fix an inadvertent regression when a legacy logger is present that relies on either Properties or Items on ProjectStartedEventArgs to be not null, together with the binary logger that switches on the new behavior.
Fixes #6498