From 5a50c360cc692344ec95356cfb51def6cd1bccaf Mon Sep 17 00:00:00 2001 From: Gennadii Altukhov Date: Thu, 30 Jul 2020 23:42:13 +0200 Subject: [PATCH] issue #2428, issue #2405: add synchronization with Optional SDK Workload templates. Call the mock SDK API from the package Microsoft.Internal.DotNet.MockTemplateLocator. --- build.cmd | 2 +- .../HiveSynchronizationException.cs | 24 ++++++ .../LocalizableStrings.Designer.cs | 24 +++++- .../LocalizableStrings.resx | 6 ++ .../Microsoft.TemplateEngine.Cli.csproj | 1 + .../New3Command.cs | 73 +++++++++++++++++++ 6 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 src/Microsoft.TemplateEngine.Cli/HiveSynchronizationException.cs diff --git a/build.cmd b/build.cmd index e3291e911c3..197ba099fd0 100644 --- a/build.cmd +++ b/build.cmd @@ -1,3 +1,3 @@ @echo off powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0eng\common\Build.ps1""" -build -restore -pack -test %*" -exit /b %ErrorLevel% \ No newline at end of file +exit /b %ErrorLevel% diff --git a/src/Microsoft.TemplateEngine.Cli/HiveSynchronizationException.cs b/src/Microsoft.TemplateEngine.Cli/HiveSynchronizationException.cs new file mode 100644 index 00000000000..bbe6cc9e3bf --- /dev/null +++ b/src/Microsoft.TemplateEngine.Cli/HiveSynchronizationException.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Microsoft.TemplateEngine.Cli +{ + public sealed class HiveSynchronizationException : Exception + { + public HiveSynchronizationException(string message, string version) + : base(message) + { + SdkVersion = version; + } + + public HiveSynchronizationException(string message, string version, Exception innerException) + : base(message, innerException) + { + SdkVersion = version; + } + + public string SdkVersion { get; } + } +} diff --git a/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs b/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs index eadf53c54fc..fe7a0dcbb56 100644 --- a/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs +++ b/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 @@ -1043,7 +1043,27 @@ public static string NoTemplatesMatchName { return ResourceManager.GetString("NoTemplatesMatchName", resourceCulture); } } - + + /// + /// Looks up a localized string similar to The list of templates was synchronized with the Optional SDK Workloads. + /// + public static string OptionalWorkloadsSynchronized + { + get { + return ResourceManager.GetString("OptionalWorkloadsSynchronized", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error during synchronization with the Optional SDK Workloads. + /// + public static string OptionalWorkloadsSyncFailed + { + get { + return ResourceManager.GetString("OptionalWorkloadsSyncFailed", resourceCulture); + } + } + /// /// Looks up a localized string similar to No updates were found.. /// diff --git a/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx b/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx index ded19f23d93..a0002584c51 100644 --- a/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx +++ b/src/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx @@ -276,6 +276,12 @@ No templates matched the input template name: {0}. + + The list of templates was synchronized with the Optional SDK Workloads. + + + Error during synchronization with the Optional SDK Workloads. + No updates were found. diff --git a/src/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj b/src/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj index e5c58f1aeae..d4caa5e7427 100644 --- a/src/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj +++ b/src/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Microsoft.TemplateEngine.Cli/New3Command.cs b/src/Microsoft.TemplateEngine.Cli/New3Command.cs index 20e74d5b162..9d74c508e7e 100644 --- a/src/Microsoft.TemplateEngine.Cli/New3Command.cs +++ b/src/Microsoft.TemplateEngine.Cli/New3Command.cs @@ -8,6 +8,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using Microsoft.DotNet.TemplateLocator; using Microsoft.TemplateEngine.Abstractions; using Microsoft.TemplateEngine.Abstractions.Mount; using Microsoft.TemplateEngine.Abstractions.TemplateUpdates; @@ -447,6 +448,19 @@ private async Task ExecuteAsync() return CreationResultStatus.Success; } + try + { + bool isHiveUpdated = SyncOptionalWorkloads(); + if (isHiveUpdated) + { + Reporter.Output.WriteLine(LocalizableStrings.OptionalWorkloadsSynchronized); + } + } + catch (HiveSynchronizationException hiex) + { + Reporter.Error.WriteLine(hiex.Message.Bold().Red()); + } + bool forceCacheRebuild = _commandInput.HasDebuggingFlag("--debug:rebuildcache"); try { @@ -508,6 +522,65 @@ private bool ConfigureLocale() return true; } + private bool SyncOptionalWorkloads() + { + bool isHiveUpdated = false; + bool isCustomHive = _commandInput.HasDebuggingFlag("--debug:ephemeral-hive") || _commandInput.HasDebuggingFlag("--debug:custom-hive"); + + if (!isCustomHive) + { + string sdkVersion = EnvironmentSettings.Host.Version; + + try + { + List owInstallationRequests = new List(); + Dictionary owInstalledPkgs = new Dictionary(); // packageId -> packageVersion + TemplateLocator optionalWorkloadLocator = new TemplateLocator(); + + IReadOnlyCollection owPkgsToSync = optionalWorkloadLocator.GetDotnetSdkTemplatePackages(sdkVersion); + + foreach (IInstallUnitDescriptor descriptor in _settingsLoader.InstallUnitDescriptorCache.Descriptors.Values) + { + + if (descriptor.IsPartOfAnOptionalWorkload) + { + if (!descriptor.Details.TryGetValue("Version", out string pkgVersion)) + { + pkgVersion = string.Empty; + } + owInstalledPkgs.Add(descriptor.Identifier, pkgVersion); + } + } + + foreach (IOptionalSdkTemplatePackageInfo packageInfo in owPkgsToSync) + { + if (!owInstalledPkgs.TryGetValue(packageInfo.TemplatePackageId, out string version) || + version != packageInfo.TemplateVersion) + { + isHiveUpdated = true; + owInstallationRequests.Add(new InstallationRequest(packageInfo.Path, isPartOfAnOptionalWorkload: true)); + } + } + + if (owInstallationRequests.Count != 0) + { + Installer.InstallPackages(owInstallationRequests); + } + + /* TODO: add comparison of Optional SDK Workload templates from Hive and returned by TemplateLocator + * implement templates removal if they are not returned by API anymore + */ + + } + catch (Exception ex) + { + throw new HiveSynchronizationException(LocalizableStrings.OptionalWorkloadsSyncFailed, sdkVersion, ex); + } + } + + return isHiveUpdated; + } + private bool Initialize() { bool ephemeralHiveFlag = _commandInput.HasDebuggingFlag("--debug:ephemeral-hive");