Skip to content

Commit 0342fe5

Browse files
brendanzagaeskijonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] Move XA4214 warning text into .resx file (#3900)
Context: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1009374/ This is a first step toward localizing the MSBuild error and warning messages produced by `Xamarin.Android.Build.Tasks.dll`. We will be following the [.NET Resource Localization pattern][0] and generating satellite assemblies using [`.resx` files][1], in particular `src/Xamarin.Android.Build.Tasks/Properties/Resources.resx`. `Resources.resx` is an XML file, and will contain `/root/data` elements in which `//data/@name` will start with the Xamarin.Android error or warning code, and `//data/value` will be the error or warning message: <root> <data name="XA4214" xml:space="preserve"> <value>The managed type `{0}` exists in multiple assemblies: {1}. Please refactor the managed type names in these assemblies so that they are not identical.</value> </data> </root> An optional `//data/comment` element may be provided to describe the meaning within the `//data/value` element to translators: <data name="XA4214" xml:space="preserve"> <value>The managed type `{0}` exists in multiple assemblies: {1}. Please refactor the managed type names in these assemblies so that they are not identical.</value> <comment> {0} - The managed type name {1} - Comma-separated list of all the assemblies where the managed type exists </comment> </data> During the build, `Resources.resx` will be translated into a `Resources.Designer.cs` file: namespace Xamarin.Android.Tasks.Properties { internal partial class Resources { internal static string XA4214 { get => ... } } } The `Resources` members should be used to obtain all strings for use in `LogCodedError()` and `LogCodedWarning()` calls: Log.LogCodedWarning ("XA4214", Properties.Resources.XA4214, kvp.Key, string.Join (", ", kvp.Value)); When an MSBuild error or warning code is used with more than one output string, then a semantically meaningful suffix should be used to distinguish between the two: <data name="XA4214_Result" xml:space="preserve"> <value>References to the type `{0}` will refer to `{0}, {1}`.</value> </data> Note that this infrastructure does not interoperate with C#6 string interpolation. Any error or warning messages currently using C#6 string interpolation will need to use .NET 1.0-style format strings. Our translation team doesn't work directly with `.resx` files. Instead, the translation team works with [XLIFF files][2]. `Resources.resx` is converted into a set of `src/Xamarin.Android.Build.Tasks/Properties/xlf/Resources.*.xlf` files via `XliffTasks.targets` from the [dotnet/xliff-tasks][3] repo. The `Resources.*.xlf` files should be automatically updated whenever `Resources.resx` is updated. Other: * This approach leaves the error code `XA4214` as a string literal for now. This differs from what dotnet/sdk and microsoft/msbuild do; they instead include the message code as part of the string resource in the `.resx` file. That might sometimes provide useful additional context for the translation team, but it also requires using a different set of logging methods from `Microsoft.Build.Utilities.TaskLoggingHelper`. * Fix the Test MSBuild Azure Pipelines build Specify the `feedsToUse` and `nugetConfigPath` inputs for the [`NuGetCommand@2`][6] Azure Pipelines task so that the NuGet restore step will be able to restore XliffTasks successfully from the dotnet-eng Azure DevOps NuGet package feed. This resolves the following error: The nuget command failed with exit code(1) and error(Errors in packages.config projects Unable to find version '1.0.0-beta.19252.1' of package 'XliffTasks'. C:\Users\dlab14\.nuget\packages\: Package 'XliffTasks.1.0.0-beta.19252.1' is not found on source 'C:\Users\dlab14\.nuget\packages\'. https://api.nuget.org/v3/index.json: Package 'XliffTasks.1.0.0-beta.19252.1' is not found on source 'https://api.nuget.org/v3/index.json'.) TODO: * When `Xamarin.Android.Build.Tasks.csproj` is converted into a [short-form project][4], add a dependency on dotnet/arcade and switch to using the [`GenerateResxSource` mechanism][5] instead of using `%(EmbeddedResource.Generator)`=ResXFileCodeGenerator and set `$(UsingToolXliff)`=True. This would match dotnet/sdk. [0]: https://docs.microsoft.com/dotnet/framework/resources/index [1]: https://docs.microsoft.com/dotnet/framework/resources/creating-resource-files-for-desktop-apps#resources-in-resx-files [2]: http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html [3]: https://github.com/dotnet/xliff-tasks [4]: https://docs.microsoft.com/visualstudio/msbuild/how-to-use-project-sdk [5]: https://github.com/dotnet/arcade/blob/e67d9f098029ebecedf11012a749b532d68ad2a9/Documentation/ArcadeSdk.md#generateresxsource-bool [6]: https://docs.microsoft.com/azure/devops/pipelines/tasks/package/nuget
1 parent eff77a4 commit 0342fe5

27 files changed

+582
-7
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*.Designer.cs eol=crlf
2020

2121
*.cs text
22+
*.resx text
23+
*.xlf text
2224
*.xml text
2325
*.md text
2426
Makefile eol=lf

Configuration.props

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@
175175
<RemapAssemblyRefTool>$(ManagedRuntime) $(ManagedRuntimeArgs) &quot;$(RemapAssemblyRefToolExecutable)&quot;</RemapAssemblyRefTool>
176176
</PropertyGroup>
177177

178+
<PropertyGroup>
179+
<XlfLanguages>cs;de;es;fr;it;ja;ko;pl;pt-BR;ru;tr;zh-Hans;zh-Hant</XlfLanguages>
180+
<UpdateXlfOnBuild Condition="'$(RunningOnCI)' != 'true'">true</UpdateXlfOnBuild>
181+
</PropertyGroup>
182+
178183
<!-- Unit Test Properties -->
179184
<PropertyGroup>
180185
<_Runtime Condition=" '$(HostOS)' != 'Windows' ">$(ManagedRuntime) $(ManagedRuntimeArgs)</_Runtime>

Documentation/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
* [Using Your Build](workflow/UsingYourBuild.md)
4040
* [Jenkins Build Artifacts](workflow/JenkinsBuildArtifacts.md)
4141
* [Development tips and native debugging](workflow/DevelopmentTips.md)
42+
* [Localization](workflow/Localization.md)
4243

4344

4445
# Coding Guidelines
10.9 KB
Loading
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Localization
2+
3+
All new Xamarin.Android MSBuild error or warning messages should be localizable,
4+
so when adding a new message, follow these steps:
5+
6+
1. Add the new message to
7+
`src/Xamarin.Android.Build.Tasks/Properties/Resources.resx`. Use the error
8+
or warning code as the resource name. For example, for `XA0000`, use
9+
`XA0000` as the name:
10+
11+
![Managed Resources Editor with XA0000 as the name for a
12+
resource][resources-editor]
13+
14+
Be sure to use Visual Studio or Visual Studio for Mac to edit the `.resx`
15+
file so that the `ResXFileCodeGenerator` tool will run and update the
16+
corresponding `Resources.Designer.cs` file.
17+
18+
2. Use the generated property from `Resources.Designer.cs` in the
19+
`LogCodedError()` and `LogCodedWarning()` calls:
20+
21+
```csharp
22+
Log.LogCodedError ("XA0000", Properties.Resources.XA0000);
23+
```
24+
25+
3. After adding the new message, build `Xamarin.Android.Build.Tasks.csproj`
26+
locally. This will run the targets from [dotnet/xliff-tasks][xliff-tasks]
27+
to update the `.xlf` [XLIFF][xliff] localization files with the latest
28+
changes from the `.resx` file.
29+
30+
4. Include the changes to the`.resx` file as well as the generated changes to
31+
the `Resources.Designer.cs` file and the `.xlf` files in the commit.
32+
33+
## Guidelines
34+
35+
* When an error or warning code is used with more than one output string, use
36+
semantically meaningful suffixes to distinguish the resource names. As a
37+
made-up example:
38+
39+
```xml
40+
<data name="XA0000_Files" xml:space="preserve">
41+
<value>Invalid files.</value>
42+
</data>
43+
<data name="XA0000_Directories" xml:space="preserve">
44+
<value>Invalid directories.</value>
45+
</data>
46+
```
47+
48+
* To include values of variables in the message, use numbered format items
49+
like `{0}` and `{1}` rather than string interpolation or string
50+
concatenation.
51+
52+
The `.resx` infrastructure does not interoperate with C# 6 string
53+
interpolation.
54+
55+
String concatenation should also be avoided because it means splitting up
56+
the message across multiple string resources, which makes it more
57+
complicated to provide appropriate context to the translators.
58+
59+
* Use the comments field in the `.resx` file to provide additional context to
60+
the translators. For example, if a format item like `{0}` needs additional
61+
explanation, add a comment:
62+
63+
```
64+
{0} - The managed type name
65+
```
66+
67+
For a few more examples, see the dotnet/sdk repo:
68+
69+
https://github.com/dotnet/sdk/blob/master/src/Tasks/Common/Resources/Strings.resx
70+
71+
[resources-editor]: ../images/resources-editor-xa0000.png
72+
[xliff-tasks]: https://github.com/dotnet/xliff-tasks
73+
[xliff]: http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html

NuGet.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<packageSources>
44
<clear />
55
<!-- ensure only the sources defined below are used -->
6+
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" protocolVersion="3" />
67
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
78
</packageSources>
89
</configuration>

build-tools/automation/yaml-templates/setup-test-environment.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ steps:
3737
displayName: nuget restore Xamarin.Android solutions
3838
inputs:
3939
restoreSolution: '**/Xamarin.Android*.sln'
40+
feedsToUse: config
41+
nugetConfigPath: NuGet.config
4042

4143
- task: MSBuild@1
4244
displayName: build Xamarin.Android.Tools.BootstrapTasks.csproj

build-tools/installers/create-installers.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="..\scripts\XAVersionInfo.targets" />
4+
<Import Project="..\scripts\LocalizationLanguages.projitems" />
45
<Import Project="..\..\bin\Build$(Configuration)\ProfileAssemblies.projitems" />
56
<Import Project="..\..\bin\Build$(Configuration)\Mono.Android.Apis.projitems" />
67
<UsingTask AssemblyFile="..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.ReplaceFileContents" />
@@ -195,6 +196,7 @@
195196
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.targets" />
196197
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Build.Tasks.dll" />
197198
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Build.Tasks.pdb" />
199+
<_MSBuildFiles Include="@(_LocalizationLanguages->'$(MSBuildSrcDir)\%(Identity)\Xamarin.Android.Build.Tasks.resources.dll')" />
198200
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.BuildInfo.txt" />
199201
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Cecil.dll" />
200202
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Cecil.pdb" />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<ItemGroup>
3+
<_LocalizationLanguages Include="$(XlfLanguages)" />
4+
</ItemGroup>
5+
</Project>

src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)