Ensure Views dll are copied during P2P builds

FastUpToDateCheck in VS doesn't account for changes solely to .Views.dll. This causes referencing projects to be treated as
up to date even though a referenced project rebuilt. Touch the marker file to cause referenced projects to rebuild.

Fixes https://github.com/aspnet/Razor/issues/2306

to cause it to treat
This commit is contained in:
Pranav K 2018-04-30 08:25:55 -07:00
parent 8d99ba53ce
commit 05c84f008a
4 changed files with 73 additions and 4 deletions

View File

@ -185,10 +185,24 @@ Copyright (c) .NET Foundation. All rights reserved.
<RazorIntermediateAssembly Condition="'$(RazorIntermediateAssembly)'==''" Include="$(IntermediateOutputPath)$(RazorTargetName).dll" />
<!-- Used in Compilation.targets -->
<_RazorDebugSymbolsIntermediatePath Condition="'$(_RazorDebugSymbolsProduced)'=='true'" Include="$(IntermediateOutputPath)$(RazorTargetName).pdb" />
<!-- Add all cshtml files to UpToDateCheckInput - a collection used by the IDE's project system to determine if a project needs to be rebuilt -->
<UpToDateCheckInput Condition="'$(RazorCompileOnBuild)'=='true'" Include="@(Content->WithMetadataValue('Extension', '.cshtml'))" />
</ItemGroup>
<ItemGroup>
<!--
Add all cshtml files to UpToDateCheckInput - a collection of files used by FastUpToDateCheck to determine
if any of the the project inputs have changed.
-->
<UpToDateCheckInput Condition="'$(RazorCompileOnBuild)'=='true'" Include="@(Content->WithMetadataValue('Extension', '.cshtml'))" />
<!--
Add Razor output files to UpToDateCheckBuilt - a collection of files used by FastUpToDateCheck to determine
if any of the project's outputs have changed.
-->
<UpToDateCheckBuilt Include="@(RazorIntermediateAssembly)"
Condition="'$(RazorCompileOnBuild)'=='true' AND '@(Content->WithMetadataValue('Extension', '.cshtml'))' != ''" />
</ItemGroup>
<!--
These are the targets that generate code using Razor, separated from the main file for ease of maintenance.
Most targets related to Razor code generation are defined there.
@ -487,6 +501,15 @@ Copyright (c) .NET Foundation. All rights reserved.
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
<!--
FastUpToDate check in VS does not consider the Views dll when determining if referencing projects need to be rebuilt.
We'll touch a marker file that is used during as input for up to date check. Based on
https://github.com/Microsoft/msbuild/blob/637f06e31ef46892faeb40044899a62a15b77f79/src/Tasks/Microsoft.Common.CurrentVersion.targets#L4364-L4368
-->
<Touch Files="@(CopyUpToDateMarker)" AlwaysCreate="true" Condition="'@(_RazorAssembly)' != ''">
<Output TaskParameter="TouchedFiles" ItemName="FileWrites" />
</Touch>
</Target>

View File

@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -173,5 +174,46 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.FileExists(result, OutputPath, "ClassLibrary.Views.dll");
Assert.FileExists(result, OutputPath, "ClassLibrary.Views.pdb");
}
[Fact]
[InitializeTestProject("ClassLibrary")]
public async Task Build_TouchesUpToDateMarkerFile()
{
var classLibraryDll = Path.Combine(IntermediateOutputPath, "ClassLibrary.dll");
var classLibraryViewsDll = Path.Combine(IntermediateOutputPath, "ClassLibrary.Views.dll");
var markerFile = Path.Combine(IntermediateOutputPath, "ClassLibrary.csproj.CopyComplete");
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
Assert.FileExists(result, classLibraryDll);
Assert.FileExists(result, classLibraryViewsDll);
Assert.FileExists(result, markerFile);
// Gather thumbprints before incremental build.
var classLibraryThumbPrint = GetThumbPrint(classLibraryDll);
var classLibraryViewsThumbPrint = GetThumbPrint(classLibraryViewsDll);
var markerFileThumbPrint = GetThumbPrint(markerFile);
result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
// Verify thumbprint file is unchanged between true incremental builds
Assert.Equal(classLibraryThumbPrint, GetThumbPrint(classLibraryDll));
Assert.Equal(classLibraryViewsThumbPrint, GetThumbPrint(classLibraryViewsDll));
// In practice, this should remain unchanged. However, since our tests reference
// binaries from other projects, this file gets updated by Microsoft.Common.targets
Assert.NotEqual(markerFileThumbPrint, GetThumbPrint(markerFile));
// Change a cshtml file and verify ClassLibrary.Views.dll and marker file are updated
File.AppendAllText(Path.Combine(Project.DirectoryPath, "Views", "_ViewImports.cshtml"), Environment.NewLine);
result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
Assert.Equal(classLibraryThumbPrint, GetThumbPrint(classLibraryDll));
Assert.NotEqual(classLibraryViewsThumbPrint, GetThumbPrint(classLibraryViewsDll));
Assert.NotEqual(markerFileThumbPrint, GetThumbPrint(markerFile));
}
}
}

View File

@ -18,11 +18,12 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
[InitializeTestProject("SimpleMvc")]
public async Task RazorSdk_AddsCshtmlFilesToUpToDateCheckInput()
{
var result = await DotnetMSBuild("_IntrospectUpToDateCheckInput");
var result = await DotnetMSBuild("_IntrospectUpToDateCheck");
Assert.BuildPassed(result);
Assert.BuildOutputContainsLine(result, $"UpToDateCheckInput: {Path.Combine("Views", "Home", "Index.cshtml")}");
Assert.BuildOutputContainsLine(result, $"UpToDateCheckInput: {Path.Combine("Views", "_ViewStart.cshtml")}");
Assert.BuildOutputContainsLine(result, $"UpToDateCheckBuilt: {Path.Combine(IntermediateOutputPath, "SimpleMvc.Views.dll")}");
}
[Fact]

View File

@ -7,8 +7,11 @@
<Message Text="CompileResource: %(_RazorCoreCompileResourceInputs.Identity) %(_RazorCoreCompileResourceInputs.LogicalName)" Importance="High" />
</Target>
<Target Name="_IntrospectUpToDateCheckInput">
<Target Name="_IntrospectUpToDateCheck">
<Message Text="UpToDateCheckInput: %(UpToDateCheckInput.Identity)" Importance="High" />
<Message Text="No UpToDateCheckInput input found" Importance="High" Condition="'@(UpToDateCheckInput->Count)' == '0'" />
<Message Text="UpToDateCheckBuilt: %(UpToDateCheckBuilt.Identity)" Importance="High" />
<Message Text="No UpToDateCheckBuilt input found" Importance="High" Condition="'@(UpToDateCheckBuilt->Count)' == '0'" />
</Target>
<Target Name="_IntrospectRazorCompileItems">