-
Notifications
You must be signed in to change notification settings - Fork 387
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
Handle ref assemblies in up-to-date check #2414
Conversation
This changes how the up-to-date check collects references because ResolveProjectReferences is too early. We need to wait until project references have been redirected to ref assemblies, which happens later. It seemed easiest to just pick up the list of actual references that Compile task will use. Let me know if there seems to be a problem with this. |
cc: @rainersigwald, @jcouv |
Are there no tests for this component? |
Unfortunately, not yet. We need integration tests, so as soon as they are running, I'm going to add some. |
Thanks! I'll stop by Monday to discuss the testing strategy (I'm not familiar with the integration tests). A few scenarios come to mind with the 3 project setup (ref assemblies turned on): |
Ping @dotnet/project-system |
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.
Mostly concerned about the implementation-assembly-of-references case we discussed in dotnet/msbuild#2180 (comment).
} | ||
logger.Verbose("Found output marker '{0}'.", _markerFile); | ||
|
||
var latestInputMarker = GetLatestInput(_referenceMarkerFiles, timestampCache); |
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.
Possible future improvement: you don't actually need the latest here, since the only question is "is any reference newer than the output". You might want to look at MSBuild's IsAnyOutOfDate
for ideas.
{ | ||
_references[referenceSchema] = new HashSet<string>(changes.After.Items.Select(item => item.Value[ResolvedPath])); | ||
_compilationReferences.Add(item.Value[ResolvedPath]); |
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.
And also
_compilationReferences.Add(item.Value[OriginalPath]);
if it exists?
if (e.ProjectChanges.TryGetValue(ResolvedAnalyzerReference.SchemaName, out var changes) && | ||
changes.Difference.AnyChanges) | ||
{ | ||
_analyzerReferences = new HashSet<string>(changes.After.Items.Select(item => item.Value[ResolvedPath])); |
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.
Which sort of string comparison do we want to use for this HashSet
?
@@ -118,12 +120,27 @@ private void OnProjectChanged(IProjectSubscriptionUpdate e) | |||
_isDisabled = disableFastUpToDateCheckString != null && string.Equals(disableFastUpToDateCheckString, TrueValue, StringComparison.OrdinalIgnoreCase); | |||
|
|||
_msBuildProjectFullPath = e.CurrentState.GetPropertyOrDefault(ConfigurationGeneral.SchemaName, ConfigurationGeneral.MSBuildProjectFullPathProperty, _msBuildProjectFullPath); | |||
foreach (var referenceSchema in ReferenceSchemas) | |||
_markerFile = e.CurrentState.GetPropertyOrDefault(ConfigurationGeneral.SchemaName, ConfigurationGeneral.CopyUpToDateMarkerProperty, null); |
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.
In dotnet/msbuild#2213 I'd like to change this to be an item instead of a property. Reasoning is embedded there. Is that a problem?
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.
That might actually make it easier i think. #2416 is making it so that we just query the projectitemschemaservice for all item types and we can add CopyUpToDateMarker item to the schema. If we did that, do we still need the CheckMarkers method below? Ideally if we can avoid any special code here for the markers that would be ideal.
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.
Unfortunately, we still need CheckMarkers. The markers have to be checked independently of the project's inputs/outputs because they are independent of one another (i.e. a dependent assembly might have an implementation-only change that won't cause the outputs of the project to be rebuilt).
OK, I've updated this review to handle CopyUpToDate as an item. I had to change slightly how we handle non-build items like CopyUpToDate, UpToDateCheckInput, and UpToDateCheckOutput to make the UI work correctly (i.e. not have them show up in Solution Explorer). |
Is this ready now? @jcouv @panopticoncentral ? |
I have been using it yesterday and this morning. Seems to work on Roslyn. |
Tagging @MattGertz for Preview4 |
@jcouv Can you test some more? I added two fixes:
Regardless, the scenario we were testing today now seems to work correctly. |
I'll try this iteration in the morning. |
Customer scenario
Given three projects that have a dependency as such: ClassLibrary1 -> ClassLibrary2 -> ConsoleApp1, if the two class libraries use the new ref assembly feature, then if ClassLibrary1's implementation is changed but not its ref assembly, the up to date check will think that ConsoleApp1 does not need to be rebuilt. It does, though, so it can copy an updated ClassLibrary1 implementation.
Without this change building projects with reference assemblies will be broken in the IDE. For Roslyn.sln we're seeing around 70% reduction in incremental build times with reference assemblies. So we want to take this change to enable such productivity enhancements.
Bugs this fixes:
Fixes #2254
Workarounds, if any
The user would have to realize that one of their assemblies is out of date and do a rebuild.
Risk
Low. The marker file we depend on is only produced in the new ref assembly case, so it doesn't affect existing projects. Fast up to date checks can be turned off if needed.
Performance impact
Low. We check timestamps on a handful of extra files, small compared to the list of files we already check.
Is this a regression from a previous update?
No.