diff --git a/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs b/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs index 0dc61ea54241..ba9e244e77b2 100644 --- a/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs +++ b/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs @@ -224,7 +224,7 @@ public InstallResponseMessage SendGetGlobalJsonWorkloadSetVersionsRequest(SdkFea { return Send(new InstallRequestMessage { - RequestType = InstallRequestType.RecordWorkloadSetInGlobalJson, + RequestType = InstallRequestType.GetGlobalJsonWorkloadSetVersions, SdkFeatureBand = sdkFeatureBand.ToString(), }); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs index db433c14981b..429aa7efd1e6 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs @@ -45,7 +45,10 @@ internal static string GetWorkloadsVersion(WorkloadInfoHelper workloadInfoHelper { workloadInfoHelper ??= new WorkloadInfoHelper(false); - return workloadInfoHelper.ManifestProvider.GetWorkloadVersion(); + var versionInfo = workloadInfoHelper.ManifestProvider.GetWorkloadVersion(); + + // The explicit space here is intentional, as it's easy to miss in localization and crucial for parsing + return versionInfo.Version + (versionInfo.VersionNotInstalledMessage is not null ? ' ' + Workloads.Workload.List.LocalizableStrings.WorkloadVersionNotInstalledShort : string.Empty); } internal static void ShowWorkloadsInfo(ParseResult parseResult = null, WorkloadInfoHelper workloadInfoHelper = null, IReporter reporter = null, string dotnetDir = null, bool showVersion = true) @@ -56,46 +59,68 @@ internal static void ShowWorkloadsInfo(ParseResult parseResult = null, WorkloadI reporter ??= Utils.Reporter.Output; string dotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); + + + var versionInfo = workloadInfoHelper.ManifestProvider.GetWorkloadVersion(); + + void WriteUpdateModeAndAnyError(string indent = "") + { + var useWorkloadSets = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(workloadInfoHelper._currentSdkFeatureBand, workloadInfoHelper.UserLocalPath), "default.json")).UseWorkloadSets; + var workloadSetsString = useWorkloadSets == true ? "workload sets" : "loose manifests"; + reporter.WriteLine(indent + string.Format(CommonStrings.WorkloadManifestInstallationConfiguration, workloadSetsString)); + + var additionalMessage = versionInfo.VersionNotInstalledMessage ?? versionInfo.UpdateModeMessage; + if (additionalMessage != null) + { + reporter.WriteLine(indent + additionalMessage); + } + } + if (showVersion) { - reporter.WriteLine($" Workload version: {workloadInfoHelper.ManifestProvider.GetWorkloadVersion()}"); + reporter.WriteLine($" Workload version: {GetWorkloadsVersion()}"); + + WriteUpdateModeAndAnyError(indent: " "); + reporter.WriteLine(); } - var useWorkloadSets = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(workloadInfoHelper._currentSdkFeatureBand, workloadInfoHelper.UserLocalPath), "default.json")).UseWorkloadSets; - var workloadSetsString = useWorkloadSets == true ? "workload sets" : "loose manifests"; - reporter.WriteLine(string.Format(CommonStrings.WorkloadManifestInstallationConfiguration, workloadSetsString)); - if (installedWorkloads.Count == 0) { reporter.WriteLine(CommonStrings.NoWorkloadsInstalledInfoWarning); - return; } + else + { + var manifestInfoDict = workloadInfoHelper.WorkloadResolver.GetInstalledManifests().ToDictionary(info => info.Id, StringComparer.OrdinalIgnoreCase); - var manifestInfoDict = workloadInfoHelper.WorkloadResolver.GetInstalledManifests().ToDictionary(info => info.Id, StringComparer.OrdinalIgnoreCase); + foreach (var workload in installedWorkloads.AsEnumerable()) + { + var workloadManifest = workloadInfoHelper.WorkloadResolver.GetManifestFromWorkload(new WorkloadId(workload.Key)); + var workloadFeatureBand = manifestInfoDict[workloadManifest.Id].ManifestFeatureBand; - foreach (var workload in installedWorkloads.AsEnumerable()) - { - var workloadManifest = workloadInfoHelper.WorkloadResolver.GetManifestFromWorkload(new WorkloadId(workload.Key)); - var workloadFeatureBand = manifestInfoDict[workloadManifest.Id].ManifestFeatureBand; + const int align = 10; + const string separator = " "; - const int align = 10; - const string separator = " "; + reporter.WriteLine($" [{workload.Key}]"); - reporter.WriteLine($" [{workload.Key}]"); + reporter.Write($"{separator}{CommonStrings.WorkloadSourceColumn}:"); + reporter.WriteLine($" {workload.Value,align}"); - reporter.Write($"{separator}{CommonStrings.WorkloadSourceColumn}:"); - reporter.WriteLine($" {workload.Value,align}"); + reporter.Write($"{separator}{CommonStrings.WorkloadManifestVersionColumn}:"); + reporter.WriteLine($" {workloadManifest.Version + '/' + workloadFeatureBand,align}"); - reporter.Write($"{separator}{CommonStrings.WorkloadManifestVersionColumn}:"); - reporter.WriteLine($" {workloadManifest.Version + '/' + workloadFeatureBand,align}"); + reporter.Write($"{separator}{CommonStrings.WorkloadManifestPathColumn}:"); + reporter.WriteLine($" {workloadManifest.ManifestPath,align}"); - reporter.Write($"{separator}{CommonStrings.WorkloadManifestPathColumn}:"); - reporter.WriteLine($" {workloadManifest.ManifestPath,align}"); + reporter.Write($"{separator}{CommonStrings.WorkloadInstallTypeColumn}:"); + reporter.WriteLine($" {WorkloadInstallType.GetWorkloadInstallType(new SdkFeatureBand(Utils.Product.Version), dotnetPath).ToString(),align}" + ); + reporter.WriteLine(""); + } + } - reporter.Write($"{separator}{CommonStrings.WorkloadInstallTypeColumn}:"); - reporter.WriteLine($" {WorkloadInstallType.GetWorkloadInstallType(new SdkFeatureBand(Utils.Product.Version), dotnetPath).ToString(),align}" - ); - reporter.WriteLine(""); + if (!showVersion) + { + WriteUpdateModeAndAnyError(); } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadHistoryRecorder.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadHistoryRecorder.cs index b4aa226ba370..270284bce9b4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadHistoryRecorder.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadHistoryRecorder.cs @@ -54,7 +54,7 @@ public void Run(Action workloadAction) private WorkloadHistoryState GetWorkloadState() { var resolver = _workloadResolverFunc(); - var currentWorkloadInfo = resolver.GetWorkloadVersion(); + var currentWorkloadVersion = resolver.GetWorkloadVersion().Version; return new WorkloadHistoryState() { ManifestVersions = resolver.GetInstalledManifests().ToDictionary(manifest => manifest.Id.ToString(), manifest => $"{manifest.Version}/{manifest.ManifestFeatureBand}"), @@ -62,9 +62,9 @@ private WorkloadHistoryState GetWorkloadState() .GetInstalledWorkloads(new SdkFeatureBand(_workloadResolver.GetSdkFeatureBand())) .Select(id => id.ToString()) .ToList(), - WorkloadSetVersion = resolver.GetWorkloadVersion() + WorkloadSetVersion = currentWorkloadVersion }; } } -} \ No newline at end of file +} diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index a80755c6af41..3f3e984d6eac 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -20,6 +20,7 @@ internal class WorkloadInstallCommand : InstallingWorkloadCommand { private bool _skipManifestUpdate; private readonly IReadOnlyCollection _workloadIds; + private readonly bool _shouldShutdownInstaller; public bool IsRunningRestore { get; set; } @@ -45,6 +46,7 @@ public WorkloadInstallCommand( WorkloadInstallerFactory.GetWorkloadInstaller(resolvedReporter, _sdkFeatureBand, _workloadResolver, Verbosity, _userProfileDir, VerifySignatures, PackageDownloader, _dotnetPath, TempDirectoryPath, _packageSourceLocation, RestoreActionConfiguration, elevationRequired: !_printDownloadLinkOnly && string.IsNullOrWhiteSpace(_downloadToCacheOption)); + _shouldShutdownInstaller = _workloadInstallerFromConstructor != null; _workloadManifestUpdater = _workloadManifestUpdaterFromConstructor ?? new WorkloadManifestUpdater(resolvedReporter, _workloadResolver, PackageDownloader, _userProfileDir, _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, displayManifestUpdates: Verbosity.IsDetailedOrDiagnostic()); @@ -120,7 +122,9 @@ public override int Execute() throw new GracefulException(string.Format(LocalizableStrings.CannotCombineSkipManifestAndVersion, WorkloadInstallCommandParser.SkipManifestUpdateOption.Name, InstallingWorkloadCommandParser.VersionOption.Name), isUserError: true); } - else if (_skipManifestUpdate && SpecifiedWorkloadSetVersionInGlobalJson) + else if ((_skipManifestUpdate && SpecifiedWorkloadSetVersionInGlobalJson) && + !IsRunningRestore) // When running restore, we first update workloads, then query the projects to figure out what workloads should be installed, then run the install command. + // When we run the install command we set skipManifestUpdate to true as an optimization to avoid trying to update twice { throw new GracefulException(string.Format(LocalizableStrings.CannotUseSkipManifestWithGlobalJsonWorkloadVersion, WorkloadInstallCommandParser.SkipManifestUpdateOption.Name, _globalJsonPath), isUserError: true); @@ -146,14 +150,21 @@ public override int Execute() } catch (Exception e) { - _workloadInstaller.Shutdown(); + if (_shouldShutdownInstaller) + { + _workloadInstaller.Shutdown(); + } // Don't show entire stack trace throw new GracefulException(string.Format(LocalizableStrings.WorkloadInstallationFailed, e.Message), e, isUserError: false); } } - _workloadInstaller.Shutdown(); + if (_shouldShutdownInstaller) + { + _workloadInstaller.Shutdown(); + } + return _workloadInstaller.ExitCode; } diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx index 4ba629fee8d5..e82e8b1e6a75 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx @@ -134,6 +134,9 @@ Found workload version {0} pinned in the global.json file at {1}. + + (not installed) + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs index 40a32b23c7be..1b393bc654ee 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs @@ -93,7 +93,7 @@ public override int Execute() } else { - Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion() ?? "unknown")); + Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion().Version ?? "unknown")); } Reporter.WriteLine(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf index 722830ef8eb3..2a900b4f2dc2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf @@ -32,6 +32,11 @@ Aktualizace jsou k dispozici pro následující úlohy: {0}. Pokud chcete získat nejnovější verzi, spusťte aktualizaci úlohy dotnet (`dotnet workload update`). {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf index cc37a79c6050..6d8a6ad9375a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf @@ -32,6 +32,11 @@ Updates sind für die folgenden Workloads verfügbar: {0}. Führen Sie „dotnet workload update“ aus, um die neueste Updates zu erhalten. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf index 0144e50a38cb..6fccba23b95c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf @@ -32,6 +32,11 @@ Hay actualizaciones disponibles para las siguientes cargas de trabajo: {0}. Ejecute "dotnet workload update" para obtener la versión más reciente. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf index 651a34096ff9..fe1b3f8895a5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf @@ -32,6 +32,11 @@ Des mises à jour sont disponibles pour les charges de travail suivantes : {0}. Exécutez `dotnet workload update` pour obtenir la dernière version. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf index 40e37f31dbe1..0a3bb9ad6c81 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf @@ -32,6 +32,11 @@ Gli aggiornamenti sono disponibili per i carichi di lavoro seguenti: {0}. Per ottenere la versione più recente, eseguire 'dotnet workload update'. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf index 906a1e304014..b0a53e52f449 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf @@ -32,6 +32,11 @@ 次のワークロードについて更新プログラムを入手可能です: {0}。最新版を取得するには、`dotnet workload update` を実行します。 {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf index e3a03464b07a..41b8060ef14e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf @@ -32,6 +32,11 @@ 다음 워크로드에 대한 업데이트를 사용할 수 있습니다. {0}. 최신 버전을 받으려면 `dotnet workload update`를 실행하세요. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf index c925df5fcd75..125782bec3e1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf @@ -32,6 +32,11 @@ Aktualizacje są dostępne dla następujących obciążeń: {0}. Uruchom polecenie `dotnet workload update`, aby uzyskać najnowszą wersję. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf index d815267266d6..29bffc61132f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf @@ -32,6 +32,11 @@ As atualizações estão disponíveis para as seguintes cargas de trabalho(s): {0}. Execute `dotnet workload update` para obter o mais recente. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf index 55c0c4924564..8f2c10c716f0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf @@ -32,6 +32,11 @@ Обновления доступны для следующих рабочих нагрузок: {0}. Чтобы получить последнюю версию, запустите `dotnet workload update`. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf index e2fd1f6d4bbb..b60e77b79c1a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf @@ -32,6 +32,11 @@ Şu iş yükleri için güncelleştirmeler var: {0}. En son sürümü almak için `dotnet workload update` çalıştırın. {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf index 110a836e90c0..5cffb456a7de 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf @@ -32,6 +32,11 @@ 以下工作负载有可用的更新: {0}。请运行 `dotnet workload update` 以获取最新版本。 {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf index c3838d6dd072..2d36f2b1639f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf @@ -32,6 +32,11 @@ 以下工作負載有可用的更新: {0}。執行 `dotnet workload update` 以取得最新更新。 {Locked="dotnet workload update"} + + (not installed) + (not installed) + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs index d02a72c2d6d6..94c40d95dc4c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs @@ -51,7 +51,7 @@ public override int Execute() recorder.Run(() => { // First update manifests and install a workload set as necessary - new WorkloadUpdateCommand(_result, recorder: recorder).Execute(); + new WorkloadUpdateCommand(_result, recorder: recorder, isRestoring: true).Execute(); var allProjects = DiscoverAllProjects(Directory.GetCurrentDirectory(), _slnOrProjectArgument).Distinct(); List allWorkloadId = RunTargetToGetWorkloadIds(allProjects); @@ -64,6 +64,8 @@ public override int Execute() IsRunningRestore = true }.Execute(); }); + + workloadInstaller.Shutdown(); return 0; } diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index a403f5266329..4ecc1e10993f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -23,6 +23,7 @@ internal class WorkloadUpdateCommand : InstallingWorkloadCommand private readonly bool _fromPreviousSdk; private WorkloadHistoryRecorder _recorder; private readonly bool _isRestoring; + private readonly bool _shouldShutdownInstaller; public WorkloadUpdateCommand( ParseResult parseResult, IReporter reporter = null, @@ -49,6 +50,9 @@ public WorkloadUpdateCommand( _dotnetPath, TempDirectoryPath, packageSourceLocation: _packageSourceLocation, RestoreActionConfiguration, elevationRequired: !_printDownloadLinkOnly && !_printRollbackDefinitionOnly && string.IsNullOrWhiteSpace(_downloadToCacheOption)); + _shouldShutdownInstaller = _workloadInstallerFromConstructor != null; + + _workloadManifestUpdater = _workloadManifestUpdaterFromConstructor ?? new WorkloadManifestUpdater(resolvedReporter, _workloadResolver, PackageDownloader, _userProfileDir, _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, sdkFeatureBand: _sdkFeatureBand); _recorder = recorder; @@ -132,7 +136,10 @@ public override int Execute() } } - _workloadInstaller.Shutdown(); + if (_shouldShutdownInstaller) + { + _workloadInstaller.Shutdown(); + } return _workloadInstaller.ExitCode; } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index f6a5e9676624..b6822dc57d86 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -14,8 +14,10 @@ public interface IWorkloadManifestProvider string GetSdkFeatureBand(); - string? GetWorkloadVersion(); + WorkloadVersionInfo GetWorkloadVersion(); Dictionary GetAvailableWorkloadSets(); + + public readonly record struct WorkloadVersionInfo(string Version, string? VersionNotInstalledMessage = null, string? UpdateModeMessage = null); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs index 054aa1201798..9caf5257f4a9 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs @@ -20,7 +20,7 @@ public interface IWorkloadResolver string GetManifestFeatureBand(string manifestId); IEnumerable GetInstalledManifests(); string GetSdkFeatureBand(); - string? GetWorkloadVersion(); + IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion(); IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads); WorkloadManifest GetManifestFromWorkload(WorkloadId workloadId); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 4acd8945ff9a..d05a243cab5b 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -6,6 +6,7 @@ using Microsoft.DotNet.Cli; using Microsoft.DotNet.Workloads.Workload; using Microsoft.NET.Sdk.Localization; +using static Microsoft.NET.Sdk.WorkloadManifestReader.IWorkloadManifestProvider; namespace Microsoft.NET.Sdk.WorkloadManifestReader { @@ -243,20 +244,29 @@ void ThrowExceptionIfManifestsNotAvailable() } } - public string? GetWorkloadVersion() + public WorkloadVersionInfo GetWorkloadVersion() { if (_globalJsonWorkloadSetVersion != null) { - return _globalJsonWorkloadSetVersion; + // _exceptionToThrow is set to null here if and only if the workload set is not installed. + // If this came from --info or workload --version, the error won't be thrown, but we should still + // suggest running `dotnet workload restore` to the user. + return new WorkloadVersionInfo(_globalJsonWorkloadSetVersion, _exceptionToThrow?.Message); } ThrowExceptionIfManifestsNotAvailable(); if (_workloadSet?.Version is not null) { - return _workloadSet?.Version!; + return new WorkloadVersionInfo(_workloadSet.Version); } + var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkVersionBand, _sdkOrUserLocalPath), "default.json"); + var installState = InstallStateContents.FromPath(installStateFilePath)!; + string? shouldRestoreMessage = installState.UseWorkloadSets == true ? + Strings.ShouldInstallAWorkloadSet : + null; + using (SHA256 sha256Hash = SHA256.Create()) { byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(string.Join(";", @@ -271,7 +281,7 @@ void ThrowExceptionIfManifestsNotAvailable() sb.Append(bytes[b].ToString("x2")); } - return $"{_sdkVersionBand.ToStringWithoutPrerelease()}-manifests.{sb}"; + return new WorkloadVersionInfo($"{_sdkVersionBand.ToStringWithoutPrerelease()}-manifests.{sb}", null, UpdateModeMessage: shouldRestoreMessage); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx index cf418daa75cb..1f4d01f08f1b 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Strings.resx @@ -201,6 +201,9 @@ Workload version {0}, which was specified in {1}, was not found. Run "dotnet workload restore" to install this workload version. {Locked="dotnet workload restore"} + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workload version {0} was not found. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index 79d1351d9f90..8aee9c940b02 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -53,7 +53,7 @@ public IEnumerable GetManifestDirectories() } public string GetSdkFeatureBand() => _sdkVersionBand; - public string? GetWorkloadVersion() => _sdkVersionBand.ToString() + ".2"; + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => new IWorkloadManifestProvider.WorkloadVersionInfo(_sdkVersionBand.ToString() + ".2"); public Dictionary GetAvailableWorkloadSets() => new(); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index 3d9eba645554..8c8828a04070 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -115,7 +115,7 @@ public void RefreshWorkloadManifests() InitializeManifests(); } - public string? GetWorkloadVersion() => _manifestProvider.GetWorkloadVersion(); + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => _manifestProvider.GetWorkloadVersion(); private void LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider) { @@ -778,7 +778,7 @@ public void RefreshWorkloadManifests() { } public Dictionary GetAvailableWorkloadSets() => new(); public IEnumerable GetManifests() => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; - public string? GetWorkloadVersion() => _sdkFeatureBand.ToString() + ".2"; + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => new IWorkloadManifestProvider.WorkloadVersionInfo(_sdkFeatureBand + ".2"); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf index 1891cc4ff30b..7b21fe4a0b17 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.cs.xlf @@ -117,6 +117,11 @@ Přesměrování úlohy {0} má jiné klíče než redirect-to. + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Neočekávaný token {0} u posunu {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf index aa35c3838c22..79f35f0b27e1 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.de.xlf @@ -117,6 +117,11 @@ Die Umleitungsworkload „{0}“ hat andere Schlüssel als „redirect-to“. + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Unerwartetes Token "{0}" bei Offset {1}. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf index 485e6e0a0cf8..58541aa6f25d 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.es.xlf @@ -117,6 +117,11 @@ La carga de trabajo de redireccionamiento '{0}' tiene claves distintas que las de 'redirect-to' + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Token "{0}" inesperado en el desplazamiento {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf index 0ae7f6800bd3..ec48007fbc8d 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.fr.xlf @@ -117,6 +117,11 @@ La charge de travail de redirection « {0} » a des clés autres que « redirection vers ». + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Jeton '{0}' inattendu à l'offset {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf index 7c666799e412..4c9164f7fd5c 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.it.xlf @@ -117,6 +117,11 @@ Il carico di lavoro '{0}' di reindirizzamento ha chiavi diverse da ' Redirect-to ' + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Token '{0}' imprevisto alla posizione di offset {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf index cc172807eaa9..6cf7ba208f34 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ja.xlf @@ -117,6 +117,11 @@ リダイレクト ワークロード '{0}' に 'redirect-to' 以外のキーがあります + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} オフセット {1} に予期しないトークン '{0}' があります diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf index 385531b1c48b..86a2f76a3b1b 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ko.xlf @@ -117,6 +117,11 @@ 리디렉션 워크로드 '{0}'에 'redirect-to' 이외의 다른 키가 있습니다 + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} 오프셋 {1}에 예기치 않은 토큰 '{0}'이(가) 있습니다. diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf index 2f5dc549ddf0..c419d8fe7264 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pl.xlf @@ -117,6 +117,11 @@ Obciążenie przekierowania „{0}” ma klucze inne niż „redirect-to” + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Nieoczekiwany token „{0}” pod przesunięciem {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf index f5f0331a25ec..ceea3b2edb17 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.pt-BR.xlf @@ -117,6 +117,11 @@ A carga de trabalho de redirecionamento '{0}' tem chaves diferentes além de 'redirecionar-para' + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Token inesperado '{0}' no deslocamento {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf index bf88a6af7bbe..bd09fe8168f6 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.ru.xlf @@ -117,6 +117,11 @@ Перенаправление рабочей нагрузки "{0}" содержит ключи, отличные от "redirect-to" + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} Непредвиденный токен "{0}" в смещении {1} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf index 786f001a3435..c343ea496921 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.tr.xlf @@ -117,6 +117,11 @@ '{0}' yeniden yönlendirme iş yükünde 'redirect-to' dışında anahtarlar var + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} {1} uzaklığında beklenmeyen '{0}' belirteci diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf index 911a2731d284..a31e3270aa9f 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hans.xlf @@ -117,6 +117,11 @@ 重定向工作负荷“{0}”具有“重定向到”以外的键 + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} 偏移为 {1} 时意外出现的标记“{0}” diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf index 423e6216ecca..285d72e53369 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/xlf/Strings.zh-Hant.xlf @@ -117,6 +117,11 @@ 重新導向工作負載 '{0}' 具有 'redirect-to' 以外的其他金鑰 + + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + Workloads are configured to install and update using workload versions, but none were found. Run "dotnet workload restore" to install a workload version. + + Unexpected token '{0}' at offset {1} 位移 {1} 有未預期的權杖 '{0}' diff --git a/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index 354aeb7ad8ee..09dad2d93f12 100644 --- a/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -40,7 +40,7 @@ public IEnumerable GetManifests() public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); - public string? GetWorkloadVersion() => "8.0.100.2"; + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => new IWorkloadManifestProvider.WorkloadVersionInfo("8.0.100.2"); } internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumerable<(string id, string content)> @@ -67,6 +67,6 @@ public IEnumerable GetManifests() IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); - public string? GetWorkloadVersion() => "8.0.100.2"; + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => new IWorkloadManifestProvider.WorkloadVersionInfo("8.0.100.2"); } } diff --git a/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index e7676a0a78ea..f13ed7df1334 100644 --- a/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/test/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -93,14 +93,14 @@ var sdkDirectoryWorkloadManifestProvider if (useWorkloadSet) { - sdkDirectoryWorkloadManifestProvider.GetWorkloadVersion().Should().Be("8.0.200"); + sdkDirectoryWorkloadManifestProvider.GetWorkloadVersion().Version.Should().Be("8.0.200"); } else { string[] manifests = sdkDirectoryWorkloadManifestProvider.GetManifests().OrderBy(m => m.ManifestId).Select(m => $"{m.ManifestId}.{m.ManifestFeatureBand}.{m.ManifestVersion}").ToArray(); manifests.Length.Should().Be(1); manifests.Should().Contain("android.8.0.200.33.0.2-rc.1"); - sdkDirectoryWorkloadManifestProvider.GetWorkloadVersion().Should().Be("8.0.200-manifests.4ba11739"); + sdkDirectoryWorkloadManifestProvider.GetWorkloadVersion().Version.Should().Be("8.0.200-manifests.4ba11739"); } Directory.Delete(Path.Combine(_manifestRoot, "8.0.100"), recursive: true); diff --git a/test/dotnet-MsiInstallation.Tests/Framework/TestExtensions.cs b/test/dotnet-MsiInstallation.Tests/Framework/TestExtensions.cs new file mode 100644 index 000000000000..d9acc9a5e945 --- /dev/null +++ b/test/dotnet-MsiInstallation.Tests/Framework/TestExtensions.cs @@ -0,0 +1,21 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.MsiInstallerTests.Framework +{ + public static class TestExtensions + { + public static AndConstraint PassWithoutWarning(this CommandResultAssertions assertions) + { + return assertions.Pass() + .And.NotHaveStdOutContaining("Warning: ") + .And.NotHaveStdErrContaining("Warning: "); + } + } +} diff --git a/test/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/test/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 213e5deb43db..ccc89980d6cb 100644 --- a/test/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/test/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -54,7 +54,7 @@ private CommandResult ApplyManifests(string manifestContents, string rollbackID) VM.WriteFile($@"c:\SdkTesting\rollback-{rollbackID}.json", manifestContents), VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", $@"c:\SdkTesting\rollback-{rollbackID}.json", "--skip-sign-check")) .Execute(); - result.Should().Pass(); + result.Should().PassWithoutWarning(); return result; } @@ -213,10 +213,10 @@ public void InstallWithRollback() InstallSdk(); VM.WriteFile($@"c:\SdkTesting\rollback-rc1.json", RollbackRC1) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--from-rollback-file", $@"c:\SdkTesting\rollback-rc1.json") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); TestWasmWorkload(); } @@ -242,7 +242,7 @@ public void UpdateShouldUndoPinnedRollback() VM.CreateRunCommand("dotnet", "workload", "update") .Execute() - .Should().Pass(); + .Should().PassWithoutWarning(); GetWorkloadVersion().Should().NotBe(workloadVersion); @@ -269,7 +269,7 @@ public void TestAspire() //AddNuGetSource("https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-aspire-d215c528/nuget/v3/index.json"); //VM.CreateRunCommand("powershell", "-Command", "& { $(irm https://aka.ms/install-artifacts-credprovider.ps1) }") - // .Execute().Should().Pass(); + // .Execute().Should().PassWithoutWarning(); InstallWorkload("aspire", skipManifestUpdate: true); @@ -277,7 +277,7 @@ public void TestAspire() .WithWorkingDirectory(@"c:\SdkTesting") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); } @@ -289,13 +289,13 @@ void TestWasmWorkload() .WithWorkingDirectory(@"c:\SdkTesting") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); var result = VM.CreateRunCommand("dotnet", "publish", "/p:RunAotCompilation=true") .WithWorkingDirectory(@"c:\SdkTesting\BlazorWasm") .Execute(); - result.Should().Pass(); + result.Should().PassWithoutWarning(); // When publishing a blazorwasm project without the wasm-tools workload installed, the following message is displayed: // Publishing without optimizations. Although it's optional for Blazor, we strongly recommend using `wasm-tools` workload! You can install it by running `dotnet workload install wasm-tools` from the command line. @@ -364,7 +364,7 @@ string ListWorkloads() .WithIsReadOnly(true) .Execute(); - result.Should().Pass(); + result.Should().PassWithoutWarning(); return result.StdOut; } diff --git a/test/dotnet-MsiInstallation.Tests/VSWorkloadTests.cs b/test/dotnet-MsiInstallation.Tests/VSWorkloadTests.cs index 7d28064c8002..5aae507aef0a 100644 --- a/test/dotnet-MsiInstallation.Tests/VSWorkloadTests.cs +++ b/test/dotnet-MsiInstallation.Tests/VSWorkloadTests.cs @@ -25,7 +25,7 @@ public void WorkloadListShowsVSInstalledWorkloads() .WithIsReadOnly(true) .Execute(); - result.Should().Pass(); + result.Should().PassWithoutWarning(); result.Should().HaveStdOutContaining("aspire"); } @@ -39,12 +39,12 @@ public void UpdatesAreAdvertisedForVSInstalledWorkloads() .WithWorkingDirectory(@"C:\SdkTesting") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); // build (or any restoring) command should check for and notify of updates VM.CreateRunCommand("dotnet", "build") .WithWorkingDirectory(@"C:\SdkTesting\LibraryTest") - .Execute().Should().Pass() + .Execute().Should().PassWithoutWarning() .And.HaveStdOutContaining("Workload updates are available"); // Workload list should list the specific workloads that have updates @@ -52,7 +52,7 @@ public void UpdatesAreAdvertisedForVSInstalledWorkloads() .WithIsReadOnly(true) .Execute() .Should() - .Pass() + .PassWithoutWarning() .And .HaveStdOutContaining("Updates are available for the following workload(s): aspire"); } diff --git a/test/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs b/test/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs index 5fd7d9da7aa1..e7d79cede1d8 100644 --- a/test/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs +++ b/test/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs @@ -49,7 +49,7 @@ public void DoesNotUseWorkloadSetsByDefault() VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); var originalRollback = GetRollback(); @@ -58,7 +58,7 @@ public void DoesNotUseWorkloadSetsByDefault() VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); var newRollback = GetRollback(); @@ -75,7 +75,7 @@ void UpdateAndSwitchToWorkloadSetMode(out string updatedWorkloadVersion, out Wor VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); rollbackAfterUpdate = GetRollback(); updatedWorkloadVersion = GetWorkloadVersion(); @@ -88,10 +88,17 @@ void UpdateAndSwitchToWorkloadSetMode(out string updatedWorkloadVersion, out Wor .WithDescription("Switch mode to workload-set") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetWorkloadVersion().Should().Be(updatedWorkloadVersion); + var expectedMessage = "Workloads are configured to install and update using workload versions, but none were found. Run \"dotnet workload restore\" to install a workload version."; + + GetDotnetInfo().Should().Contain(expectedMessage) + .And.NotContain("(not installed)"); + GetDotnetWorkloadInfo().Should().Contain(expectedMessage) + .And.NotContain("(not installed)"); + GetUpdateMode().Should().Be("workload-set"); } @@ -105,7 +112,7 @@ public void UpdateWithWorkloadSets() AddNuGetSource(@"c:\SdkTesting\WorkloadSets"); VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion2); @@ -124,7 +131,7 @@ public void UpdateInWorkloadSetModeWithNoAvailableWorkloadSet() VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews", "--source", @"c:\SdkTesting\EmptySource") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); var newRollback = GetRollback(); @@ -157,13 +164,13 @@ private void UpdateToWorkloadSetVersion(string versionToInstall) VM.CreateRunCommand("dotnet", "workload", "update", "--version", versionToInstall, "--include-previews") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); VM.CreateRunCommand("dotnet", "workload", "search") .WithIsReadOnly(true) .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetWorkloadVersion().Should().Be(versionToInstall); @@ -175,7 +182,7 @@ private void UpdateToWorkloadSetVersion(string versionToInstall) VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion2); } @@ -200,7 +207,7 @@ public void UpdateToUnavailableWorkloadSetVersion() .WithIsReadOnly(true) .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetWorkloadVersion().Should().Be(workloadVersionBeforeUpdate); } @@ -224,7 +231,7 @@ public void UpdateWorkloadSetWithoutAvailableManifests() .WithIsReadOnly(true) .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetWorkloadVersion().Should().Be(workloadVersionBeforeUpdate); } @@ -245,7 +252,7 @@ public void UpdateToWorkloadSetVersionWithManifestsNotAvailable() .WithIsReadOnly(true) .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetWorkloadVersion().Should().Be(workloadVersionBeforeUpdate); } @@ -260,9 +267,13 @@ void SetupWorkloadSetInGlobalJson(out WorkloadSet originalRollback) originalRollback = GetRollback(SdkTestingDirectory); - VM.WriteFile("C:\\SdkTesting\\global.json", @$"{{""sdk"":{{""workloadVersion"":""{versionToUpdateTo}""}}}}").Execute().Should().Pass(); + VM.WriteFile("C:\\SdkTesting\\global.json", @$"{{""sdk"":{{""workloadVersion"":""{versionToUpdateTo}""}}}}").Execute().Should().PassWithoutWarning(); - GetWorkloadVersion(SdkTestingDirectory).Should().Be(versionToUpdateTo); + GetWorkloadVersion(SdkTestingDirectory).Should().Be(versionToUpdateTo + " (not installed)"); + GetDotnetInfo(SdkTestingDirectory).Should().Contain("Workload version: " + versionToUpdateTo + " (not installed)") + .And.Contain($@"Workload version {versionToUpdateTo}, which was specified in C:\SdkTesting\global.json, was not found"); + GetDotnetWorkloadInfo(SdkTestingDirectory).Should().Contain("Workload version: " + versionToUpdateTo + " (not installed)") + .And.Contain($@"Workload version {versionToUpdateTo}, which was specified in C:\SdkTesting\global.json, was not found"); // The version should have changed but not yet the manifests. Since we expect both, getting the rollback should fail. var result = VM.CreateRunCommand("dotnet", "workload", "update", "--print-rollback") @@ -285,13 +296,13 @@ public void RestoreWorkloadSetViaGlobalJson() var testProjectFolder = Path.Combine(SdkTestingDirectory, "ConsoleApp"); VM.CreateRunCommand("dotnet", "new", "console", "-o", "ConsoleApp") .WithWorkingDirectory(SdkTestingDirectory) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); SetupWorkloadSetInGlobalJson(out var originalRollback); VM.CreateRunCommand("dotnet", "workload", "restore") .WithWorkingDirectory(testProjectFolder) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion(SdkTestingDirectory).Should().Be(WorkloadSetVersion2); @@ -306,7 +317,7 @@ public void UseGlobalJsonToSpecifyWorkloadSet(string command) SetupWorkloadSetInGlobalJson(out var originalRollback); string[] args = command.Equals("install") ? ["dotnet", "workload", "install", "aspire"] : ["dotnet", "workload", command]; - VM.CreateRunCommand(args).WithWorkingDirectory(SdkTestingDirectory).Execute().Should().Pass(); + VM.CreateRunCommand(args).WithWorkingDirectory(SdkTestingDirectory).Execute().Should().PassWithoutWarning(); GetRollback(SdkTestingDirectory).Should().NotBe(originalRollback); } @@ -344,12 +355,12 @@ public void InstallWithVersionWhenPinned() originalVersion.Should().NotBe(WorkloadSetVersion1); VM.CreateRunCommand("dotnet", "workload", "update", "--version", WorkloadSetVersion1, "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion1); VM.CreateRunCommand("dotnet", "workload", "install", "aspire", "--version", WorkloadSetVersion2) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion2); } @@ -365,13 +376,13 @@ public void InstallWithGlobalJsonWhenPinned() originalVersion.Should().NotBe(WorkloadSetVersion1); VM.CreateRunCommand("dotnet", "workload", "update", "--version", WorkloadSetVersion1, "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion1); VM.CreateRunCommand("dotnet", "workload", "install", "aspire") .WithWorkingDirectory(SdkTestingDirectory) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion(SdkTestingDirectory).Should().Be(WorkloadSetVersion2); @@ -393,10 +404,10 @@ public void UpdateShouldNotPinWorkloadSet() VM.CreateActionGroup($"Disable {WorkloadSetVersion2}", VM.CreateRunCommand("cmd", "/c", "ren", @$"c:\SdkTesting\WorkloadSets\Microsoft.NET.Workloads.{sdkFeatureBand}.{packageVersion}.nupkg", $"Microsoft.NET.Workloads.{sdkFeatureBand}.{packageVersion}.bak"), VM.CreateRunCommand("cmd", "/c", "ren", @$"c:\SdkTesting\WorkloadSets\Microsoft.NET.Workloads.{sdkFeatureBand}.*.{packageVersion}.nupkg", $"Microsoft.NET.Workloads.{sdkFeatureBand}.*.{packageVersion}.bak")) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion1); @@ -404,7 +415,7 @@ public void UpdateShouldNotPinWorkloadSet() VM.CreateActionGroup($"Enable {WorkloadSetVersion2}", VM.CreateRunCommand("cmd", "/c", "ren", @$"c:\SdkTesting\WorkloadSets\Microsoft.NET.Workloads.{sdkFeatureBand}.{packageVersion}.bak", $"Microsoft.NET.Workloads.{sdkFeatureBand}.{packageVersion}.nupkg"), VM.CreateRunCommand("cmd", "/c", "ren", @$"c:\SdkTesting\WorkloadSets\Microsoft.NET.Workloads.{sdkFeatureBand}.*.{packageVersion}.bak", $"Microsoft.NET.Workloads.{sdkFeatureBand}.*.{packageVersion}.nupkg")) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); InstallWorkload("aspire", skipManifestUpdate: false); @@ -438,7 +449,7 @@ public void GarbageCollectWorkloadSets() // Update to latest workload set version VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); GetWorkloadVersion().Should().Be(WorkloadSetVersion2); @@ -451,22 +462,22 @@ public void GarbageCollectWorkloadSets() // Downgrade to earlier workload set version VM.CreateRunCommand("dotnet", "workload", "update", "--version", WorkloadSetVersion1) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); // Later workload set version should be GC'd VM.GetRemoteDirectory(workloadSet2Path).Should().NotExist(); // Now, pin older workload set version in global.json - VM.WriteFile("C:\\SdkTesting\\global.json", @$"{{""sdk"":{{""workloadVersion"":""{WorkloadSetVersion1}""}}}}").Execute().Should().Pass(); + VM.WriteFile("C:\\SdkTesting\\global.json", @$"{{""sdk"":{{""workloadVersion"":""{WorkloadSetVersion1}""}}}}").Execute().Should().PassWithoutWarning(); // Install pinned version VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") .WithWorkingDirectory(SdkTestingDirectory) - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); // Update globally installed version to later version VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); // Check workload versions in global context and global.json directory GetWorkloadVersion().Should().Be(WorkloadSetVersion2); @@ -477,11 +488,11 @@ public void GarbageCollectWorkloadSets() VM.GetRemoteDirectory(workloadSet1Path).Should().Exist(); // Now, remove pinned workload set from global.json - VM.WriteFile("C:\\SdkTesting\\global.json", "{}").Execute().Should().Pass(); + VM.WriteFile("C:\\SdkTesting\\global.json", "{}").Execute().Should().PassWithoutWarning(); // Run workload update to do a GC VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews") - .Execute().Should().Pass(); + .Execute().Should().PassWithoutWarning(); // Workload set 1 should have been GC'd VM.GetRemoteDirectory(workloadSet1Path).Should().NotExist(); @@ -513,7 +524,7 @@ public void WorkloadSearchVersion() var searchVersionResult = VM.CreateRunCommand("dotnet", "workload", "search", "version") .WithIsReadOnly(true) .Execute(); ; - searchVersionResult.Should().Pass(); + searchVersionResult.Should().PassWithoutWarning(); // Without source set up, there should be no workload sets found searchVersionResult.StdOut.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries) @@ -527,7 +538,7 @@ public void WorkloadSearchVersion() searchVersionResult = VM.CreateRunCommand("dotnet", "workload", "search", "version") .WithIsReadOnly(true) .Execute(); - searchVersionResult.Should().Pass(); + searchVersionResult.Should().PassWithoutWarning(); var actualVersions = searchVersionResult.StdOut.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); actualVersions.Should().Equal(WorkloadSetVersion2, WorkloadSetVersion1); @@ -537,7 +548,7 @@ public void WorkloadSearchVersion() .WithIsReadOnly(true) .Execute(); - searchVersionResult.Should().Pass(); + searchVersionResult.Should().PassWithoutWarning(); var searchResultJson = JsonNode.Parse(searchVersionResult.StdOut); var searchResultWorkloadSet = WorkloadSet.FromDictionaryForJson(JsonSerializer.Deserialize>(searchResultJson["manifestVersions"]), new SdkFeatureBand(SdkInstallerVersion)); @@ -546,7 +557,7 @@ public void WorkloadSearchVersion() VM.CreateRunCommand("dotnet", "workload", "update", "--include-previews", "--version", WorkloadSetVersion2) .Execute() .Should() - .Pass(); + .PassWithoutWarning(); GetRollback().ManifestVersions.Should().BeEquivalentTo(searchResultWorkloadSet.ManifestVersions); } @@ -558,17 +569,42 @@ string GetWorkloadVersion(string workingDirectory = null) .WithIsReadOnly(true) .Execute(); - result.Should().Pass(); + result.Should().PassWithoutWarning(); + + return result.StdOut; + } + + string GetDotnetInfo(string workingDirectory = null) + { + var result = VM.CreateRunCommand("dotnet", "--info") + .WithWorkingDirectory(workingDirectory) + .WithIsReadOnly(true) + .Execute(); + + result.Should().PassWithoutWarning(); return result.StdOut; } + + string GetDotnetWorkloadInfo(string workingDirectory = null) + { + var result = VM.CreateRunCommand("dotnet", "workload", "--info") + .WithWorkingDirectory(workingDirectory) + .WithIsReadOnly(true) + .Execute(); + + result.Should().PassWithoutWarning(); + + return result.StdOut; + } + string GetUpdateMode() { var result = VM.CreateRunCommand("dotnet", "workload", "config", "--update-mode") .WithIsReadOnly(true) .Execute(); - result.Should().Pass(); + result.Should().PassWithoutWarning(); return result.StdOut; } @@ -580,7 +616,7 @@ void AddNuGetSource(string source, string directory = null) .WithDescription($"Add {source} to NuGet.config") .Execute() .Should() - .Pass(); + .PassWithoutWarning(); } } } diff --git a/test/dotnet-workload-install.Tests/MockManifestProvider.cs b/test/dotnet-workload-install.Tests/MockManifestProvider.cs index 94cc85ae5f1d..2f0c86a1b01b 100644 --- a/test/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/test/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -48,6 +48,6 @@ public IEnumerable GetManifests() } public string GetSdkFeatureBand() => SdkFeatureBand.ToString(); - public string GetWorkloadVersion() => SdkFeatureBand.ToString() + ".2"; + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => new IWorkloadManifestProvider.WorkloadVersionInfo(SdkFeatureBand.ToString() + ".2"); } } diff --git a/test/dotnet-workload-search.Tests/MockWorkloadResolver.cs b/test/dotnet-workload-search.Tests/MockWorkloadResolver.cs index e7abd19ceff2..45120fe3d04a 100644 --- a/test/dotnet-workload-search.Tests/MockWorkloadResolver.cs +++ b/test/dotnet-workload-search.Tests/MockWorkloadResolver.cs @@ -39,7 +39,7 @@ public void RefreshWorkloadManifests() { /* noop */ } public IEnumerable GetInstalledManifests() => _installedManifests ?? throw new NotImplementedException(); public IWorkloadResolver CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); public string GetSdkFeatureBand() => "12.0.400"; - public string GetWorkloadVersion() => "12.0.400.2"; + public IWorkloadManifestProvider.WorkloadVersionInfo GetWorkloadVersion() => new IWorkloadManifestProvider.WorkloadVersionInfo("12.0.400.2"); public IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads) => throw new NotImplementedException(); WorkloadResolver IWorkloadResolver.CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); WorkloadManifest IWorkloadResolver.GetManifestFromWorkload(WorkloadId workloadId) => throw new NotImplementedException();