Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry pick [Extend Templates testing framework to test through API] to release/7.0.2xx #5766

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Microsoft.TemplateEngine.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -470,6 +472,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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -508,6 +522,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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6EA1A508-6033-4538-BF98-7F71B4E297AD}
Expand Down
36 changes: 22 additions & 14 deletions src/Microsoft.TemplateEngine.Edge/DefaultEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,20 @@ namespace Microsoft.TemplateEngine.Edge
{
/// <summary>
/// Default implementation of <see cref="IEnvironment"/>.
/// Gets environment variables from <see cref="System.Environment"/>.
/// Gets environment variables from <see cref="Environment"/>.
/// </summary>
public sealed class DefaultEnvironment : IEnvironment
public class DefaultEnvironment : IEnvironment
{
private const int DefaultBufferWidth = 160;
private readonly IReadOnlyDictionary<string, string> _environmentVariables;

public DefaultEnvironment()
{
Dictionary<string, string> variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
IDictionary env = System.Environment.GetEnvironmentVariables();
public DefaultEnvironment() : this(FetchEnvironmentVariables())
{ }

foreach (string key in env.Keys.OfType<string>())
{
variables[key] = (env[key] as string) ?? string.Empty;
}

_environmentVariables = variables;
NewLine = System.Environment.NewLine;
protected DefaultEnvironment(IReadOnlyDictionary<string, string> environmentVariables)
{
_environmentVariables = environmentVariables;
NewLine = Environment.NewLine;
}

/// <inheritdoc/>
Expand All @@ -43,7 +38,7 @@ public DefaultEnvironment()
/// <inheritdoc/>
public string ExpandEnvironmentVariables(string name)
{
return System.Environment.ExpandEnvironmentVariables(name);
return Environment.ExpandEnvironmentVariables(name);
}

/// <inheritdoc/>
Expand All @@ -58,5 +53,18 @@ public IReadOnlyDictionary<string, string> GetEnvironmentVariables()
{
return _environmentVariables;
}

protected static IReadOnlyDictionary<string, string> FetchEnvironmentVariables()
{
Dictionary<string, string> variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
IDictionary env = Environment.GetEnvironmentVariables();

foreach (string key in env.Keys.OfType<string>())
{
variables[key] = (env[key] as string) ?? string.Empty;
}

return variables;
}
}
}
5 changes: 4 additions & 1 deletion src/Microsoft.TemplateEngine.Edge/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@

Microsoft.TemplateEngine.Edge.DefaultEnvironment.DefaultEnvironment(System.Collections.Generic.IReadOnlyDictionary<string!, string!>! environmentVariables) -> void
Microsoft.TemplateEngine.Edge.VirtualEnvironment
Microsoft.TemplateEngine.Edge.VirtualEnvironment.VirtualEnvironment(System.Collections.Generic.IReadOnlyDictionary<string!, string!>? virtualEnvironemnt, bool includeRealEnvironment) -> void
static Microsoft.TemplateEngine.Edge.DefaultEnvironment.FetchEnvironmentVariables() -> System.Collections.Generic.IReadOnlyDictionary<string!, string!>!
44 changes: 44 additions & 0 deletions src/Microsoft.TemplateEngine.Edge/VirtualEnvironment.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Virtualized implementation of <see cref="IEnvironment"/>.
/// Allows to overwrite and/or add environment variables not defined in physical environment.
/// </summary>
public class VirtualEnvironment : DefaultEnvironment
{
/// <summary>
/// Creates new instance of <see cref="VirtualEnvironment"/>.
/// </summary>
/// <param name="virtualEnvironemnt">Variables to be considered as environment variables. They have precedence over physical environment variables.</param>
/// <param name="includeRealEnvironment">If set to true - variables from <see cref="Environment"/> are added.</param>
public VirtualEnvironment(IReadOnlyDictionary<string, string>? virtualEnvironemnt, bool includeRealEnvironment)
: base(MergeEnvironmentVariables(virtualEnvironemnt, includeRealEnvironment))
{ }

private static IReadOnlyDictionary<string, string> MergeEnvironmentVariables(
IReadOnlyDictionary<string, string>? virtualEnvironemnt, bool includeRealEnvironment)
{
Dictionary<string, string> variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

if (includeRealEnvironment)
{
variables.Merge(FetchEnvironmentVariables());
}

if (virtualEnvironemnt != null)
{
variables.Merge(virtualEnvironemnt);
}

return variables;
}
}
}
60 changes: 51 additions & 9 deletions src/Microsoft.TemplateEngine.IDE/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@
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
{
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;

/// <summary>
Expand All @@ -35,19 +37,25 @@ public class Bootstrapper : IDisposable
/// <param name="loadDefaultComponents">if true, the default components (providers, installers, generator) will be loaded. Same as calling <see cref="LoadDefaultComponents()"/> after instance is created.</param>
/// <param name="hostSettingsLocation">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.</param>
public Bootstrapper(ITemplateEngineHost host, bool virtualizeConfiguration, bool loadDefaultComponents = true, string? hostSettingsLocation = null)
/// <param name="environment">optional environment to be used (defaults to <see cref="DefaultEnvironment"/>).</param>
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,
Expand All @@ -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();
Expand All @@ -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);
}
Expand Down Expand Up @@ -103,7 +111,7 @@ public Task<IReadOnlyList<ITemplateInfo>> GetTemplatesAsync(CancellationToken ca
/// <summary>
/// Gets list of available templates, if <paramref name="filters"/> is provided returns only matching templates.
/// </summary>
/// <param name="filters">List of filters to apply. See <see cref="WellKnownSearchFilters"/> for predefined filters.</param>
/// <param name="filters">List of filters to apply. See <see cref="Utils.WellKnownSearchFilters"/> for predefined filters.</param>
/// <param name="exactMatchesOnly">
/// true: templates should match all filters; false: templates should match any filter.
/// </param>
Expand Down Expand Up @@ -158,6 +166,40 @@ public Task<ITemplateCreationResult> CreateAsync(
cancellationToken: cancellationToken);
}

/// <summary>
/// Instantiates the template.
/// </summary>
/// <param name="info">The template to instantiate.</param>
/// <param name="name">The name to use.</param>
/// <param name="outputPath">The output directory for template instantiation.</param>
/// <param name="inputParameters">The template parameters.</param>
/// <param name="baselineName">The baseline configuration to use.</param>
/// <param name="cancellationToken">A cancellation token to cancel the asynchronous operation.</param>
/// <returns><see cref="ITemplateCreationResult"/> containing information on created template or error occurred.</returns>
#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<ITemplateCreationResult> 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);
}

/// <summary>
/// Dry runs the template with given parameters.
/// </summary>
Expand Down
1 change: 0 additions & 1 deletion src/Microsoft.TemplateEngine.IDE/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ Microsoft.TemplateEngine.IDE.Bootstrapper.Uninstall(string! path) -> System.Coll
Microsoft.TemplateEngine.IDE.Bootstrapper.Uninstall(System.Collections.Generic.IEnumerable<string!>! paths) -> System.Collections.Generic.IEnumerable<string!>!
Microsoft.TemplateEngine.IDE.Bootstrapper.UninstallTemplatePackagesAsync(System.Collections.Generic.IEnumerable<Microsoft.TemplateEngine.Abstractions.TemplatePackage.IManagedTemplatePackage!>! managedPackages, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Microsoft.TemplateEngine.Abstractions.Installer.UninstallResult!>!>!
Microsoft.TemplateEngine.IDE.Bootstrapper.UpdateTemplatePackagesAsync(System.Collections.Generic.IEnumerable<Microsoft.TemplateEngine.Abstractions.Installer.UpdateRequest!>! updateRequests, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Microsoft.TemplateEngine.Abstractions.Installer.UpdateResult!>!>!
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<System.Collections.Generic.IReadOnlyList<Microsoft.TemplateEngine.Abstractions.TemplatePackage.IManagedTemplatePackage!>!>!
Microsoft.TemplateEngine.IDE.Bootstrapper.GetTemplatePackagesAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Microsoft.TemplateEngine.Abstractions.TemplatePackage.ITemplatePackage!>!>!
Microsoft.TemplateEngine.IDE.Bootstrapper.GetTemplatesAsync(System.Collections.Generic.IEnumerable<System.Func<Microsoft.TemplateEngine.Abstractions.ITemplateInfo!, Microsoft.TemplateEngine.Abstractions.TemplateFiltering.MatchInfo?>!>! filters, bool exactMatchesOnly = true, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<Microsoft.TemplateEngine.Abstractions.TemplateFiltering.ITemplateMatchInfo!>!>!
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.TemplateEngine.IDE/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@

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<Microsoft.TemplateEngine.Edge.Template.ITemplateCreationResult!>!
Loading