diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/Components.cs b/src/Cli/Microsoft.TemplateEngine.Cli/Components.cs index 57eb7b1d9347..34870595d00e 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/Components.cs +++ b/src/Cli/Microsoft.TemplateEngine.Cli/Components.cs @@ -14,7 +14,8 @@ public static class Components (typeof(IPostActionProcessor), new ChmodPostActionProcessor()), (typeof(IPostActionProcessor), new InstructionDisplayPostActionProcessor()), (typeof(IPostActionProcessor), new ProcessStartPostActionProcessor()), - (typeof(IPostActionProcessor), new AddJsonPropertyPostActionProcessor()) + (typeof(IPostActionProcessor), new AddJsonPropertyPostActionProcessor()), + (typeof(IPostActionProcessor), new CreateOrUpdateDotnetConfigPostActionProcessor()), }; } } diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs b/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs index 18d737c820d9..f7b0a86e0e80 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs +++ b/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.TemplateEngine.Cli { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class LocalizableStrings { @@ -458,6 +458,15 @@ internal static string CliTemplateSearchCoordinator_Info_SearchInProgress { } } + /// + /// Looks up a localized string similar to The colon separator "::" has been deprecated in favor of the at symbol "@" for separating the package from the version in dotnet new install. In your case, this means {0}@{1} instead of {0}::{1}.. + /// + internal static string Colon_Separator_Deprecated { + get { + return ResourceManager.GetString("Colon_Separator_Deprecated", resourceCulture); + } + } + /// /// Looks up a localized string similar to Author. /// @@ -1394,6 +1403,51 @@ internal static string PossibleValuesHeader { } } + /// + /// Looks up a localized string similar to Created new section in 'dotnet.config' file. + /// + internal static string PostAction_CreateDotnetConfig_CreatedNewSection { + get { + return ResourceManager.GetString("PostAction_CreateDotnetConfig_CreatedNewSection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'.. + /// + internal static string PostAction_CreateDotnetConfig_ManuallyUpdate { + get { + return ResourceManager.GetString("PostAction_CreateDotnetConfig_ManuallyUpdate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully created 'dotnet.config' file.. + /// + internal static string PostAction_CreateDotnetConfig_Succeeded { + get { + return ResourceManager.GetString("PostAction_CreateDotnetConfig_Succeeded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The required value in 'dotnet.config' is already set.. + /// + internal static string PostAction_CreateDotnetConfig_ValueAlreadyExist { + get { + return ResourceManager.GetString("PostAction_CreateDotnetConfig_ValueAlreadyExist", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Post action argument '{0}' is mandatory, but not configured.. + /// + internal static string PostAction_DotnetConfig_Error_ArgumentNotConfigured { + get { + return ResourceManager.GetString("PostAction_DotnetConfig_Error_ArgumentNotConfigured", resourceCulture); + } + } + /// /// Looks up a localized string similar to Post action argument '{0}' is not a valid boolean value.. /// @@ -1870,35 +1924,21 @@ internal static string TemplatePackageCoordinator_Install_Info_OverrideNotice { return ResourceManager.GetString("TemplatePackageCoordinator_Install_Info_OverrideNotice", resourceCulture); } } - - /// - /// Looks up a localized string similar to The following template packages will be installed:. - /// - internal static string TemplatePackageCoordinator_Install_Info_PackageIsAvailable - { - get - { - return ResourceManager.GetString("TemplatePackageCoordinator_Install_Info_PackageIsAvailable", resourceCulture); - } - } - + /// - /// Looks up a localized string indicating that :: as a separator is deprecated in favor of @. + /// Looks up a localized string similar to The following template package(s) are already available:. /// - internal static string Colon_Separator_Deprecated - { + internal static string TemplatePackageCoordinator_Install_Info_PackageIsAvailable { get { - return ResourceManager.GetString("Colon_Separator_Deprecated", resourceCulture); + return ResourceManager.GetString("TemplatePackageCoordinator_Install_Info_PackageIsAvailable", resourceCulture); } } - + /// /// Looks up a localized string similar to The following template packages will be installed:. /// - internal static string TemplatePackageCoordinator_Install_Info_PackagesToBeInstalled - { - get - { + internal static string TemplatePackageCoordinator_Install_Info_PackagesToBeInstalled { + get { return ResourceManager.GetString("TemplatePackageCoordinator_Install_Info_PackagesToBeInstalled", resourceCulture); } } diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx b/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx index 3f38783adb27..d7de5f7d82b2 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx +++ b/src/Cli/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx @@ -953,4 +953,23 @@ The header is followed by the list of parameters and their errors (might be seve Attempting to find json file '{0}' in '{1}' + + Post action argument '{0}' is mandatory, but not configured. + + + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + \ No newline at end of file diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj b/src/Cli/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj index 228c9cd613d2..d8fb3406268a 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj +++ b/src/Cli/Microsoft.TemplateEngine.Cli/Microsoft.TemplateEngine.Cli.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/PostActionProcessors/CreateOrUpdateDotnetConfigPostActionProcessor.cs b/src/Cli/Microsoft.TemplateEngine.Cli/PostActionProcessors/CreateOrUpdateDotnetConfigPostActionProcessor.cs new file mode 100644 index 000000000000..9afbf5e899a0 --- /dev/null +++ b/src/Cli/Microsoft.TemplateEngine.Cli/PostActionProcessors/CreateOrUpdateDotnetConfigPostActionProcessor.cs @@ -0,0 +1,131 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.DotNet.Cli.Utils; +using Microsoft.Extensions.Configuration; +using Microsoft.TemplateEngine.Abstractions; +using Microsoft.TemplateEngine.Abstractions.PhysicalFileSystem; + +namespace Microsoft.TemplateEngine.Cli.PostActionProcessors +{ + internal sealed class CreateOrUpdateDotnetConfigPostActionProcessor : PostActionProcessorBase + { + private const string SectionArgument = "section"; + private const string KeyArgument = "key"; + private const string ValueArgument = "value"; + + public override Guid Id => ActionProcessorId; + + internal static Guid ActionProcessorId { get; } = new Guid("597E7933-0D87-452C-B094-8FA0EEF7FD97"); + + protected override bool ProcessInternal( + IEngineEnvironmentSettings environment, + IPostAction action, + ICreationEffects creationEffects, + ICreationResult templateCreationResult, + string outputBasePath) + { + if (!action.Args.TryGetValue(SectionArgument, out string? sectionName)) + { + Reporter.Error.WriteLine(string.Format(LocalizableStrings.PostAction_DotnetConfig_Error_ArgumentNotConfigured, SectionArgument)); + return false; + } + + if (!action.Args.TryGetValue(KeyArgument, out string? key)) + { + Reporter.Error.WriteLine(string.Format(LocalizableStrings.PostAction_DotnetConfig_Error_ArgumentNotConfigured, KeyArgument)); + return false; + } + + if (!action.Args.TryGetValue(ValueArgument, out string? value)) + { + Reporter.Error.WriteLine(string.Format(LocalizableStrings.PostAction_DotnetConfig_Error_ArgumentNotConfigured, ValueArgument)); + return false; + } + + var fileSystem = environment.Host.FileSystem; + var repoRoot = GetRootDirectory(fileSystem, outputBasePath); + var dotnetConfigFilePath = Path.Combine(repoRoot, "dotnet.config"); + if (!fileSystem.FileExists(dotnetConfigFilePath)) + { + fileSystem.WriteAllText(dotnetConfigFilePath, $""" + [{sectionName}] + {key} = "{value}" + + """); + + Reporter.Output.WriteLine(LocalizableStrings.PostAction_CreateDotnetConfig_Succeeded); + return true; + } + + var builder = new ConfigurationBuilder(); + using var stream = fileSystem.OpenRead(dotnetConfigFilePath); + builder.AddIniStream(stream); + IConfigurationRoot config = builder.Build(); + var section = config.GetSection(sectionName); + + if (!section.Exists()) + { + var existingContent = fileSystem.ReadAllText(dotnetConfigFilePath); + fileSystem.WriteAllText(dotnetConfigFilePath, $""" + {existingContent} + + [{sectionName}] + {key} = "{value}" + + """); + + Reporter.Output.WriteLine(LocalizableStrings.PostAction_CreateDotnetConfig_CreatedNewSection); + return true; + } + + string? existingValue = section[key]; + if (string.IsNullOrEmpty(existingValue)) + { + // The section exists, but the key/value pair does not. + Reporter.Error.WriteLine(string.Format(LocalizableStrings.PostAction_CreateDotnetConfig_ManuallyUpdate, $"{key} = \"{value}\"", $"[{sectionName}]")); + return false; + } + + if (existingValue.Equals(value, StringComparison.Ordinal)) + { + // The key already exists with the same value, nothing to do. + Reporter.Output.WriteLine(LocalizableStrings.PostAction_CreateDotnetConfig_ValueAlreadyExist); + return true; + } + + Reporter.Error.WriteLine(string.Format(LocalizableStrings.PostAction_CreateDotnetConfig_ManuallyUpdate, $"{key} = \"{value}\"", $"[{sectionName}]")); + return false; + } + + private static string GetRootDirectory(IPhysicalFileSystem fileSystem, string outputBasePath) + { + string? currentDirectory = outputBasePath; + string? directoryWithSln = null; + while (currentDirectory is not null) + { + if (fileSystem.FileExists(Path.Combine(currentDirectory, "dotnet.config")) || + fileSystem.DirectoryExists(Path.Combine(currentDirectory, ".git"))) + { + return currentDirectory; + } + + // DirectoryExists here should always be true in practice, but for the way tests are mocking the file system, it's not. + // The check was added to prevent test failures similar to: + // System.IO.DirectoryNotFoundException : Could not find a part of the path '/Users/runner/work/1/s/artifacts/bin/Microsoft.TemplateEngine.Cli.UnitTests/Release/sandbox'. + // We get to this exception when doing `EnumerateFiles` on a directory that was virtually created in memory (not really available on disk). + // EnumerateFiles tries to access the physical file system, which then fails. + if (fileSystem.DirectoryExists(currentDirectory) && + (fileSystem.EnumerateFiles(currentDirectory, "*.sln", SearchOption.TopDirectoryOnly).Any() || + fileSystem.EnumerateFiles(currentDirectory, "*.slnx", SearchOption.TopDirectoryOnly).Any())) + { + directoryWithSln = currentDirectory; + } + + currentDirectory = Directory.GetParent(currentDirectory)?.FullName; + } + + return directoryWithSln ?? outputBasePath; + } + } +} diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.cs.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.cs.xlf index 45f6d58a1ba7..2a4a247003b1 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.cs.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Chcete tuto akci spustit? [{0}(ano)|{1}(ne)] + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. Argument post-action {0} není platná logická hodnota. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.de.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.de.xlf index eb67ab8bf9bf..2bf7017b7241 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.de.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Möchten Sie diese Aktion ausführen [{0} (ja) |{1} (nein)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. Das Post-Aktionsargument „{0}“ ist kein gültiger boolescher Wert. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.es.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.es.xlf index 748e66f30a00..5b9822e43d7b 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.es.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve ¿Quiere ejecutar esta acción [{0}(yes)|{1}(no)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. El argumento de la acción publicado '{0}' no es un valor booleano válido. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.fr.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.fr.xlf index d86722e36e60..b25d0abe8451 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.fr.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Voulez-vous exécuter cette action [{0} (yes) |{1} (no)] ? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. L’argument post-action « {0} » n’est pas une valeur booléenne valide. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.it.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.it.xlf index 45d8e4f02e4e..2d8e48dbaf41 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.it.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Eseguire questa azione [{0} (sì) |{1} (no)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. L'argomento dell'azione successiva '{0}' non è un valore booleano valido. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ja.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ja.xlf index 2f9a5c77a259..8c189ad07d9f 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ja.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve このアクションを実行しますか[{0} (はい) |{1} (いいえ)] ですか? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. 事後アクションの引数 '{0}' は有効なブール値ではありません。 diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ko.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ko.xlf index 11699454506d..01d53932780b 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ko.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve 이 작업을 실행하시겠어요 [{0} (예) |{1} (아니요)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. 사후 작업 인수 '{0}'은(는) 올바른 부울 값이 아닙니다. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pl.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pl.xlf index 6e5167124b31..e35d2f20dcfa 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pl.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Chcesz uruchomić tę akcję [{0}(tak)|{1}(nie)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. Argument akcji „{0}” nie jest prawidłową wartością logiczną. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pt-BR.xlf index 24f89179cb85..5f09b05a889f 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.pt-BR.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Deseja executar esta ação [{0}(yes)|{1}(no)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. O argumento de pós-ação '{0}' não é um valor booleano válido. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ru.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ru.xlf index 6578a4d5bf14..e16f4f2f2508 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.ru.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Вы хотите выполнить это действие [{0}(да)|{1}(нет)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. Аргумент после действия "{0}" не является допустимым логическим значением. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.tr.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.tr.xlf index a0d71cff2b96..9cf57a18b1ff 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.tr.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve Bu eylemi çalıştırmak istiyor musunuz [{0}(evet)|{1}(hayır)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. '{0}' eylem sonrası bağımsız değişkeni, geçerli bir boole değeri değil. diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hans.xlf index f75d8ad68dae..be2844f845b7 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hans.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve 是否要运行此操作 [{0}(是)|{1}(否)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. Post 操作参数“{0}”不是有效的布尔值。 diff --git a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hant.xlf index 56c64a9d9b91..df84bc90c6dd 100644 --- a/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/Microsoft.TemplateEngine.Cli/xlf/LocalizableStrings.zh-Hant.xlf @@ -830,6 +830,31 @@ The header is followed by the list of parameters and their errors (might be seve 是否要執行此動作 [{0}(是)|{1}(否)]? + + Created new section in 'dotnet.config' file + Created new section in 'dotnet.config' file + {Locked="dotnet.config"} + + + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + Updating existing values in 'dotnet.config' is not yet supported. Please, manually update 'dotnet.config' to have '{0}' under section '{1}'. + {Locked="dotnet.config"} + + + Successfully created 'dotnet.config' file. + Successfully created 'dotnet.config' file. + {Locked="dotnet.config"} + + + The required value in 'dotnet.config' is already set. + The required value in 'dotnet.config' is already set. + {Locked="dotnet.config"} + + + Post action argument '{0}' is mandatory, but not configured. + Post action argument '{0}' is mandatory, but not configured. + + Post action argument '{0}' is not a valid boolean value. Post 巨集指令引數 '{0}' 不是有效的布林值。 diff --git a/test/Microsoft.TemplateEngine.Cli.UnitTests/PostActionTests/CreateOrUpdateDotnetConfigPostActionTests.cs b/test/Microsoft.TemplateEngine.Cli.UnitTests/PostActionTests/CreateOrUpdateDotnetConfigPostActionTests.cs new file mode 100644 index 000000000000..6d66a0c6b895 --- /dev/null +++ b/test/Microsoft.TemplateEngine.Cli.UnitTests/PostActionTests/CreateOrUpdateDotnetConfigPostActionTests.cs @@ -0,0 +1,223 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.TemplateEngine.Abstractions; +using Microsoft.TemplateEngine.Cli.PostActionProcessors; +using Microsoft.TemplateEngine.Mocks; +using Microsoft.TemplateEngine.TestHelper; + +using Moq; + +namespace Microsoft.TemplateEngine.Cli.UnitTests.PostActionTests; + +public class CreateOrUpdateDotnetConfigPostActionTests : IClassFixture +{ + private readonly IEngineEnvironmentSettings _engineEnvironmentSettings; + + public CreateOrUpdateDotnetConfigPostActionTests(EnvironmentSettingsHelper environmentSettingsHelper) + { + _engineEnvironmentSettings = environmentSettingsHelper.CreateEnvironment(hostIdentifier: GetType().Name, virtualize: true); + } + + [Theory] + [InlineData("section")] + [InlineData("key")] + [InlineData("value")] + public void MissingArgumentShouldFail(string missingArgumentName) + { + string targetBasePath = GetTargetPath(); + + var dictionary = new Dictionary + { + ["section"] = "dotnet.test.runner", + ["key"] = "name", + ["value"] = "Microsoft.Testing.Platform" + }; + dictionary.Remove(missingArgumentName); + + IPostAction postAction = new MockPostAction(default, default, default, default, default!) + { + ActionId = CreateOrUpdateDotnetConfigPostActionProcessor.ActionProcessorId, + Args = dictionary, + }; + + Mock mockReporter = new(); + + mockReporter.Setup(r => r.WriteLine(It.IsAny())) + .Verifiable(); + + Reporter.SetError(mockReporter.Object); + + CreateOrUpdateDotnetConfigPostActionProcessor processor = new(); + + bool result = processor.Process( + _engineEnvironmentSettings, + postAction, + new MockCreationEffects(), + new MockCreationResult(), + targetBasePath); + + Assert.False(result); + + mockReporter.Verify(r => r.WriteLine(string.Format(LocalizableStrings.PostAction_DotnetConfig_Error_ArgumentNotConfigured, missingArgumentName)), Times.Once); + } + + [Fact] + public void CreatesDotnetConfigWhenDoesNotExist() + { + string targetBasePath = GetTargetPath(); + string dotnetConfigPath = Path.Combine(targetBasePath, "dotnet.config"); + + IPostAction postAction = CreatePostActionForMTP(); + + Mock mockReporter = new(); + + mockReporter.Setup(r => r.WriteLine(It.IsAny())) + .Verifiable(); + + Reporter.SetOutput(mockReporter.Object); + + CreateOrUpdateDotnetConfigPostActionProcessor processor = new(); + + _engineEnvironmentSettings.Host.FileSystem.FileExists(dotnetConfigPath).Should().BeFalse(); + + bool result = processor.Process( + _engineEnvironmentSettings, + postAction, + new MockCreationEffects(), + new MockCreationResult(), + targetBasePath); + + Assert.True(result); + + _engineEnvironmentSettings.Host.FileSystem.FileExists(dotnetConfigPath).Should().BeTrue(); + _engineEnvironmentSettings.Host.FileSystem.ReadAllText(dotnetConfigPath).Should().Be(""" + [dotnet.test.runner] + name = "Microsoft.Testing.Platform" + + """); + + mockReporter.Verify(r => r.WriteLine(LocalizableStrings.PostAction_CreateDotnetConfig_Succeeded), Times.Once); + } + + [Fact] + public void CreatesNewSectionWhenFileExistsButSectionDoesNot() + { + string targetBasePath = GetTargetPath(); + string dotnetConfigPath = Path.Combine(targetBasePath, "dotnet.config"); + + IPostAction postAction = CreatePostActionForMTP(); + CreateDotnetConfig(dotnetConfigPath, "mysection", "mykey", "myvalue"); + Mock mockReporter = new(); + + mockReporter.Setup(r => r.WriteLine(It.IsAny())) + .Verifiable(); + + Reporter.SetOutput(mockReporter.Object); + + CreateOrUpdateDotnetConfigPostActionProcessor processor = new(); + + _engineEnvironmentSettings.Host.FileSystem.FileExists(dotnetConfigPath).Should().BeTrue(); + _engineEnvironmentSettings.Host.FileSystem.ReadAllText(dotnetConfigPath).Should().Be(""" + [mysection] + mykey = "myvalue" + + """); + + bool result = processor.Process( + _engineEnvironmentSettings, + postAction, + new MockCreationEffects(), + new MockCreationResult(), + targetBasePath); + + Assert.True(result); + + _engineEnvironmentSettings.Host.FileSystem.FileExists(dotnetConfigPath).Should().BeTrue(); + _engineEnvironmentSettings.Host.FileSystem.ReadAllText(dotnetConfigPath).Should().Be(""" + [mysection] + mykey = "myvalue" + + + [dotnet.test.runner] + name = "Microsoft.Testing.Platform" + + """); + + mockReporter.Verify(r => r.WriteLine(LocalizableStrings.PostAction_CreateDotnetConfig_CreatedNewSection), Times.Once); + } + + [Fact] + public void DoesNothingIfNoUpdatesNeedToHappen() + { + string targetBasePath = GetTargetPath(); + string dotnetConfigPath = Path.Combine(targetBasePath, "dotnet.config"); + + IPostAction postAction = CreatePostActionForMTP(); + CreateDotnetConfig(dotnetConfigPath, "dotnet.test.runner", "name", "Microsoft.Testing.Platform"); + Mock mockReporter = new(); + + mockReporter.Setup(r => r.WriteLine(It.IsAny())) + .Verifiable(); + + Reporter.SetOutput(mockReporter.Object); + + CreateOrUpdateDotnetConfigPostActionProcessor processor = new(); + + _engineEnvironmentSettings.Host.FileSystem.FileExists(dotnetConfigPath).Should().BeTrue(); + _engineEnvironmentSettings.Host.FileSystem.ReadAllText(dotnetConfigPath).Should().Be(""" + [dotnet.test.runner] + name = "Microsoft.Testing.Platform" + + """); + + bool result = processor.Process( + _engineEnvironmentSettings, + postAction, + new MockCreationEffects(), + new MockCreationResult(), + targetBasePath); + + Assert.True(result); + + _engineEnvironmentSettings.Host.FileSystem.FileExists(dotnetConfigPath).Should().BeTrue(); + _engineEnvironmentSettings.Host.FileSystem.ReadAllText(dotnetConfigPath).Should().Be(""" + [dotnet.test.runner] + name = "Microsoft.Testing.Platform" + + """); + + mockReporter.Verify(r => r.WriteLine(LocalizableStrings.PostAction_CreateDotnetConfig_ValueAlreadyExist), Times.Once); + } + + private static IPostAction CreatePostActionForMTP() + => new MockPostAction(default, default, default, default, default!) + { + ActionId = CreateOrUpdateDotnetConfigPostActionProcessor.ActionProcessorId, + Args = new Dictionary + { + ["section"] = "dotnet.test.runner", + ["key"] = "name", + ["value"] = "Microsoft.Testing.Platform", + }, + }; + + private void CreateDotnetConfig(string dotnetConfigPath, string section, string key, string value) + => _engineEnvironmentSettings.Host.FileSystem.WriteAllText(dotnetConfigPath, $""" + [{section}] + {key} = "{value}" + + """); + + private string GetTargetPath([CallerMemberName] string testName = "") + { + string targetBasePath = Path.Combine(_engineEnvironmentSettings.GetTempVirtualizedPath(), testName); + _engineEnvironmentSettings.Host.FileSystem.CreateDirectory(targetBasePath); + + // This is done to not let the preprocessor logic go above our base path directory. + _engineEnvironmentSettings.Host.FileSystem.CreateDirectory(Path.Combine(targetBasePath, ".git")); + return targetBasePath; + } +} diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/.template.config/template.json b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/.template.config/template.json new file mode 100644 index 000000000000..18b058625a93 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/.template.config/template.json @@ -0,0 +1,29 @@ +{ + "author": "Test Asset", + "classifications": [ "Test Asset" ], + "name": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection", + "generatorVersions": "[1.0.0.0-*)", + "groupIdentity": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection", + "precedence": "100", + "identity": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection", + "shortName": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection", + "sourceName": "AddNewSection", + "primaryOutputs": [ + { + "path": "AddNewSection.csproj" + } + ], + "postActions": [ + { + "description": "Add dotnet.config", + "manualInstructions": [ { "text": "Create dotnet.config manually." } ], + "args": { + "section": "SectionFromTemplateJson", + "key": "KeyFromTemplateJson", + "value": "ValueFromTemplateJson" + }, + "actionId": "597E7933-0D87-452C-B094-8FA0EEF7FD97", + "continueOnError": true + } + ] +} diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/AddNewSection.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/AddNewSection.csproj new file mode 100644 index 000000000000..ba7e2d463888 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/AddNewSection.csproj @@ -0,0 +1,8 @@ + + + + Exe + $(CurrentTargetFramework) + + + diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/Program.cs b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/Program.cs new file mode 100644 index 000000000000..38a7692a4297 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/Program.cs @@ -0,0 +1,14 @@ +using System; +using Newtonsoft.Json; + +namespace Basic +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + string result = JsonConvert.SerializeObject(new { a = "test" }); + } + } +} diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/dotnet.config b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/dotnet.config new file mode 100644 index 000000000000..d658b6c3fdd3 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/AddNewSection/dotnet.config @@ -0,0 +1,2 @@ +[existing-section] +mykey = "myvalue" \ No newline at end of file diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/.template.config/template.json b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/.template.config/template.json new file mode 100644 index 000000000000..93c23963f8d7 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/.template.config/template.json @@ -0,0 +1,29 @@ +{ + "author": "Test Asset", + "classifications": [ "Test Asset" ], + "name": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting", + "generatorVersions": "[1.0.0.0-*)", + "groupIdentity": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting", + "precedence": "100", + "identity": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting", + "shortName": "TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting", + "sourceName": "CreateNonExisting", + "primaryOutputs": [ + { + "path": "CreateNonExisting.csproj" + } + ], + "postActions": [ + { + "description": "Add dotnet.config", + "manualInstructions": [ { "text": "Create dotnet.config manually." } ], + "args": { + "section": "SectionFromTemplateJson", + "key": "KeyFromTemplateJson", + "value": "ValueFromTemplateJson" + }, + "actionId": "597E7933-0D87-452C-B094-8FA0EEF7FD97", + "continueOnError": true + } + ] +} diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/CreateNonExisting.csproj b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/CreateNonExisting.csproj new file mode 100644 index 000000000000..ba7e2d463888 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/CreateNonExisting.csproj @@ -0,0 +1,8 @@ + + + + Exe + $(CurrentTargetFramework) + + + diff --git a/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/Program.cs b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/Program.cs new file mode 100644 index 000000000000..38a7692a4297 --- /dev/null +++ b/test/TestAssets/TestPackages/dotnet-new/test_templates/PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting/Program.cs @@ -0,0 +1,14 @@ +using System; +using Newtonsoft.Json; + +namespace Basic +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + string result = JsonConvert.SerializeObject(new { a = "test" }); + } + } +} diff --git a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Linux.verified.txt b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Linux.verified.txt index 948efa0f8d7b..c69514a6ee7b 100644 --- a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Linux.verified.txt +++ b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Linux.verified.txt @@ -31,6 +31,8 @@ TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicInSolutionRoot Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithFiles Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithIndexes Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting Test Asset TestAssets.PostActions.Instructions.Basic TestAssets.PostActions.Instructions.Basic Test Asset TestAssets.PostActions.RestoreNuGet.Basic TestAssets.PostActions.RestoreNuGet.Basic Test Asset TestAssets.PostActions.RestoreNuGet.BasicWit... TestAssets.PostActions.RestoreNuGet.BasicWithFiles Test Asset diff --git a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.OSX.verified.txt b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.OSX.verified.txt index 948efa0f8d7b..c69514a6ee7b 100644 --- a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.OSX.verified.txt +++ b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.OSX.verified.txt @@ -31,6 +31,8 @@ TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicInSolutionRoot Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithFiles Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithIndexes Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting Test Asset TestAssets.PostActions.Instructions.Basic TestAssets.PostActions.Instructions.Basic Test Asset TestAssets.PostActions.RestoreNuGet.Basic TestAssets.PostActions.RestoreNuGet.Basic Test Asset TestAssets.PostActions.RestoreNuGet.BasicWit... TestAssets.PostActions.RestoreNuGet.BasicWithFiles Test Asset diff --git a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Windows.verified.txt b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Windows.verified.txt index 8f48b106823e..f2c16d05d10d 100644 --- a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Windows.verified.txt +++ b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.Windows.verified.txt @@ -31,6 +31,8 @@ TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithFiles Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithIndexes Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.Basic Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting Test Asset TestAssets.PostActions.Instructions.Basic TestAssets.PostActions.Instructions.Basic Test Asset TestAssets.PostActions.RestoreNuGet.BasicWit... TestAssets.PostActions.RestoreNuGet.BasicWithFiles Test Asset TestAssets.PostActions.RestoreNuGet.Basic TestAssets.PostActions.RestoreNuGet.Basic Test Asset diff --git a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.verified.txt b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.verified.txt index 3264f4ecfdd7..0a6b5d625e43 100644 --- a/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.verified.txt +++ b/test/dotnet-new.IntegrationTests/Approvals/DotnetNewDetailsTest.CanDisplayDetails_InstalledPackage_LocalPackage.verified.txt @@ -31,6 +31,8 @@ TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithFiles Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.BasicWithIndexes Test Asset TestAssets.PostActions.AddProjectToSolution.... TestAssets.PostActions.AddProjectToSolution.Basic Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection Test Asset + TestAssets.PostActions.CreateOrUpdateDotnetC... TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting Test Asset TestAssets.PostActions.Instructions.Basic TestAssets.PostActions.Instructions.Basic Test Asset TestAssets.PostActions.RestoreNuGet.BasicWit... TestAssets.PostActions.RestoreNuGet.BasicWithFiles Test Asset TestAssets.PostActions.RestoreNuGet.Basic TestAssets.PostActions.RestoreNuGet.Basic Test Asset diff --git a/test/dotnet-new.IntegrationTests/PostActionTests.cs b/test/dotnet-new.IntegrationTests/PostActionTests.cs index 3e9c6a391914..3acada973357 100644 --- a/test/dotnet-new.IntegrationTests/PostActionTests.cs +++ b/test/dotnet-new.IntegrationTests/PostActionTests.cs @@ -3,6 +3,7 @@ using System.Text.Json.Nodes; using Microsoft.DotNet.Cli.Utils; +using Microsoft.TemplateEngine.TestHelper; using Microsoft.TemplateEngine.Utils; namespace Microsoft.DotNet.Cli.New.IntegrationTests @@ -1215,5 +1216,72 @@ public void AddJsonProperty_FailsWhenJsonFileNotFoundInEligableDirectories() File.Delete(jsonFileLocation); } + + [Fact] + public void CreateOrUpdateDotnetConfig_CreateNonExisting() + { + string templateLocation = _testAssetsManager.CopyTestAsset("PostActions/CreateOrUpdateDotnetConfig/CreateNonExisting", testAssetSubdirectory: DotnetNewTestTemplatesBasePath).WithSource().Path; + string expectedTemplateName = "TestAssets.PostActions.CreateOrUpdateDotnetConfig.CreateNonExisting"; + string home = CreateTemporaryFolder(folderName: "Home"); + string workingDirectory = CreateTemporaryFolder(); + string outputDirectory = TestUtils.CreateTemporaryFolder(); + InstallTestTemplate(templateLocation, _log, home, workingDirectory); + + var commandResult = new DotnetNewCommand(_log, expectedTemplateName, "-n", "MyProject", "-o", outputDirectory) + .WithCustomHive(home) + .WithWorkingDirectory(workingDirectory) + .Execute(); + + commandResult + .Should() + .ExitWith(0) + .And.NotHaveStdErr() + .And.HaveStdOutContaining($"The template \"{expectedTemplateName}\" was created successfully.") + .And.HaveStdOutContaining("Successfully created 'dotnet.config' file.") + .And.NotHaveStdOutContaining("Manual instructions"); + + Assert.Equal( + """ + [SectionFromTemplateJson] + KeyFromTemplateJson = "ValueFromTemplateJson" + + """, + File.ReadAllText(Path.Combine(outputDirectory, "dotnet.config"))); + } + + [Fact] + public void CreateOrUpdateDotnetConfig_AddNewSection() + { + string templateLocation = _testAssetsManager.CopyTestAsset("PostActions/CreateOrUpdateDotnetConfig/AddNewSection", testAssetSubdirectory: DotnetNewTestTemplatesBasePath).WithSource().Path; + string expectedTemplateName = "TestAssets.PostActions.CreateOrUpdateDotnetConfig.AddNewSection"; + string home = CreateTemporaryFolder(folderName: "Home"); + string workingDirectory = CreateTemporaryFolder(); + string outputDirectory = TestUtils.CreateTemporaryFolder(); + InstallTestTemplate(templateLocation, _log, home, workingDirectory); + + var commandResult = new DotnetNewCommand(_log, expectedTemplateName, "-n", "MyProject", "-o", outputDirectory) + .WithCustomHive(home) + .WithWorkingDirectory(workingDirectory) + .Execute(); + + commandResult + .Should() + .ExitWith(0) + .And.NotHaveStdErr() + .And.HaveStdOutContaining($"The template \"{expectedTemplateName}\" was created successfully.") + .And.HaveStdOutContaining("Created new section in 'dotnet.config' file") + .And.NotHaveStdOutContaining("Manual instructions"); + + Assert.Equal( + """ + [existing-section] + mykey = "myvalue" + + [SectionFromTemplateJson] + KeyFromTemplateJson = "ValueFromTemplateJson" + + """, + File.ReadAllText(Path.Combine(outputDirectory, "dotnet.config"))); + } } }