diff --git a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.CodeGeneration.targets b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.CodeGeneration.targets index 5b1648e93c..3cb1e75bb0 100644 --- a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.CodeGeneration.targets +++ b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.CodeGeneration.targets @@ -96,8 +96,8 @@ Condition="'@(RazorGenerate)'!= ''"> + Directories="$(RazorGenerateIntermediateOutputPath)" + Condition = "Exists('$(RazorGenerateIntermediateOutputPath)')"/> + OutputPath="$(RazorGenerateIntermediateOutputPath)" /> @@ -120,6 +120,18 @@ + + /$([System.String]::Copy('%(Identity)').Replace('\','/')) + Non-Resx + false + + + + + + <_RazorCoreCompileResourceInputs + Include="@(RazorEmbeddedResource)" + Condition="'%(RazorEmbeddedResource.WithCulture)'=='false' and '%(RazorEmbeddedResource.Type)'=='Non-Resx' " /> diff --git a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets index 02df10972a..71b6f09f41 100644 --- a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets +++ b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.Compilation.targets @@ -17,11 +17,13 @@ Replace @(_DebugSymbolsIntermediatePath) with @(_RazorDebugSymbolsIntermediatePath) Replace @(IntermediateAssembly) with @(RazorIntermediateAssembly) Replace @(ReferencePathWithRefAssemblies) with @(RazorReferencePath) + Remove @(_CoreCompileResourceInputs) with @(_RazorCoreCompileResourceInputs) Set TargetType="$(OutputType)" to TargetType="Library" - Razor is always a .dll Remove Returns="@(CscCommandLineArgs)" - Remove @(_CoreCompileResourceInputs) + + Remove @(EmbeddedFiles) Remove $(ApplicationIcon) $(Win32Resource) $(Win32Manifest) Remove @(EmbeddedDocumentation) and @(EmbeddedFiles) Remove @(CustomAdditionalCompileInputs) and @(CustomAdditionalCompileOutputs) @@ -43,7 +45,8 @@ @(CompiledLicenseFile); @(LinkResource); $(ResolvedCodeAnalysisRuleSet); - @(AdditionalFiles)" + @(AdditionalFiles); + @(_RazorCoreCompileResourceInputs)" Outputs="@(RazorIntermediateAssembly); @(_RazorDebugSymbolsIntermediatePath); $(NonExistentFile)" @@ -134,7 +137,7 @@ ProvideCommandLineArgs="$(ProvideCommandLineArgs)" References="@(RazorReferencePath)" ReportAnalyzer="$(ReportAnalyzer)" - Resources="@(CompiledLicenseFile)" + Resources="@(_RazorCoreCompileResourceInputs);@(CompiledLicenseFile)" ResponseFiles="$(CompilerResponseFile)" RuntimeMetadataVersion="$(RuntimeMetadataVersion)" SharedCompilationId="$(SharedCompilationId)" diff --git a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props index ae938b6ba3..66f5aaa762 100644 --- a/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props +++ b/src/Microsoft.AspNetCore.Razor.Design/build/netstandard2.0/Microsoft.AspNetCore.Razor.Design.props @@ -3,6 +3,32 @@ Properties and tasks supporting Razor MSBuild integration --> + + + + true + + + false + + + false + + @@ -42,45 +41,64 @@ + + false + + + + + true + + + $(MvcRazorCompileOnPublish) + + + true + + + + - - false - true - - $(IntermediateOutputPath)Razor\ + $(IntermediateOutputPath)Razor\ $(TargetName).PrecompiledViews - - false + false + true + + false + true - false + $([MSBuild]::EnsureTrailingSlash('$(MvcRazorOutputPath)')) + + + $(MvcRazorEmbedViewSources) + false - - - - - - <_RazorDebugSymbolsProduced>false @@ -92,10 +110,14 @@ <_RazorDebugSymbolsProduced Condition="'$(DebugType)'=='embedded'">false + - + + + <_RazorDebugSymbolsIntermediatePath Condition="'$(_RazorDebugSymbolsProduced)'=='true'" Include="$(IntermediateOutputPath)$(RazorTargetName).pdb" /> - <_RazorDebugSymbolsOutputPath Include="@(_RazorDebugSymbolsIntermediatePath->'$(OutDir)%(Filename)%(Extension)')" /> + + + false + - - $(RazorGenerateOutputPath)%(RelativeDir)%(Filename).cs + + + + + + + + + + $(RazorGenerateIntermediateOutputPath)%(RelativeDir)%(Filename).cs @@ -177,8 +215,12 @@ BeforeTargets="BuiltProjectOutputGroup" Condition="'$(ResolvedRazorCompileToolset)'=='RazorSdk' and '$(RazorCompileOnBuild)'=='true'"> + + $([MSBuild]::EnsureTrailingSlash('$(OutDir)')) + + - + @@ -250,10 +292,14 @@ AfterTargets="CopyFilesToOutputDirectory" Condition="'$(ResolvedRazorCompileToolset)'=='RazorSdk' and '$(RazorCompileOnBuild)'=='true'"> + + $([MSBuild]::EnsureTrailingSlash('$(OutDir)')) + + r)); + } + + [Fact] + [InitializeTestProject("SimpleMvc")] + public async Task RazorCompile_MvcRazorEmbedViewSources_EmbedsCshtmlFiles() + { + var result = await DotnetMSBuild("RazorCompile", "/p:EmbedRazorGenerateSources=true"); + + Assert.BuildPassed(result); + + Assert.FileExists(result, IntermediateOutputPath, "SimpleMvc.PrecompiledViews.dll"); + + var assembly = LoadAssemblyFromBytes(result.Project.DirectoryPath, IntermediateOutputPath, "SimpleMvc.PrecompiledViews.dll"); + var resources = assembly.GetManifestResourceNames(); + + Assert.Equal(new string[] + { + "/Views/_ViewImports.cshtml", + "/Views/_ViewStart.cshtml", + "/Views/Home/About.cshtml", + "/Views/Home/Contact.cshtml", + "/Views/Home/Index.cshtml", + "/Views/Shared/_Layout.cshtml", + "/Views/Shared/_ValidationScriptsPartial.cshtml", + "/Views/Shared/Error.cshtml", + }, + resources.OrderBy(r => r)); + } + + private Assembly LoadAssemblyFromBytes(params string[] paths) + { + // We need to load the assembly from bytes to load it without locking the file - and yes, we need to + // load the pdb too, or else the CLR will load/lock it based on the path specified in the assembly. + var assemblyBytes = File.ReadAllBytes(Path.Combine(paths)); + var symbolBytes = File.ReadAllBytes(Path.ChangeExtension(Path.Combine(paths), ".pdb")); + return Assembly.Load(assemblyBytes, symbolBytes); + } } } diff --git a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/RazorGenerateIntegrationTest.cs b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/RazorGenerateIntegrationTest.cs index c479e80dfa..af4dd592d1 100644 --- a/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/RazorGenerateIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Design.Test/IntegrationTests/RazorGenerateIntegrationTest.cs @@ -200,5 +200,52 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.FileCountEquals(result, 0, RazorIntermediateOutputPath, "*.cs"); } + + [Fact] + [InitializeTestProject("SimpleMvc")] + public async Task RazorGenerate_MvcRazorFilesToCompile_OverridesDefaultItems() + { + var content = @" + + + + + + +"; + File.WriteAllText(Path.Combine(Project.DirectoryPath, "Directory.Build.props"), content); + + var result = await DotnetMSBuild(RazorGenerateTarget); + + Assert.BuildPassed(result); + + Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cs"); + Assert.FileCountEquals(result, 1, RazorIntermediateOutputPath, "*.cs"); + } + + [Fact] + [InitializeTestProject("SimpleMvc")] + public async Task RazorGenerate_EnableDefaultRazorGenerateItems_False_OverridesDefaultItems() + { + var content = @" + + + + false + + + + + +"; + File.WriteAllText(Path.Combine(Project.DirectoryPath, "Directory.Build.props"), content); + + var result = await DotnetMSBuild(RazorGenerateTarget); + + Assert.BuildPassed(result); + + Assert.FileExists(result, RazorIntermediateOutputPath, "Views", "Home", "About.cs"); + Assert.FileCountEquals(result, 1, RazorIntermediateOutputPath, "*.cs"); + } } }