Skip to content

Commit 40cafd7

Browse files
authored
[browser] Fix processing of satellite assemblies from referenced assembly during publish (#106696)
1 parent e5b9dbb commit 40cafd7

10 files changed

Lines changed: 81 additions & 11 deletions

File tree

src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Microsoft.Playwright;
1212
using Xunit.Abstractions;
1313
using Xunit;
14+
using System.Xml.Linq;
1415

1516
#nullable enable
1617

@@ -38,4 +39,44 @@ public async Task LoadSatelliteAssembly()
3839
m => Assert.Equal("es-ES with satellite: hola", m)
3940
);
4041
}
42+
43+
[Fact]
44+
public async Task LoadSatelliteAssemblyFromReference()
45+
{
46+
CopyTestAsset("WasmBasicTestApp", "SatelliteLoadingTestsFromReference", "App");
47+
48+
// Replace ProjectReference with Reference
49+
var appCsprojPath = Path.Combine(_projectDir!, "WasmBasicTestApp.csproj");
50+
var appCsproj = XDocument.Load(appCsprojPath);
51+
52+
var projectReference = appCsproj.Descendants("ProjectReference").Where(pr => pr.Attribute("Include")?.Value?.Contains("ResourceLibrary") ?? false).Single();
53+
var itemGroup = projectReference.Parent!;
54+
projectReference.Remove();
55+
56+
var reference = new XElement("Reference");
57+
reference.SetAttributeValue("Include", "..\\ResourceLibrary\\bin\\Release\\net9.0\\ResourceLibrary.dll");
58+
itemGroup.Add(reference);
59+
60+
appCsproj.Save(appCsprojPath);
61+
62+
// Build the library
63+
var libraryCsprojPath = Path.GetFullPath(Path.Combine(_projectDir!, "..", "ResourceLibrary"));
64+
new DotNetCommand(s_buildEnv, _testOutput)
65+
.WithWorkingDirectory(libraryCsprojPath)
66+
.WithEnvironmentVariable("NUGET_PACKAGES", _nugetPackagesDir)
67+
.ExecuteWithCapturedOutput("build -c Release")
68+
.EnsureSuccessful();
69+
70+
// Publish the app and assert
71+
PublishProject("Release");
72+
73+
var result = await RunSdkStyleAppForPublish(new(Configuration: "Release", TestScenario: "SatelliteAssembliesTest"));
74+
Assert.Collection(
75+
result.TestOutput,
76+
m => Assert.Equal("default: hello", m),
77+
m => Assert.Equal("es-ES without satellite: hello", m),
78+
m => Assert.Equal("default: hello", m),
79+
m => Assert.Equal("es-ES with satellite: hola", m)
80+
);
81+
}
4182
}

src/mono/wasm/build/WasmApp.Common.targets

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@
442442
<!-- Use a unique property, so the already run wasm targets can also run -->
443443
<MSBuild Projects="$(MSBuildProjectFile)"
444444
Targets="WasmNestedPublishApp"
445-
Properties="_WasmInNestedPublish_UniqueProperty_XYZ=true;;WasmBuildingForNestedPublish=true;DeployOnBuild=;_IsPublishing=;_WasmIsPublishing=$(_IsPublishing)">
445+
Properties="_WasmInNestedPublish_UniqueProperty_XYZ=true;;WasmBuildingForNestedPublish=true;DeployOnBuild=;_IsPublishing=;_WasmIsPublishing=$(_IsPublishing);ResolveAssemblyReferencesFindRelatedSatellites=true">
446446
<Output TaskParameter="TargetOutputs" ItemName="WasmNestedPublishAppResultItems" />
447447
</MSBuild>
448448

src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,19 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5-
using System.Globalization;
6-
using System.Threading.Tasks;
7-
using System.Resources;
85
using System.Runtime.InteropServices.JavaScript;
6+
using System.Threading.Tasks;
97

108
public partial class SatelliteAssembliesTest
119
{
1210
[JSExport]
1311
public static async Task Run()
1412
{
15-
var rm = new ResourceManager("WasmBasicTestApp.words", typeof(Program).Assembly);
16-
TestOutput.WriteLine("default: " + rm.GetString("hello", CultureInfo.CurrentCulture));
17-
TestOutput.WriteLine("es-ES without satellite: " + rm.GetString("hello", new CultureInfo("es-ES")));
13+
ResourceLibrary.ResourceAccessor.Read(TestOutput.WriteLine, false);
1814

1915
await LoadSatelliteAssemblies(new[] { "es-ES" });
2016

21-
rm = new ResourceManager("WasmBasicTestApp.words", typeof(Program).Assembly);
22-
TestOutput.WriteLine("default: " + rm.GetString("hello", CultureInfo.CurrentCulture));
23-
TestOutput.WriteLine("es-ES with satellite: " + rm.GetString("hello", new CultureInfo("es-ES")));
17+
ResourceLibrary.ResourceAccessor.Read(TestOutput.WriteLine, true);
2418
}
2519

2620
[JSImport("INTERNAL.loadSatelliteAssemblies")]

src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
<ItemGroup>
1818
<ProjectReference Include="..\Library\Json.csproj" />
19+
<ProjectReference Include="..\ResourceLibrary\ResourceLibrary.csproj" />
1920
</ItemGroup>
2021

2122
<ItemGroup>

src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
14
using System.Text.Json;
25
using System.Text.Json.Serialization;
36

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Globalization;
6+
using System.Threading.Tasks;
7+
using System.Resources;
8+
9+
namespace ResourceLibrary;
10+
11+
public static class ResourceAccessor
12+
{
13+
public static void Read(Action<string> testOuput, bool hasSatellites)
14+
{
15+
var rm = new ResourceManager("ResourceLibrary.words", typeof(ResourceAccessor).Assembly);
16+
testOuput($"default: {rm.GetString("hello", CultureInfo.CurrentCulture)}");
17+
testOuput($"es-ES {(hasSatellites ? "with" : "without")} satellite: {rm.GetString("hello", new CultureInfo("es-ES"))}");
18+
}
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net9.0</TargetFramework>
4+
<OutputType>Library</OutputType>
5+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
6+
</PropertyGroup>
7+
</Project>

src/mono/wasm/testassets/WasmBasicTestApp/App/words.es-ES.resx renamed to src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/words.es-ES.resx

File renamed without changes.

src/mono/wasm/testassets/WasmBasicTestApp/App/words.resx renamed to src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/words.resx

File renamed without changes.

src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,12 @@ public override bool Execute()
110110
assetCandidate.SetMetadata("AssetTraitName", "Culture");
111111
assetCandidate.SetMetadata("AssetTraitValue", inferredCulture);
112112
assetCandidate.SetMetadata("RelativePath", $"_framework/{inferredCulture}/{satelliteAssembly.GetMetadata("FileName")}{satelliteAssembly.GetMetadata("Extension")}");
113-
assetCandidate.SetMetadata("RelatedAsset", Path.GetFullPath(Path.Combine(OutputPath, "wwwroot", "_framework", Path.GetFileName(assetCandidate.GetMetadata("ResolvedFrom")))));
113+
114+
var resolvedFrom = assetCandidate.GetMetadata("ResolvedFrom");
115+
if (resolvedFrom == "{RawFileName}") // Satellite assembly found from `<Reference />` element
116+
resolvedFrom = candidate.GetMetadata("OriginalItemSpec");
117+
118+
assetCandidate.SetMetadata("RelatedAsset", Path.GetFullPath(Path.Combine(OutputPath, "wwwroot", "_framework", Path.GetFileName(resolvedFrom))));
114119

115120
assetCandidates.Add(assetCandidate);
116121
continue;

0 commit comments

Comments
 (0)