Ensure ApplicationPart attributes are added during incremental builds (dotnet/aspnetcore-tooling#686)

Fixes https://github.com/aspnet/AspNetCore/issues/11315\n\nCommit migrated from 1a7a74bce8
This commit is contained in:
Pranav K 2019-06-19 11:43:07 -07:00 committed by GitHub
parent c16d55c63f
commit 060ff0d878
3 changed files with 69 additions and 1 deletions

View File

@ -67,7 +67,16 @@ Copyright (c) .NET Foundation. All rights reserved.
OutputFile="$(_MvcApplicationPartAttributeGeneratedFile)"
Condition="'@(_ApplicationPartAssemblyNames->Count())' != '0'" />
<ItemGroup Condition="'@(_ApplicationPartAssemblyNames->Count())' != '0'">
<!--
If the generated attribute file exists, but no assembly names were discovered,
it suggests that the assembly references were changed to no longer point to MVC.
In this case, delete the file so that future incremental builds can no longer pick it up.
-->
<Delete
File="$(_MvcApplicationPartAttributeGeneratedFile)"
Condition="'@(_ApplicationPartAssemblyNames->Count())' == '0' AND Exists('$(_MvcApplicationPartAttributeGeneratedFile)')" />
<ItemGroup Condition="Exists('$(_MvcApplicationPartAttributeGeneratedFile)')">
<Compile Remove="$(_MvcApplicationPartAttributeGeneratedFile)" Condition="'$(Language)'!='F#'" />
<Compile Include="$(_MvcApplicationPartAttributeGeneratedFile)" Condition="'$(Language)'!='F#'" />

View File

@ -34,6 +34,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.FileExists(result, IntermediateOutputPath, "AppWithP2PReference.MvcApplicationPartsAssemblyInfo.cs");
Assert.FileContains(result, Path.Combine(IntermediateOutputPath, "AppWithP2PReference.MvcApplicationPartsAssemblyInfo.cs"), "[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute(\"ClassLibrary\")]");
Assert.AssemblyHasAttribute(result, Path.Combine(OutputPath, "AppWithP2PReference.dll"), "Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute");
}
[Fact]
@ -69,6 +70,33 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.FileExists(result, generatedAttributeFile);
Assert.Equal(thumbPrint, GetThumbPrint(generatedAttributeFile));
Assert.AssemblyHasAttribute(result, Path.Combine(OutputPath, "AppWithP2PReference.dll"), "Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute");
}
// Regression test for https://github.com/aspnet/AspNetCore/issues/11315
[Fact]
[InitializeTestProject("AppWithP2PReference", additionalProjects: "ClassLibrary")]
public async Task BuildIncrementalism_CausingRecompilation_WhenApplicationPartAttributeIsGenerated()
{
var result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
var generatedAttributeFile = Path.Combine(IntermediateOutputPath, "AppWithP2PReference.MvcApplicationPartsAssemblyInfo.cs");
Assert.FileExists(result, generatedAttributeFile);
Assert.FileContains(result, generatedAttributeFile, "[assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute(\"ClassLibrary\")]");
var thumbPrint = GetThumbPrint(generatedAttributeFile);
// Touch a file in the main app which should call recompilation, but not the Mvc discovery tasks to re-run.
File.AppendAllText(Path.Combine(Project.DirectoryPath, "Program.cs"), " ");
result = await DotnetMSBuild("Build");
Assert.BuildPassed(result);
Assert.FileExists(result, generatedAttributeFile);
Assert.Equal(thumbPrint, GetThumbPrint(generatedAttributeFile));
Assert.AssemblyHasAttribute(result, Path.Combine(OutputPath, "AppWithP2PReference.dll"), "Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute");
}
[Fact]
@ -88,6 +116,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
Assert.FileExists(result, IntermediateOutputPath, "SimpleMvcFSharp.MvcApplicationPartsAssemblyInfo.fs");
Assert.FileContains(result, Path.Combine(IntermediateOutputPath, "SimpleMvcFSharp.MvcApplicationPartsAssemblyInfo.fs"), "<assembly: Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute(\"ClassLibrary\")>");
Assert.AssemblyHasAttribute(result, Path.Combine(OutputPath, "SimpleMvcFSharp.dll"), "Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute");
}
[Fact]

View File

@ -507,6 +507,36 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests
}
}
public static void AssemblyHasAttribute(MSBuildResult result, string assemblyPath, string fullTypeName)
{
if (result == null)
{
throw new ArgumentNullException(nameof(result));
}
assemblyPath = Path.Combine(result.Project.DirectoryPath, Path.Combine(assemblyPath));
var typeNames = GetAssemblyAttributes(assemblyPath);
Assert.Contains(fullTypeName, typeNames);
}
private static IEnumerable<string> GetAssemblyAttributes(string assemblyPath)
{
using (var file = File.OpenRead(assemblyPath))
{
var peReader = new PEReader(file);
var metadataReader = peReader.GetMetadataReader();
return metadataReader.CustomAttributes.Where(t => !t.IsNil).Select(t =>
{
var attribute = metadataReader.GetCustomAttribute(t);
var constructor = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
var type = metadataReader.GetTypeReference((TypeReferenceHandle)constructor.Parent);
return metadataReader.GetString(type.Namespace) + "." + metadataReader.GetString(type.Name);
}).ToArray();
}
}
private abstract class MSBuildXunitException : Xunit.Sdk.XunitException
{
protected MSBuildXunitException(MSBuildResult result)