From 4a2f9d3015a2a5217cdd1c1d3c91e5798c273d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 2 Jun 2023 03:11:39 +0200 Subject: [PATCH] [browser] Fix fingerprinting of relinked dotnet.js during build (#86048) * Fix reading version of relinked dotnet.js during build * Support .NET 7 file name * Add WBT test * Fix publish fingerprinting * ConvertDllsToWebCil: fix path concatenation --------- Co-authored-by: Ankit Jain --- ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 5 +++ .../Blazor/BuildPublishTests.cs | 12 ++++++ .../wasm/Wasm.Build.Tests/BuildTestBase.cs | 39 ++++++++++++++++++- .../Wasm.Build.Tests/Wasm.Build.Tests.csproj | 1 + .../ComputeWasmBuildAssets.cs | 5 ++- .../ComputeWasmPublishAssets.cs | 9 +++-- .../ConvertDllsToWebCil.cs | 2 +- 7 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index c8296deecbf02c..7b9af4e65a5399 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -190,11 +190,15 @@ Copyright (c) .NET Foundation. All rights reserved. <_WasmConfigFileCandidates Include="@(StaticWebAsset)" Condition="'%(SourceType)' == 'Discovered'" /> + <_DotNetJsItem Include="@(ReferenceCopyLocalPaths)" Condition="('%(FileName)' == 'dotnet' or '%(FileName)' == 'dotnet.native') and '%(Extension)' == '.js'" /> + + <_DotNetJsBuildVersion>%(_DotNetJsItem.NuGetPackageVersion) + k.StartsWith("dotnet.") && k.EndsWith(".js")).ToArray(); + + void AssertFileExists(string fileName) + { + string absolutePath = Path.Combine(binFrameworkDir, fileName); + Assert.True(File.Exists(absolutePath), $"Expected to find '{absolutePath}'"); + } + + string versionHashRegex = @"\d.0.\d?(-[a-z]+(\.\d\.\d+\.\d)?)?\.([a-zA-Z0-9])+"; + Assert.Collection( + dotnetJsEntries.OrderBy(f => f), + item => { Assert.Equal(expectFingerprinting ? $"dotnet\\.{versionHashRegex}\\.js" : "dotnet.js", item); AssertFileExists(item); }, + item => { Assert.Matches($"dotnet\\.native\\.{versionHashRegex}\\.js", item); AssertFileExists(item); }, + item => { Assert.Matches($"dotnet\\.runtime\\.{versionHashRegex}\\.js", item); AssertFileExists(item); } + ); + } + } + + private static BootJsonData ParseBootData(Stream stream) + { + stream.Position = 0; + var serializer = new DataContractJsonSerializer( + typeof(BootJsonData), + new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true }); + + var config = (BootJsonData?)serializer.ReadObject(stream); + Assert.NotNull(config); + return config; } protected void AssertBlazorBootJson(string config, bool isPublish, bool isNet7AndBelow, string targetFramework = DefaultTargetFrameworkForBlazor, string? binFrameworkDir = null) diff --git a/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj b/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj index 1f2f1d2ad7ecfe..0ff15466c29ef6 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj +++ b/src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj @@ -33,6 +33,7 @@ + diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs index d8fe399652dc7a..580f5288b2ccb2 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs @@ -31,6 +31,9 @@ public class ComputeWasmBuildAssets : Task [Required] public ITaskItem[] ProjectSatelliteAssemblies { get; set; } + [Required] + public string DotNetJsVersion { get; set; } + [Required] public string OutputPath { get; set; } @@ -114,7 +117,7 @@ public override bool Execute() if (candidateFileName != "dotnet" || FingerprintDotNetJs) { var itemHash = FileHasher.GetFileHash(candidate.ItemSpec); - newDotnetJSFileName = $"{candidateFileName}.{candidate.GetMetadata("NuGetPackageVersion")}.{itemHash}.js"; + newDotnetJSFileName = $"{candidateFileName}.{DotNetJsVersion}.{itemHash}.js"; var originalFileFullPath = Path.GetFullPath(candidate.ItemSpec); var originalFileDirectory = Path.GetDirectoryName(originalFileFullPath); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs index 60c1afd1f02efe..a94c95bc9ddadd 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs @@ -216,7 +216,7 @@ private List ProcessNativeAssets( newDotNetJs = new TaskItem(Path.GetFullPath(aotDotNetJs.ItemSpec), asset.CloneCustomMetadata()); newDotNetJs.SetMetadata("OriginalItemSpec", aotDotNetJs.ItemSpec); - string relativePath = FingerprintDotNetJs + string relativePath = baseName != "dotnet" || FingerprintDotNetJs ? $"_framework/{$"{baseName}.{DotNetJsVersion}.{FileHasher.GetFileHash(aotDotNetJs.ItemSpec)}.js"}" : $"_framework/{baseName}.js"; @@ -242,8 +242,9 @@ private List ProcessNativeAssets( if (isDotNetWasm) { - var aotDotNetWasm = WasmAotAssets.SingleOrDefault(a => { - var name= $"{a.GetMetadata("FileName")}{a.GetMetadata("Extension")}"; + var aotDotNetWasm = WasmAotAssets.SingleOrDefault(a => + { + var name = $"{a.GetMetadata("FileName")}{a.GetMetadata("Extension")}"; return name == "dotnet.native.wasm" || name == "dotnet.wasm"; }); ITaskItem newDotNetWasm = null; @@ -589,7 +590,7 @@ private void GroupResolvedFilesToPublish( } var extension = candidate.GetMetadata("Extension"); - if (string.Equals(extension, ".dll", StringComparison.Ordinal) || string.Equals (extension, Utils.WebcilInWasmExtension, StringComparison.Ordinal)) + if (string.Equals(extension, ".dll", StringComparison.Ordinal) || string.Equals(extension, Utils.WebcilInWasmExtension, StringComparison.Ordinal)) { var culture = candidate.GetMetadata("Culture"); var inferredCulture = candidate.GetMetadata("DestinationSubDirectory").Replace("\\", "/").Trim('/'); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs index 4bbbf8f62501d7..f5d0288ffe4e4f 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ConvertDllsToWebCil.cs @@ -66,7 +66,7 @@ public override bool Execute() var tmpDir = IntermediateOutputPath; if (!Directory.Exists(tmpDir)) Directory.CreateDirectory(tmpDir); - var tmpWebcil = string.Concat (tmpDir, webcilFileName); + var tmpWebcil = Path.Combine(tmpDir, webcilFileName); var webcilWriter = Microsoft.WebAssembly.Build.Tasks.WebcilConverter.FromPortableExecutable(inputPath: filePath, outputPath: tmpWebcil, logger: Log); webcilWriter.ConvertToWebcil();