From c7f05ff4b759ee068d959bb5e6419dad98859d74 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Sun, 16 May 2021 08:42:40 -0700 Subject: [PATCH 1/2] Update error message string --- src/Tasks/Common/Resources/Strings.resx | 4 ++-- src/Tasks/Common/Resources/xlf/Strings.cs.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.de.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.es.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.fr.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.it.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.ja.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.ko.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.pl.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.ru.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.tr.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf | 6 ++++-- src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf | 6 ++++-- 14 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/Tasks/Common/Resources/Strings.resx b/src/Tasks/Common/Resources/Strings.resx index 3fbb2006b006..7907b0fb3d8d 100644 --- a/src/Tasks/Common/Resources/Strings.resx +++ b/src/Tasks/Common/Resources/Strings.resx @@ -691,7 +691,8 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1146: "} - NETSDK1147: The following workload packs were not installed: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} @@ -806,5 +807,4 @@ The following are names of parameters or literal values and should not be transl NETSDK1173: The provided type library '{0}' is in an invalid format. {StrBegin="NETSDK1173: "} - \ No newline at end of file diff --git a/src/Tasks/Common/Resources/xlf/Strings.cs.xlf b/src/Tasks/Common/Resources/xlf/Strings.cs.xlf index 62b13568561c..338c97c5aaba 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.cs.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.cs.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: Nebyly nainstalovány následující sady úloh: {0}. + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.de.xlf b/src/Tasks/Common/Resources/xlf/Strings.de.xlf index 591ddfbc291c..036b72c6c015 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.de.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.de.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: Die folgenden Workloadpakete wurden nicht installiert: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.es.xlf b/src/Tasks/Common/Resources/xlf/Strings.es.xlf index a40cc9415660..f84a7243e7b7 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.es.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.es.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: The following workload packs were not installed: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.fr.xlf b/src/Tasks/Common/Resources/xlf/Strings.fr.xlf index 8adc73123d9b..65a996ad6239 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.fr.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.fr.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: les packs de charges de travail suivants n'ont pas été installés : {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.it.xlf b/src/Tasks/Common/Resources/xlf/Strings.it.xlf index c72912cb19f7..e5330925687b 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.it.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.it.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: i pacchetti del carico di lavoro seguenti non sono stati installati: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.ja.xlf b/src/Tasks/Common/Resources/xlf/Strings.ja.xlf index 24e718cb6162..b050b9dfb825 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.ja.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.ja.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: 次のワークロード パックはインストールされませんでした: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.ko.xlf b/src/Tasks/Common/Resources/xlf/Strings.ko.xlf index a552b01c5e4f..5b78b6dc8402 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.ko.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.ko.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: 다음 워크로드 팩이 설치되지 않았습니다. {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.pl.xlf b/src/Tasks/Common/Resources/xlf/Strings.pl.xlf index 342a0780b031..129b02985c91 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.pl.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.pl.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: Następujące pakiety obciążeń nie zostały zainstalowane: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf b/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf index d6a8f7938266..5b09ff55a82e 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: os seguintes pacotes de carga de trabalho não foram instalados: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.ru.xlf b/src/Tasks/Common/Resources/xlf/Strings.ru.xlf index a8382649492b..1f3fb7e3fd99 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.ru.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.ru.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: следующие пакеты рабочих нагрузок не были установлены: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.tr.xlf b/src/Tasks/Common/Resources/xlf/Strings.tr.xlf index c9f111eac163..eb6f20d79a77 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.tr.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.tr.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: Şu iş yükü paketleri yüklenmedi: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf index 4883bb7fb83e..14a9df7e6bef 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: 未安装以下工作负载包: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} diff --git a/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf index 97b02f5d08c6..091dff26882b 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -876,8 +876,10 @@ The following are names of parameters or literal values and should not be transl {StrBegin="NETSDK1148: "} - NETSDK1147: The following workload packs were not installed: {0} - NETSDK1147: 未安裝下列工作負載套件: {0} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} + NETSDK1147: To build this project, the following workloads must be installed: {0} +To install these workloads, run the following command: {1} {StrBegin="NETSDK1147: "} From 1a9a8cc9847d7ff67b3386ec89a5f26c4993036e Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Sun, 16 May 2021 08:44:03 -0700 Subject: [PATCH 2/2] Generate suggestions for workloads to install --- .../Microsoft.NET.Build.Tasks.csproj | 4 ++ .../ShowMissingWorkloads.cs | 41 ++++++++++-- .../Microsoft.NET.Sdk.ImportWorkloads.targets | 16 ++++- .../WorkloadTests.cs | 65 +++++++++++++++++-- 4 files changed, 115 insertions(+), 11 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj b/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj index af47e3c223b5..e7ff4814657f 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj +++ b/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj @@ -13,6 +13,7 @@ The MSBuild targets and properties for building .NET Core projects. Library $(SdkTargetFramework);net472 + annotations @@ -72,10 +73,13 @@ + + + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs index f55a2b922d02..9e1522d83986 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ShowMissingWorkloads.cs @@ -9,6 +9,8 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.NET.Sdk.WorkloadManifestReader; namespace Microsoft.NET.Build.Tasks { @@ -16,17 +18,46 @@ public class ShowMissingWorkloads : TaskBase { public ITaskItem[] MissingWorkloadPacks { get; set; } + public string NetCoreRoot { get; set; } + + public string NETCoreSdkVersion { get; set; } + + public bool GenerateErrorsForMissingWorkloads { get; set; } + + [Output] + public ITaskItem[] SuggestedWorkloads { get; set; } + protected override void ExecuteCore() { if (MissingWorkloadPacks.Any()) { - // TODO: Once IWorkloadResolver.GetWorkloadSuggestionForMissingPacks is implemented, switch to using that to report recommended workloads to install, - // instead of reporting which workload packs are missing - var errorMessage = string.Format(CultureInfo.CurrentCulture, - Strings.WorkloadNotInstalled, string.Join(" ", MissingWorkloadPacks.Select(p => p.ItemSpec))); + var workloadManifestProvider = new SdkDirectoryWorkloadManifestProvider(NetCoreRoot, NETCoreSdkVersion); + var workloadResolver = WorkloadResolver.Create(workloadManifestProvider, NetCoreRoot, NETCoreSdkVersion); + + var suggestedWorkloads = workloadResolver.GetWorkloadSuggestionForMissingPacks(MissingWorkloadPacks.Select(item => item.ItemSpec).ToList()); + + if (GenerateErrorsForMissingWorkloads) + { + var suggestedInstallCommand = "dotnet workload install " + string.Join(" ", suggestedWorkloads.Select(w => w.Id)); - Log.LogError(errorMessage); + var errorMessage = string.Format(CultureInfo.CurrentCulture, + Strings.WorkloadNotInstalled, string.Join(" ", suggestedWorkloads.Select(w => w.Id)), suggestedInstallCommand); + + Log.LogError(errorMessage); + } + + SuggestedWorkloads = suggestedWorkloads.Select(suggestedWorkload => + { + var taskItem = new TaskItem(suggestedWorkload.Id); + taskItem.SetMetadata("VisualStudioComponentId", ToSafeId(suggestedWorkload.Id)); + return taskItem; + }).ToArray(); } } + + internal static string ToSafeId(string id) + { + return id.Replace("-", ".").Replace(" ", ".").Replace("_", "."); + } } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.ImportWorkloads.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.ImportWorkloads.targets index d2c08d2a8f06..a4757ad5b12d 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.ImportWorkloads.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.ImportWorkloads.targets @@ -17,10 +17,22 @@ Copyright (c) .NET Foundation. All rights reserved. + + + + + + - - + + diff --git a/src/Tests/Microsoft.NET.Build.Tests/WorkloadTests.cs b/src/Tests/Microsoft.NET.Build.Tests/WorkloadTests.cs index 4f3942f9690a..dd5277364013 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/WorkloadTests.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/WorkloadTests.cs @@ -64,27 +64,84 @@ public void It_should_fail_without_workload() } [Fact] - public void It_should_fail_without_workload_when_multitargeted() + public void It_should_create_suggested_workload_items() { var testProject = new TestProject() { Name = "WorkloadTest", - TargetFrameworks = "net5.0;net5.0-missingworkloadtestplatform" + TargetFrameworks = "net5.0-missingworkloadtestplatform" }; var testAsset = _testAssetsManager .CreateTestProject(testProject); - new BuildCommand(testAsset) + var getValuesCommand = new GetValuesCommand(testAsset, "SuggestedWorkload", GetValuesCommand.ValueType.Item); + getValuesCommand.DependsOnTargets = "GetSuggestedWorkloads"; + getValuesCommand.MetadataNames.Add("VisualStudioComponentId"); + getValuesCommand.ShouldRestore = false; + + getValuesCommand.Execute() + .Should() + .Pass(); + + getValuesCommand.GetValuesWithMetadata().Select(valueAndMetadata => (valueAndMetadata.value, valueAndMetadata.metadata["VisualStudioComponentId"])) + .Should() + .BeEquivalentTo(("microsoft-net-sdk-missingtestworkload", "microsoft.net.sdk.missingtestworkload")); + } + + [Fact] + public void It_should_fail_to_restore_without_workload_when_multitargeted() + { + var testProject = new TestProject() + { + Name = "WorkloadTest", + TargetFrameworks = "net5.0-android;net5.0-ios" + }; + + var testAsset = _testAssetsManager + .CreateTestProject(testProject); + + new RestoreCommand(testAsset) .Execute() .Should() .Fail() .And .HaveStdOutContaining("NETSDK1147"); + + // Until https://github.com/NuGet/Home/issues/10872 is fixed, only one of the errors will be reported when restoring + // Once that is fixed we should add the following checks: + // .And + // .HaveStdOutContaining("ios") + // .And + // .HaveStdOutContaining("android"); + } + + [Fact] + public void It_should_fail_to_build_without_workload_when_multitargeted() + { + var testProject = new TestProject() + { + Name = "WorkloadTest", + TargetFrameworks = "net5.0-android;net5.0-ios" + }; + + var testAsset = _testAssetsManager + .CreateTestProject(testProject); + + new BuildCommand(testAsset) + .ExecuteWithoutRestore() + .Should() + .Fail() + .And + .HaveStdOutContaining("NETSDK1147") + .And + .HaveStdOutContaining("ios") + .And + .HaveStdOutContaining("android"); } [Fact] - public void It_should_fail_when_multitargeted_to_unknown_platforms() + public void It_should_fail_to_build_when_multitargeted_to_unknown_platforms() { var testProject = new TestProject() {