diff --git a/Microsoft.TemplateEngine.sln b/Microsoft.TemplateEngine.sln index b1b8421e84b..392461e372a 100644 --- a/Microsoft.TemplateEngine.sln +++ b/Microsoft.TemplateEngine.sln @@ -100,6 +100,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.TemplateEngine.Co tools\Shared\Microsoft.TemplateEngine.CommandUtils\TestCommand.cs = tools\Shared\Microsoft.TemplateEngine.CommandUtils\TestCommand.cs EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TemplateEngine.Authoring.TemplateApiVerifier", "tools\Microsoft.TemplateEngine.Authoring.TemplateApiVerifier\Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.csproj", "{449B9DDA-F18C-411E-9A74-3930652BB78A}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "template-samples", "template-samples", "{3A2D12C2-0455-4471-9EBB-91749BA3A60F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.TemplateEngine.Samples", "dotnet-template-samples\Microsoft.TemplateEngine.Samples.csproj", "{DFB06A25-719F-4C8B-B84D-55D2D601BEF6}" @@ -474,6 +476,18 @@ Global {E8B9226E-879F-495A-BDAD-2607844D048C}.Release|x64.Build.0 = Release|Any CPU {E8B9226E-879F-495A-BDAD-2607844D048C}.Release|x86.ActiveCfg = Release|Any CPU {E8B9226E-879F-495A-BDAD-2607844D048C}.Release|x86.Build.0 = Release|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Debug|x64.ActiveCfg = Debug|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Debug|x64.Build.0 = Debug|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Debug|x86.ActiveCfg = Debug|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Debug|x86.Build.0 = Debug|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Release|Any CPU.Build.0 = Release|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Release|x64.ActiveCfg = Release|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Release|x64.Build.0 = Release|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Release|x86.ActiveCfg = Release|Any CPU + {449B9DDA-F18C-411E-9A74-3930652BB78A}.Release|x86.Build.0 = Release|Any CPU {DFB06A25-719F-4C8B-B84D-55D2D601BEF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DFB06A25-719F-4C8B-B84D-55D2D601BEF6}.Debug|Any CPU.Build.0 = Debug|Any CPU {DFB06A25-719F-4C8B-B84D-55D2D601BEF6}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -524,6 +538,7 @@ Global {D190251C-5649-4DD6-A158-16D119116352} = {C5186341-2064-49AA-B398-CDF4302D2823} {43053BC4-32B4-4404-B62D-410F367CE0CE} = {B794BF86-4185-4DCE-AC86-C27D5D966B9B} {EE8CD472-D8C4-4CD0-BC84-6C305F5971AE} = {43053BC4-32B4-4404-B62D-410F367CE0CE} + {449B9DDA-F18C-411E-9A74-3930652BB78A} = {B794BF86-4185-4DCE-AC86-C27D5D966B9B} {DFB06A25-719F-4C8B-B84D-55D2D601BEF6} = {3A2D12C2-0455-4471-9EBB-91749BA3A60F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/Microsoft.TemplateEngine.Edge/DefaultEnvironment.cs b/src/Microsoft.TemplateEngine.Edge/DefaultEnvironment.cs index c2c7788eb5d..f8e3f420133 100644 --- a/src/Microsoft.TemplateEngine.Edge/DefaultEnvironment.cs +++ b/src/Microsoft.TemplateEngine.Edge/DefaultEnvironment.cs @@ -11,25 +11,20 @@ namespace Microsoft.TemplateEngine.Edge { /// /// Default implementation of . - /// Gets environment variables from . + /// Gets environment variables from . /// - public sealed class DefaultEnvironment : IEnvironment + public class DefaultEnvironment : IEnvironment { private const int DefaultBufferWidth = 160; private readonly IReadOnlyDictionary _environmentVariables; - public DefaultEnvironment() - { - Dictionary variables = new Dictionary(StringComparer.OrdinalIgnoreCase); - IDictionary env = System.Environment.GetEnvironmentVariables(); + public DefaultEnvironment() : this(FetchEnvironmentVariables()) + { } - foreach (string key in env.Keys.OfType()) - { - variables[key] = (env[key] as string) ?? string.Empty; - } - - _environmentVariables = variables; - NewLine = System.Environment.NewLine; + protected DefaultEnvironment(IReadOnlyDictionary environmentVariables) + { + _environmentVariables = environmentVariables; + NewLine = Environment.NewLine; } /// @@ -43,7 +38,7 @@ public DefaultEnvironment() /// public string ExpandEnvironmentVariables(string name) { - return System.Environment.ExpandEnvironmentVariables(name); + return Environment.ExpandEnvironmentVariables(name); } /// @@ -58,5 +53,18 @@ public IReadOnlyDictionary GetEnvironmentVariables() { return _environmentVariables; } + + protected static IReadOnlyDictionary FetchEnvironmentVariables() + { + Dictionary variables = new Dictionary(StringComparer.OrdinalIgnoreCase); + IDictionary env = Environment.GetEnvironmentVariables(); + + foreach (string key in env.Keys.OfType()) + { + variables[key] = (env[key] as string) ?? string.Empty; + } + + return variables; + } } } diff --git a/src/Microsoft.TemplateEngine.Edge/PublicAPI.Unshipped.txt b/src/Microsoft.TemplateEngine.Edge/PublicAPI.Unshipped.txt index 99f040ccaf6..b41de3b5a23 100644 --- a/src/Microsoft.TemplateEngine.Edge/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TemplateEngine.Edge/PublicAPI.Unshipped.txt @@ -1 +1,5 @@ -Microsoft.TemplateEngine.Edge.Settings.ITemplateInfoHostJsonCache.HostData.get -> string? \ No newline at end of file +Microsoft.TemplateEngine.Edge.DefaultEnvironment.DefaultEnvironment(System.Collections.Generic.IReadOnlyDictionary! environmentVariables) -> void +Microsoft.TemplateEngine.Edge.Settings.ITemplateInfoHostJsonCache.HostData.get -> string? +Microsoft.TemplateEngine.Edge.VirtualEnvironment +Microsoft.TemplateEngine.Edge.VirtualEnvironment.VirtualEnvironment(System.Collections.Generic.IReadOnlyDictionary? virtualEnvironemnt, bool includeRealEnvironment) -> void +static Microsoft.TemplateEngine.Edge.DefaultEnvironment.FetchEnvironmentVariables() -> System.Collections.Generic.IReadOnlyDictionary! diff --git a/src/Microsoft.TemplateEngine.Edge/VirtualEnvironment.cs b/src/Microsoft.TemplateEngine.Edge/VirtualEnvironment.cs new file mode 100644 index 00000000000..4b90d107f58 --- /dev/null +++ b/src/Microsoft.TemplateEngine.Edge/VirtualEnvironment.cs @@ -0,0 +1,44 @@ +// 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 Microsoft.TemplateEngine.Abstractions; +using Microsoft.TemplateEngine.Utils; + +namespace Microsoft.TemplateEngine.Edge +{ + /// + /// Virtualized implementation of . + /// Allows to overwrite and/or add environment variables not defined in physical environment. + /// + public class VirtualEnvironment : DefaultEnvironment + { + /// + /// Creates new instance of . + /// + /// Variables to be considered as environment variables. They have precedence over physical environment variables. + /// If set to true - variables from are added. + public VirtualEnvironment(IReadOnlyDictionary? virtualEnvironemnt, bool includeRealEnvironment) + : base(MergeEnvironmentVariables(virtualEnvironemnt, includeRealEnvironment)) + { } + + private static IReadOnlyDictionary MergeEnvironmentVariables( + IReadOnlyDictionary? virtualEnvironemnt, bool includeRealEnvironment) + { + Dictionary variables = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (includeRealEnvironment) + { + variables.Merge(FetchEnvironmentVariables()); + } + + if (virtualEnvironemnt != null) + { + variables.Merge(virtualEnvironemnt); + } + + return variables; + } + } +} diff --git a/src/Microsoft.TemplateEngine.IDE/Bootstrapper.cs b/src/Microsoft.TemplateEngine.IDE/Bootstrapper.cs index 3b888bcaab1..a7b97d64450 100644 --- a/src/Microsoft.TemplateEngine.IDE/Bootstrapper.cs +++ b/src/Microsoft.TemplateEngine.IDE/Bootstrapper.cs @@ -10,13 +10,15 @@ using System.Threading.Tasks; using Microsoft.TemplateEngine.Abstractions; using Microsoft.TemplateEngine.Abstractions.Installer; -using Microsoft.TemplateEngine.Abstractions.TemplateFiltering; using Microsoft.TemplateEngine.Abstractions.TemplatePackage; using Microsoft.TemplateEngine.Edge; using Microsoft.TemplateEngine.Edge.Settings; -using Microsoft.TemplateEngine.Utils; +using Microsoft.TemplateEngine.Edge.Template; using ITemplateCreationResult = Microsoft.TemplateEngine.Edge.Template.ITemplateCreationResult; +using ITemplateMatchInfo = Microsoft.TemplateEngine.Abstractions.TemplateFiltering.ITemplateMatchInfo; +using MatchInfo = Microsoft.TemplateEngine.Abstractions.TemplateFiltering.MatchInfo; using TemplateCreator = Microsoft.TemplateEngine.Edge.Template.TemplateCreator; +using WellKnownSearchFilters = Microsoft.TemplateEngine.Utils.WellKnownSearchFilters; namespace Microsoft.TemplateEngine.IDE { @@ -24,7 +26,7 @@ public class Bootstrapper : IDisposable { private readonly ITemplateEngineHost _host; private readonly TemplateCreator _templateCreator; - private readonly Edge.Settings.TemplatePackageManager _templatePackagesManager; + private readonly TemplatePackageManager _templatePackagesManager; private readonly EngineEnvironmentSettings _engineEnvironmentSettings; /// @@ -35,19 +37,25 @@ public class Bootstrapper : IDisposable /// if true, the default components (providers, installers, generator) will be loaded. Same as calling after instance is created. /// the file path to store host specific settings. Use null for default location. /// Note: this parameter changes only directory of host and host version specific settings. Global settings path remains unchanged. - public Bootstrapper(ITemplateEngineHost host, bool virtualizeConfiguration, bool loadDefaultComponents = true, string? hostSettingsLocation = null) + /// optional environment to be used (defaults to ). + public Bootstrapper( + ITemplateEngineHost host, + bool virtualizeConfiguration, + bool loadDefaultComponents = true, + string? hostSettingsLocation = null, + IEnvironment? environment = null) { _host = host ?? throw new ArgumentNullException(nameof(host)); + environment ??= new DefaultEnvironment(); if (string.IsNullOrWhiteSpace(hostSettingsLocation)) { - _engineEnvironmentSettings = new EngineEnvironmentSettings(host, virtualizeSettings: virtualizeConfiguration); + _engineEnvironmentSettings = new EngineEnvironmentSettings(host, virtualizeSettings: virtualizeConfiguration, environment: environment); } else { string hostSettingsDir = Path.Combine(hostSettingsLocation, host.HostIdentifier); string hostVersionSettingsDir = Path.Combine(hostSettingsLocation, host.HostIdentifier, host.Version); - IEnvironment environment = new DefaultEnvironment(); IPathInfo pathInfo = new DefaultPathInfo(environment, host, hostSettingsDir: hostSettingsDir, hostVersionSettingsDir: hostVersionSettingsDir); _engineEnvironmentSettings = new EngineEnvironmentSettings( host, @@ -57,7 +65,7 @@ public Bootstrapper(ITemplateEngineHost host, bool virtualizeConfiguration, bool } _templateCreator = new TemplateCreator(_engineEnvironmentSettings); - _templatePackagesManager = new Edge.Settings.TemplatePackageManager(_engineEnvironmentSettings); + _templatePackagesManager = new TemplatePackageManager(_engineEnvironmentSettings); if (loadDefaultComponents) { LoadDefaultComponents(); @@ -73,7 +81,7 @@ public void LoadDefaultComponents() { AddComponent(component.Type, component.Instance); } - foreach ((Type Type, IIdentifiedComponent Instance) component in Edge.Components.AllComponents) + foreach ((Type Type, IIdentifiedComponent Instance) component in Components.AllComponents) { AddComponent(component.Type, component.Instance); } @@ -103,7 +111,7 @@ public Task> GetTemplatesAsync(CancellationToken ca /// /// Gets list of available templates, if is provided returns only matching templates. /// - /// List of filters to apply. See for predefined filters. + /// List of filters to apply. See for predefined filters. /// /// true: templates should match all filters; false: templates should match any filter. /// @@ -158,6 +166,40 @@ public Task CreateAsync( cancellationToken: cancellationToken); } + /// + /// Instantiates the template. + /// + /// The template to instantiate. + /// The name to use. + /// The output directory for template instantiation. + /// The template parameters. + /// The baseline configuration to use. + /// A cancellation token to cancel the asynchronous operation. + /// containing information on created template or error occurred. +#pragma warning disable RS0027 // Public API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters + public Task CreateAsync( + ITemplateInfo info, + string? name, + string outputPath, + InputDataSet? inputParameters, + string? baselineName = null, + CancellationToken cancellationToken = default) +#pragma warning restore RS0027 // Public API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters + { + return _templateCreator.InstantiateAsync( + info, + name, + fallbackName: null, + outputPath: outputPath, + inputParameters: inputParameters, + forceCreation: false, + baselineName: baselineName, + dryRun: false, + cancellationToken: cancellationToken); + } + /// /// Dry runs the template with given parameters. /// diff --git a/src/Microsoft.TemplateEngine.IDE/PublicAPI.Shipped.txt b/src/Microsoft.TemplateEngine.IDE/PublicAPI.Shipped.txt index 5451ca77dd1..453be566bdd 100644 --- a/src/Microsoft.TemplateEngine.IDE/PublicAPI.Shipped.txt +++ b/src/Microsoft.TemplateEngine.IDE/PublicAPI.Shipped.txt @@ -20,7 +20,6 @@ Microsoft.TemplateEngine.IDE.Bootstrapper.Uninstall(string! path) -> System.Coll Microsoft.TemplateEngine.IDE.Bootstrapper.Uninstall(System.Collections.Generic.IEnumerable! paths) -> System.Collections.Generic.IEnumerable! Microsoft.TemplateEngine.IDE.Bootstrapper.UninstallTemplatePackagesAsync(System.Collections.Generic.IEnumerable! managedPackages, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!>! Microsoft.TemplateEngine.IDE.Bootstrapper.UpdateTemplatePackagesAsync(System.Collections.Generic.IEnumerable! updateRequests, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!>! -Microsoft.TemplateEngine.IDE.Bootstrapper.Bootstrapper(Microsoft.TemplateEngine.Abstractions.ITemplateEngineHost! host, bool virtualizeConfiguration, bool loadDefaultComponents = true, string? hostSettingsLocation = null) -> void Microsoft.TemplateEngine.IDE.Bootstrapper.GetManagedTemplatePackagesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!>! Microsoft.TemplateEngine.IDE.Bootstrapper.GetTemplatePackagesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!>! Microsoft.TemplateEngine.IDE.Bootstrapper.GetTemplatesAsync(System.Collections.Generic.IEnumerable!>! filters, bool exactMatchesOnly = true, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task!>! diff --git a/src/Microsoft.TemplateEngine.IDE/PublicAPI.Unshipped.txt b/src/Microsoft.TemplateEngine.IDE/PublicAPI.Unshipped.txt index 5f282702bb0..34b8eeef253 100644 --- a/src/Microsoft.TemplateEngine.IDE/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TemplateEngine.IDE/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ - \ No newline at end of file +Microsoft.TemplateEngine.IDE.Bootstrapper.Bootstrapper(Microsoft.TemplateEngine.Abstractions.ITemplateEngineHost! host, bool virtualizeConfiguration, bool loadDefaultComponents = true, string? hostSettingsLocation = null, Microsoft.TemplateEngine.Abstractions.IEnvironment? environment = null) -> void +Microsoft.TemplateEngine.IDE.Bootstrapper.CreateAsync(Microsoft.TemplateEngine.Abstractions.ITemplateInfo! info, string? name, string! outputPath, Microsoft.TemplateEngine.Edge.Template.InputDataSet? inputParameters, string? baselineName = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task! \ No newline at end of file diff --git a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/ExampleTemplateTest.cs b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/ExampleTemplateTest.cs index 9b78f45d6f3..84d45a7129a 100644 --- a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/ExampleTemplateTest.cs +++ b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/ExampleTemplateTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Extensions.Logging; +using Microsoft.TemplateEngine.Authoring.TemplateApiVerifier; using Microsoft.TemplateEngine.TestHelper; using Microsoft.TemplateEngine.Tests; using Xunit.Abstractions; @@ -17,6 +18,10 @@ public ExampleTemplateTest(ITestOutputHelper log) _log = new XunitLoggerProvider(log).CreateLogger("TestRun"); } + // Following 2 tests share identical snapshot folder - that's the reason for the additional + // naming parameters (DoNotPrependCallerMethodNameToScenarioName, DoNotAppendTemplateArgsToScenarioName, ScenarioName) + // The identity of snapshots ilustrates that execution through API and through full blown command leads to identical results + [Fact] public async void VerificationEngineSampleDogfoodTest() { @@ -33,10 +38,47 @@ public async void VerificationEngineSampleDogfoodTest() SnapshotsDirectory = "Snapshots", OutputDirectory = workingDir, VerifyCommandOutput = true, - DoNotPrependTemplateNameToScenarioName = true, + DoNotPrependCallerMethodNameToScenarioName = true, DoNotAppendTemplateArgsToScenarioName = true, + ScenarioName = "SampleDogfoodTest", + // This is here just for testing and documentation purposes - showing functionality of differing snapshots for arch + UniqueFor = UniqueForOption.Architecture, + } + .WithCustomScrubbers( + ScrubbersDefinition.Empty + .AddScrubber(sb => sb.Replace("B is enabled", "*******")) + .AddScrubber((path, content) => + { + if (path.Replace(Path.DirectorySeparatorChar, '/') == "std-streams/stdout.txt") + { + content.Replace("SampleTestTemplate", "%TEMPLATE%"); + } + })); + + VerificationEngine engine = new VerificationEngine(_log); + await engine.Execute(options); + } + + [Fact] + public async void VerificationEngineSampleDogfoodTest_ExecThroughApi() + { + string workingDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName().Replace(".", string.Empty)); + string templateShortName = "TestAssets.SampleTestTemplate"; + + //get the template location + string templateLocation = Path.Combine(TestTemplatesLocation, "TestTemplate"); + + TemplateVerifierOptions options = new TemplateVerifierOptions(templateName: templateShortName) + { + TemplatePath = templateLocation, + SnapshotsDirectory = "Snapshots", + OutputDirectory = workingDir, + VerifyCommandOutput = true, + DoNotPrependCallerMethodNameToScenarioName = true, + ScenarioName = "SampleDogfoodTest", UniqueFor = UniqueForOption.Architecture, } + .WithInstantiationThroughTemplateCreatorApi(new Dictionary() { { "paramB", "true" } }) .WithCustomScrubbers( ScrubbersDefinition.Empty .AddScrubber(sb => sb.Replace("B is enabled", "*******")) diff --git a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests.csproj b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests.csproj index 16f16898339..898e55c2212 100644 --- a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests.csproj +++ b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests.csproj @@ -9,6 +9,7 @@ + diff --git a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/VerificationEngineSampleDogfoodTest._.x64.verified/TestAssets.SampleTestTemplate/Test.cs b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/TestAssets.SampleTestTemplate.SampleDogfoodTest.x64.verified/TestAssets.SampleTestTemplate/Test.cs similarity index 100% rename from test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/VerificationEngineSampleDogfoodTest._.x64.verified/TestAssets.SampleTestTemplate/Test.cs rename to test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/TestAssets.SampleTestTemplate.SampleDogfoodTest.x64.verified/TestAssets.SampleTestTemplate/Test.cs diff --git a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/VerificationEngineSampleDogfoodTest._.x64.verified/std-streams/stderr.txt b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/TestAssets.SampleTestTemplate.SampleDogfoodTest.x64.verified/std-streams/stderr.txt similarity index 100% rename from test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/VerificationEngineSampleDogfoodTest._.x64.verified/std-streams/stderr.txt rename to test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/TestAssets.SampleTestTemplate.SampleDogfoodTest.x64.verified/std-streams/stderr.txt diff --git a/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/VerificationEngineSampleDogfoodTest._.x64.verified/std-streams/stdout.txt b/test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/TestAssets.SampleTestTemplate.SampleDogfoodTest.x64.verified/std-streams/stdout.txt similarity index 100% rename from test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/VerificationEngineSampleDogfoodTest._.x64.verified/std-streams/stdout.txt rename to test/Microsoft.TemplateEngine.Authoring.TemplateVerifier.IntegrationTests/Snapshots/TestAssets.SampleTestTemplate.SampleDogfoodTest.x64.verified/std-streams/stdout.txt diff --git a/test/Microsoft.TemplateEngine.TestHelper/EnvironmentSettingsHelper.cs b/test/Microsoft.TemplateEngine.TestHelper/EnvironmentSettingsHelper.cs index 411c10ffd57..d448c79b41b 100644 --- a/test/Microsoft.TemplateEngine.TestHelper/EnvironmentSettingsHelper.cs +++ b/test/Microsoft.TemplateEngine.TestHelper/EnvironmentSettingsHelper.cs @@ -38,16 +38,6 @@ public IEngineEnvironmentSettings CreateEnvironment( { locale = "en-US"; } - var builtIns = new List<(Type, IIdentifiedComponent)>(); - if (additionalComponents != null) - { - builtIns.AddRange(additionalComponents); - } - builtIns.AddRange(Edge.Components.AllComponents); - if (loadDefaultGenerator) - { - builtIns.AddRange(Orchestrator.RunnableProjects.Components.AllComponents); - } IEnumerable loggerProviders = new[] { new XunitLoggerProvider(_testOutputHelper) }; if (addLoggerProviders != null) diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/LocalizableStrings.Designer.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/LocalizableStrings.Designer.cs new file mode 100644 index 00000000000..e698d990009 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/LocalizableStrings.Designer.cs @@ -0,0 +1,126 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.TemplateEngine.Authoring.TemplateApiVerifier { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // 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.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class LocalizableStrings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal LocalizableStrings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.LocalizableStrings", typeof(LocalizableStrings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The template "{0}" was created successfully.. + /// + internal static string CreateSuccessful { + get { + return ResourceManager.GetString("CreateSuccessful", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}).. + /// + internal static string Error_ConfigDoesntExist { + get { + return ResourceManager.GetString("Error_ConfigDoesntExist", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Template configuration file could not be retrieved from configured mount point.. + /// + internal static string Error_ConfigRetrieval { + get { + return ResourceManager.GetString("Error_ConfigRetrieval", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'.. + /// + internal static string Error_DotnetPath { + get { + return ResourceManager.GetString("Error_DotnetPath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failed to install template: {0}, details: {1}.. + /// + internal static string Error_InstallFail { + get { + return ResourceManager.GetString("Error_InstallFail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No packages fetched after installation.. + /// + internal static string Error_NoPackages { + get { + return ResourceManager.GetString("Error_NoPackages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'.. + /// + internal static string Error_TemplateArgsDisalowed { + get { + return ResourceManager.GetString("Error_TemplateArgsDisalowed", resourceCulture); + } + } + } +} diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/LocalizableStrings.resx b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/LocalizableStrings.resx new file mode 100644 index 00000000000..ba0a4e6465e --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/LocalizableStrings.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.csproj b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.csproj new file mode 100644 index 00000000000..9502126703c --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.csproj @@ -0,0 +1,40 @@ + + + + Library + $(NETCoreTargetFramework) + The extension of templates verification engine enabling verification testing through dotnet template engine API. + false + enable + enable + true + true + + + + + + + + + + + + + + + + + True + True + LocalizableStrings.resx + + + + + + ResXFileCodeGenerator + LocalizableStrings.Designer.cs + + + diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/PublicAPI.Shipped.txt b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/PublicAPI.Shipped.txt new file mode 100644 index 00000000000..91b0e1a43b9 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/PublicAPI.Unshipped.txt b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/PublicAPI.Unshipped.txt new file mode 100644 index 00000000000..99d9cafb120 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.TemplateVerifierOptionsExtensions +static Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.TemplateVerifierOptionsExtensions.WithInstantiationThroughTemplateCreatorApi(this Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! options, Microsoft.TemplateEngine.Edge.Template.InputDataSet? inputDataSet) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! +static Microsoft.TemplateEngine.Authoring.TemplateApiVerifier.TemplateVerifierOptionsExtensions.WithInstantiationThroughTemplateCreatorApi(this Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! options, System.Collections.Generic.IReadOnlyDictionary? inputParameters) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/TemplateVerifierOptionsExtensions.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/TemplateVerifierOptionsExtensions.cs new file mode 100644 index 00000000000..d6b6527d038 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/TemplateVerifierOptionsExtensions.cs @@ -0,0 +1,164 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.TemplateEngine.Abstractions; +using Microsoft.TemplateEngine.Abstractions.Installer; +using Microsoft.TemplateEngine.Authoring.TemplateVerifier; +using Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands; +using Microsoft.TemplateEngine.Edge; +using Microsoft.TemplateEngine.Edge.Template; +using Microsoft.TemplateEngine.IDE; +using WellKnownSearchFilters = Microsoft.TemplateEngine.Utils.WellKnownSearchFilters; + +namespace Microsoft.TemplateEngine.Authoring.TemplateApiVerifier +{ + public static class TemplateVerifierOptionsExtensions + { + /// + /// Adds custom template instantiator that runs template instantiation in-proc via TemplateCreator API. + /// + /// + /// + /// + public static TemplateVerifierOptions WithInstantiationThroughTemplateCreatorApi( + this TemplateVerifierOptions options, + IReadOnlyDictionary? inputParameters) + { + return options.WithCustomInstatiation(async verifierOptions => await RunInstantiation(verifierOptions, inputParameters, null).ConfigureAwait(false)); + } + + /// + /// Adds custom template instantiator that runs template instantiation in-proc via TemplateCreator API. + /// + /// + /// + /// + public static TemplateVerifierOptions WithInstantiationThroughTemplateCreatorApi( + this TemplateVerifierOptions options, + InputDataSet? inputDataSet) + { + return options.WithCustomInstatiation(async verifierOptions => await RunInstantiation(verifierOptions, null, inputDataSet).ConfigureAwait(false)); + } + + private static async Task RunInstantiation( + TemplateVerifierOptions options, + IReadOnlyDictionary? inputParameters, + InputDataSet? inputDataSet) + { + if (!string.IsNullOrEmpty(options.DotnetExecutablePath)) + { + throw new TemplateVerificationException(LocalizableStrings.Error_DotnetPath, TemplateVerificationErrorCode.InvalidOption); + } + + if (options.TemplateSpecificArgs != null) + { + throw new TemplateVerificationException(LocalizableStrings.Error_TemplateArgsDisalowed, TemplateVerificationErrorCode.InvalidOption); + } + + // Create temp folder and instantiate there + string workingDir = options.OutputDirectory ?? Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (Directory.Exists(workingDir) && Directory.EnumerateFileSystemEntries(workingDir).Any()) + { + throw new TemplateVerificationException(TemplateVerifier.LocalizableStrings.VerificationEngine_Error_WorkDirExists, TemplateVerificationErrorCode.WorkingDirectoryExists); + } + + if (!ExtractParameter(inputParameters, inputDataSet, "name", out string? name) && + !ExtractParameter(inputParameters, inputDataSet, "n", out name)) + { + name = options.TemplateName; + } + + if (!ExtractParameter(inputParameters, inputDataSet, "output", out string? output) && + !ExtractParameter(inputParameters, inputDataSet, "o", out output)) + { + output = options.TemplateName; + } + + string outputPath = Path.Combine(workingDir, output!); + + var host = new DefaultTemplateEngineHost( + nameof(TemplateVerifierOptionsExtensions), + "1.0.0", + null, + new List<(Type, IIdentifiedComponent)>(), + Array.Empty()); + + var bootstrapper = new Bootstrapper( + host, + virtualizeConfiguration: string.IsNullOrEmpty(options.SettingsDirectory), + loadDefaultComponents: true, + hostSettingsLocation: options.SettingsDirectory, + environment: new VirtualEnvironment(options.Environment, true)); + + if (!string.IsNullOrEmpty(options.TemplatePath)) + { + await InstallTemplateAsync(bootstrapper, options.TemplatePath).ConfigureAwait(false); + } + + var foundTemplates = await bootstrapper.GetTemplatesAsync(new[] { WellKnownSearchFilters.NameFilter(options.TemplateName) }).ConfigureAwait(false); + + if (foundTemplates.Count == 0) + { + throw new TemplateVerificationException(LocalizableStrings.Error_NoPackages, TemplateVerificationErrorCode.InstallFailed); + } + + ITemplateInfo template = foundTemplates[0].Info; + + ITemplateCreationResult result = await + (inputDataSet != null + ? bootstrapper.CreateAsync( + info: template, + name: name, + inputParameters: inputDataSet, + outputPath: outputPath) + : bootstrapper.CreateAsync( + info: template, + name: name, + parameters: inputParameters ?? new Dictionary(), + outputPath: outputPath)).ConfigureAwait(false); + + return new CommandResultData( + (int)result.Status, + result.Status == CreationResultStatus.Success ? string.Format(LocalizableStrings.CreateSuccessful, result.TemplateFullName) : string.Empty, + result.ErrorMessage ?? string.Empty, + // We do not want to use result.OutputBaseDirectory as it points to the base of template + // not a working dir of command (which is one level up - as we explicitly specify output subdir, as if '-o' was passed) + workingDir); + } + + private static async Task InstallTemplateAsync(Bootstrapper bootstrapper, string template) + { + List installRequests = new List() { new InstallRequest(Path.GetFullPath(template)) }; + + IReadOnlyList installationResults = await bootstrapper.InstallTemplatePackagesAsync(installRequests).ConfigureAwait(false); + InstallResult? failedResult = installationResults.FirstOrDefault(result => !result.Success); + if (failedResult != null) + { + throw new TemplateVerificationException(string.Format("Failed to install template: {0}, details:{1}", failedResult.InstallRequest.PackageIdentifier, failedResult.ErrorMessage), TemplateVerificationErrorCode.InstallFailed); + } + } + + private static bool ExtractParameter( + IReadOnlyDictionary? inputParameters, + InputDataSet? inputDataSet, + string key, + out string? value) + { + value = null; + if ( + inputDataSet != null && + inputDataSet.ParameterDefinitionSet.TryGetValue(key, out ITemplateParameter parameter) && + inputDataSet.TryGetValue(parameter, out InputParameterData parameterValue) && + parameterValue.Value != null) + { + value = parameterValue.Value.ToString(); + } + else + { + inputParameters?.TryGetValue(key, out value); + } + + return !string.IsNullOrEmpty(value); + } + } +} diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.cs.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.cs.xlf new file mode 100644 index 00000000000..51204ffc6ee --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.cs.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.de.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.de.xlf new file mode 100644 index 00000000000..121034e9f01 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.de.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.es.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.es.xlf new file mode 100644 index 00000000000..9d95c92ee05 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.es.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.fr.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.fr.xlf new file mode 100644 index 00000000000..c6b590d155e --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.fr.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.it.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.it.xlf new file mode 100644 index 00000000000..10834bd85bd --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.it.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ja.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ja.xlf new file mode 100644 index 00000000000..9c27435af88 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ja.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ko.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ko.xlf new file mode 100644 index 00000000000..e2d3c82beea --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ko.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.pl.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.pl.xlf new file mode 100644 index 00000000000..4020eb9e563 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.pl.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.pt-BR.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.pt-BR.xlf new file mode 100644 index 00000000000..4a37404fe0d --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.pt-BR.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ru.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ru.xlf new file mode 100644 index 00000000000..3ae87bf670f --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.ru.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.tr.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.tr.xlf new file mode 100644 index 00000000000..1b6dc1397ba --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.tr.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.zh-Hans.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.zh-Hans.xlf new file mode 100644 index 00000000000..a04a4f9fe4c --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.zh-Hans.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.zh-Hant.xlf b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.zh-Hant.xlf new file mode 100644 index 00000000000..b47085285b0 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateApiVerifier/xlf/LocalizableStrings.zh-Hant.xlf @@ -0,0 +1,44 @@ + + + + + + The template "{0}" was created successfully. + The template "{0}" was created successfully. + {0} holds template name + + + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Template config: {0} doesn't exist. When using 'WithInstantiationThroughTemplateCreatorApi' the 'TemplatePath' parameter must specify path to the template.json or to the root of template (containing {1}). + Do not translate 'TemplatePath' and 'WithInstantiationThroughTemplateCreatorApi' + +{0} and {1} contain paths + + + Template configuration file could not be retrieved from configured mount point. + Template configuration file could not be retrieved from configured mount point. + + + + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + 'DotnetExecutablePath' parameter must not be specified when using 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'DotnetExecutablePath' and 'WithInstantiationThroughTemplateCreatorApi' + + + Failed to install template: {0}, details: {1}. + Failed to install template: {0}, details: {1}. + {0} is tamplate name, {1} is error message + + + No packages fetched after installation. + No packages fetched after installation. + + + + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + 'TemplateSpecificArgs' parameter must not be specified when using WithInstantiationThroughTemplateCreatorApi. Parameters should be passed via the argument of 'WithInstantiationThroughTemplateCreatorApi'. + Do not translate 'TemplateSpecificArgs' and 'WithInstantiationThroughTemplateCreatorApi' + + + + \ No newline at end of file diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/CommandResultData.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/CommandResultData.cs index 364b41f99f1..bbb5c2f99a2 100644 --- a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/CommandResultData.cs +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/CommandResultData.cs @@ -5,7 +5,7 @@ namespace Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands { - internal class CommandResultData + internal class CommandResultData : IInstantiationResult { public CommandResultData(int exitCode, string stdOut, string stdErr, string workingDirectory) { @@ -26,5 +26,7 @@ public CommandResultData(CommandResult commandResult) public string StdErr { get; } public string WorkingDirectory { get; } + + public string InstantiatedContentDirectory => WorkingDirectory; } } diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/IInstantiationResult.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/IInstantiationResult.cs new file mode 100644 index 00000000000..f5c710f7f52 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/IInstantiationResult.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands; + +/// +/// The result information of a template instantiation action. +/// +public interface IInstantiationResult +{ + /// + /// Exit code of the action (e.g. exit code of the dotnet new command). + /// 0 indicates successful action. Nonzero otherwise. + /// + int ExitCode { get; } + + /// + /// Standard output stream content for the instantiation action. + /// + string StdOut { get; } + + /// + /// Standard error stream content for the instantiation action. + /// + string StdErr { get; } + + /// + /// Path to directory containing the output of the instantiation. + /// + string InstantiatedContentDirectory { get; } +} diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/RunInstantiation.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/RunInstantiation.cs new file mode 100644 index 00000000000..ac4e327a879 --- /dev/null +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Commands/RunInstantiation.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands; + +/// +/// Runs the template instantiation (and installation if needed) based on given options. +/// +/// +/// +public delegate Task RunInstantiation(TemplateVerifierOptions options); diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Globals.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Globals.cs index 974d69b2b90..b90283829de 100644 --- a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Globals.cs +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/Globals.cs @@ -5,4 +5,5 @@ [assembly: InternalsVisibleTo("Microsoft.TemplateEngine.Authoring.CLI.IntegrationTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.TemplateEngine.Authoring.TemplateVerifier.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] +[assembly: InternalsVisibleTo("Microsoft.TemplateEngine.Authoring.TemplateApiVerifier, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/PublicAPI.Unshipped.txt b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/PublicAPI.Unshipped.txt index a6b0635c9d2..b57aff898c7 100644 --- a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/PublicAPI.Unshipped.txt +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/PublicAPI.Unshipped.txt @@ -1,4 +1,10 @@ -Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition +Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.IInstantiationResult +Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.IInstantiationResult.ExitCode.get -> int +Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.IInstantiationResult.InstantiatedContentDirectory.get -> string! +Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.IInstantiationResult.StdErr.get -> string! +Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.IInstantiationResult.StdOut.get -> string! +Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.RunInstantiation +Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition.AddScrubber(Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition.ScrubFileByPath! fileScrubber) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition! Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition.AddScrubber(System.Action! scrubber, string? extension = null) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition! Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition.ScrubbersDefinition(System.Action! scrubber, string? extension = null) -> void @@ -19,6 +25,7 @@ Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerificationExceptio Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerificationException.TemplateVerificationException(System.Runtime.Serialization.SerializationInfo! info, System.Runtime.Serialization.StreamingContext context) -> void Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.CustomDirectoryVerifier.get -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.VerifyDirectory? +Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.CustomInstatiation.get -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.RunInstantiation? Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.CustomScrubbers.get -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition? Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.DisableDefaultVerificationExcludePatterns.get -> bool Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.DisableDefaultVerificationExcludePatterns.init -> void @@ -62,6 +69,7 @@ Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.Veri Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.VerifyCommandOutput.init -> void Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.WithCustomDirectoryVerifier(Microsoft.TemplateEngine.Authoring.TemplateVerifier.VerifyDirectory! verifier) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.WithCustomEnvironment(System.Collections.Generic.IReadOnlyDictionary! environment) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! +Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.WithCustomInstatiation(Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands.RunInstantiation! instantiation) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.WithCustomScrubbers(Microsoft.TemplateEngine.Authoring.TemplateVerifier.ScrubbersDefinition! scrubbers) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions.WithEnvironmentVariable(string! name, string! value) -> Microsoft.TemplateEngine.Authoring.TemplateVerifier.TemplateVerifierOptions! Microsoft.TemplateEngine.Authoring.TemplateVerifier.UniqueForOption diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/TemplateVerifierOptions.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/TemplateVerifierOptions.cs index 7f8f409d0e3..e850fed68e6 100644 --- a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/TemplateVerifierOptions.cs +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/TemplateVerifierOptions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Extensions.Options; +using Microsoft.TemplateEngine.Authoring.TemplateVerifier.Commands; using Microsoft.TemplateEngine.Utils; namespace Microsoft.TemplateEngine.Authoring.TemplateVerifier @@ -131,6 +132,11 @@ public class TemplateVerifierOptions : IOptions /// public string? StandardOutputFileExtension { get; init; } + /// + /// Gets the delegate that performs custom generation of template output contents. + /// + public RunInstantiation? CustomInstatiation { get; private set; } + // Enable if too many underlying features are asked. // On the other hand if possible, we should wrap everyting and dfo not expose underlying technology to allow for change. // public Action VerifySettingsAdjustor { get; init; } @@ -187,5 +193,17 @@ public TemplateVerifierOptions WithCustomDirectoryVerifier(VerifyDirectory verif CustomDirectoryVerifier = verifier; return this; } + + /// + /// Adds custom template instantiator. + /// If custom template generator is provided it's responsible for proper instantiation of a template (as well as installation if needed) based on given options. + /// + /// + /// + public TemplateVerifierOptions WithCustomInstatiation(RunInstantiation instantiation) + { + CustomInstatiation = instantiation; + return this; + } } } diff --git a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/VerificationEngine.cs b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/VerificationEngine.cs index 969d63321a8..1f7364ba9c6 100644 --- a/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/VerificationEngine.cs +++ b/tools/Microsoft.TemplateEngine.Authoring.TemplateVerifier/VerificationEngine.cs @@ -76,7 +76,11 @@ public async Task Execute( TemplateVerifierOptions options = optionsAccessor.Value; - CommandResultData commandResult = RunDotnetNewCommand(options, _commandRunner, _loggerFactory, _logger); + RunInstantiation instantiate = + options.CustomInstatiation ?? + (verifierOptions => Task.FromResult(RunDotnetNewCommand(verifierOptions, _commandRunner, _loggerFactory, _logger))); + + IInstantiationResult commandResult = await instantiate(options).ConfigureAwait(false); if (options.IsCommandExpectedToFail) { @@ -112,13 +116,13 @@ public async Task Execute( await VerifyResult( options, commandResult, - new CallerInfo() { CallerMethod = callerMethod, CallerSourceFile = sourceFile, ContentDirectory = commandResult.WorkingDirectory }) + new CallerInfo() { CallerMethod = callerMethod, CallerSourceFile = sourceFile, ContentDirectory = commandResult.InstantiatedContentDirectory }) .ConfigureAwait(false); // if everything is successful - let's delete the created files (unless placed into explicitly requested dir) - if (string.IsNullOrEmpty(options.OutputDirectory) && _fileSystem.DirectoryExists(commandResult.WorkingDirectory)) + if (string.IsNullOrEmpty(options.OutputDirectory) && _fileSystem.DirectoryExists(commandResult.InstantiatedContentDirectory)) { - _fileSystem.DirectoryDelete(commandResult.WorkingDirectory, true); + _fileSystem.DirectoryDelete(commandResult.InstantiatedContentDirectory, true); } } @@ -281,7 +285,7 @@ private static string EncodeArgsAsPath(IEnumerable? args) return r.Replace(string.Join('#', args), string.Empty); } - private static CommandResultData RunDotnetNewCommand(TemplateVerifierOptions options, ICommandRunner commandRunner, ILoggerFactory? loggerFactory, ILogger logger) + private static IInstantiationResult RunDotnetNewCommand(TemplateVerifierOptions options, ICommandRunner commandRunner, ILoggerFactory? loggerFactory, ILogger logger) { // Create temp folder and instantiate there string workingDir = options.OutputDirectory ?? Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); @@ -416,7 +420,7 @@ private static void DummyMethod() } } - private async Task VerifyResult(TemplateVerifierOptions args, CommandResultData commandResultData, CallerInfo callerInfo) + private async Task VerifyResult(TemplateVerifierOptions args, IInstantiationResult commandResultData, CallerInfo callerInfo) { UsesVerifyAttribute a = new UsesVerifyAttribute(); // https://github.com/VerifyTests/Verify/blob/d8cbe38f527d6788ecadd6205c82803bec3cdfa6/src/Verify.Xunit/Verifier.cs#L10 @@ -427,7 +431,7 @@ private async Task VerifyResult(TemplateVerifierOptions args, CommandResultData if (args.VerifyCommandOutput) { - if (_fileSystem.DirectoryExists(Path.Combine(commandResultData.WorkingDirectory, SpecialFiles.StandardStreamsDir))) + if (_fileSystem.DirectoryExists(Path.Combine(commandResultData.InstantiatedContentDirectory, SpecialFiles.StandardStreamsDir))) { throw new TemplateVerificationException( string.Format( @@ -436,15 +440,15 @@ private async Task VerifyResult(TemplateVerifierOptions args, CommandResultData TemplateVerificationErrorCode.InternalError); } - _fileSystem.CreateDirectory(Path.Combine(commandResultData.WorkingDirectory, SpecialFiles.StandardStreamsDir)); + _fileSystem.CreateDirectory(Path.Combine(commandResultData.InstantiatedContentDirectory, SpecialFiles.StandardStreamsDir)); await _fileSystem.WriteAllTextAsync( - Path.Combine(commandResultData.WorkingDirectory, SpecialFiles.StandardStreamsDir, SpecialFiles.StdOut + (args.StandardOutputFileExtension ?? SpecialFiles.DefaultExtension)), + Path.Combine(commandResultData.InstantiatedContentDirectory, SpecialFiles.StandardStreamsDir, SpecialFiles.StdOut + (args.StandardOutputFileExtension ?? SpecialFiles.DefaultExtension)), commandResultData.StdOut) .ConfigureAwait(false); await _fileSystem.WriteAllTextAsync( - Path.Combine(commandResultData.WorkingDirectory, SpecialFiles.StandardStreamsDir, SpecialFiles.StdErr + (args.StandardOutputFileExtension ?? SpecialFiles.DefaultExtension)), + Path.Combine(commandResultData.InstantiatedContentDirectory, SpecialFiles.StandardStreamsDir, SpecialFiles.StdErr + (args.StandardOutputFileExtension ?? SpecialFiles.DefaultExtension)), commandResultData.StdErr) .ConfigureAwait(false); }