Skip to content

Commit

Permalink
[release/9.0] [browser] Fix processing of satellite assemblies from r…
Browse files Browse the repository at this point in the history
…eferenced assembly during publish (#107398)

* Fix related asset computation for satellites from reference (not projectReference) where ResolvedFrom contains {RawFileName}

* WBT

* Don't remove files with DestinationSubDirectory from ResolvedFileToPublish because they can be resource assemblies from References

* Feedback

* Fix condition

* We can't check for RawFileName, because ProjectReference satellites goes through the same path and are not discovered by nested publish

* Comment about "{RawFileName}"

* Explicitly set ResolveAssemblyReferencesFindRelatedSatellites=true for nested publish

---------

Co-authored-by: Marek Fišera <mara@neptuo.com>
Co-authored-by: Larry Ewing <lewing@microsoft.com>
Co-authored-by: Jeff Schwartz <jeffschw@microsoft.com>
  • Loading branch information
4 people committed Sep 12, 2024
1 parent 73229ad commit 24cd94c
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.Playwright;
using Xunit.Abstractions;
using Xunit;
using System.Xml.Linq;

#nullable enable

Expand Down Expand Up @@ -38,4 +39,44 @@ public async Task LoadSatelliteAssembly()
m => Assert.Equal("es-ES with satellite: hola", m)
);
}

[Fact]
public async Task LoadSatelliteAssemblyFromReference()
{
CopyTestAsset("WasmBasicTestApp", "SatelliteLoadingTestsFromReference", "App");

// Replace ProjectReference with Reference
var appCsprojPath = Path.Combine(_projectDir!, "WasmBasicTestApp.csproj");
var appCsproj = XDocument.Load(appCsprojPath);

var projectReference = appCsproj.Descendants("ProjectReference").Where(pr => pr.Attribute("Include")?.Value?.Contains("ResourceLibrary") ?? false).Single();
var itemGroup = projectReference.Parent!;
projectReference.Remove();

var reference = new XElement("Reference");
reference.SetAttributeValue("Include", "..\\ResourceLibrary\\bin\\Release\\net9.0\\ResourceLibrary.dll");
itemGroup.Add(reference);

appCsproj.Save(appCsprojPath);

// Build the library
var libraryCsprojPath = Path.GetFullPath(Path.Combine(_projectDir!, "..", "ResourceLibrary"));
new DotNetCommand(s_buildEnv, _testOutput)
.WithWorkingDirectory(libraryCsprojPath)
.WithEnvironmentVariable("NUGET_PACKAGES", _nugetPackagesDir)
.ExecuteWithCapturedOutput("build -c Release")
.EnsureSuccessful();

// Publish the app and assert
PublishProject("Release");

var result = await RunSdkStyleAppForPublish(new(Configuration: "Release", TestScenario: "SatelliteAssembliesTest"));
Assert.Collection(
result.TestOutput,
m => Assert.Equal("default: hello", m),
m => Assert.Equal("es-ES without satellite: hello", m),
m => Assert.Equal("default: hello", m),
m => Assert.Equal("es-ES with satellite: hola", m)
);
}
}
2 changes: 1 addition & 1 deletion src/mono/wasm/build/WasmApp.Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@
<!-- Use a unique property, so the already run wasm targets can also run -->
<MSBuild Projects="$(MSBuildProjectFile)"
Targets="WasmNestedPublishApp"
Properties="_WasmInNestedPublish_UniqueProperty_XYZ=true;;WasmBuildingForNestedPublish=true;DeployOnBuild=;_IsPublishing=;_WasmIsPublishing=$(_IsPublishing)">
Properties="_WasmInNestedPublish_UniqueProperty_XYZ=true;;WasmBuildingForNestedPublish=true;DeployOnBuild=;_IsPublishing=;_WasmIsPublishing=$(_IsPublishing);ResolveAssemblyReferencesFindRelatedSatellites=true">
<Output TaskParameter="TargetOutputs" ItemName="WasmNestedPublishAppResultItems" />
</MSBuild>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Globalization;
using System.Threading.Tasks;
using System.Resources;
using System.Runtime.InteropServices.JavaScript;
using System.Threading.Tasks;

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

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

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

[JSImport("INTERNAL.loadSatelliteAssemblies")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<ItemGroup>
<ProjectReference Include="..\Library\Json.csproj" />
<ProjectReference Include="..\ResourceLibrary\ResourceLibrary.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Text.Json;
using System.Text.Json.Serialization;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Globalization;
using System.Threading.Tasks;
using System.Resources;

namespace ResourceLibrary;

public static class ResourceAccessor
{
public static void Read(Action<string> testOuput, bool hasSatellites)
{
var rm = new ResourceManager("ResourceLibrary.words", typeof(ResourceAccessor).Assembly);
testOuput($"default: {rm.GetString("hello", CultureInfo.CurrentCulture)}");
testOuput($"es-ES {(hasSatellites ? "with" : "without")} satellite: {rm.GetString("hello", new CultureInfo("es-ES"))}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ public override bool Execute()
assetCandidate.SetMetadata("AssetTraitName", "Culture");
assetCandidate.SetMetadata("AssetTraitValue", inferredCulture);
assetCandidate.SetMetadata("RelativePath", $"_framework/{inferredCulture}/{satelliteAssembly.GetMetadata("FileName")}{satelliteAssembly.GetMetadata("Extension")}");
assetCandidate.SetMetadata("RelatedAsset", Path.GetFullPath(Path.Combine(OutputPath, "wwwroot", "_framework", Path.GetFileName(assetCandidate.GetMetadata("ResolvedFrom")))));

var resolvedFrom = assetCandidate.GetMetadata("ResolvedFrom");
if (resolvedFrom == "{RawFileName}") // Satellite assembly found from `<Reference />` element
resolvedFrom = candidate.GetMetadata("OriginalItemSpec");

assetCandidate.SetMetadata("RelatedAsset", Path.GetFullPath(Path.Combine(OutputPath, "wwwroot", "_framework", Path.GetFileName(resolvedFrom))));

assetCandidates.Add(assetCandidate);
continue;
Expand Down

0 comments on commit 24cd94c

Please sign in to comment.