| File: Constraints\HostConstraint.cs | Web Access |
| Project: src\sdk\src\TemplateEngine\Microsoft.TemplateEngine.Edge\Microsoft.TemplateEngine.Edge.csproj (Microsoft.TemplateEngine.Edge) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json.Nodes; using Microsoft.TemplateEngine.Abstractions; using Microsoft.TemplateEngine.Abstractions.Constraints; using Microsoft.TemplateEngine.Utils; namespace Microsoft.TemplateEngine.Edge.Constraints { public sealed class HostConstraintFactory : ITemplateConstraintFactory { Guid IIdentifiedComponent.Id { get; } = Guid.Parse("{93721B30-6890-403F-BAE7-5925990865A2}"); string ITemplateConstraintFactory.Type => "host"; Task<ITemplateConstraint> ITemplateConstraintFactory.CreateTemplateConstraintAsync(IEngineEnvironmentSettings environmentSettings, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); return Task.FromResult((ITemplateConstraint)new HostConstraint(environmentSettings, this)); } internal class HostConstraint : ConstraintBase { internal HostConstraint(IEngineEnvironmentSettings environmentSettings, ITemplateConstraintFactory factory) : base(environmentSettings, factory) { } public override string DisplayName => LocalizableStrings.HostConstraint_Name; protected override TemplateConstraintResult EvaluateInternal(string? args) { IReadOnlyList<HostInformation> supportedHosts = ParseArgs(args).ToList(); //check primary host name first bool primaryHostNameMatch = false; foreach (HostInformation hostInfo in supportedHosts.Where(h => h.HostName.Equals(EnvironmentSettings.Host.HostIdentifier, StringComparison.OrdinalIgnoreCase))) { primaryHostNameMatch = true; if (hostInfo.Version == null || hostInfo.Version.CheckIfVersionIsValid(EnvironmentSettings.Host.Version)) { return TemplateConstraintResult.CreateAllowed(this); } } if (!primaryHostNameMatch) { //if there is no primary host name, check fallback host names foreach (HostInformation hostInfo in supportedHosts.Where(h => EnvironmentSettings.Host.FallbackHostTemplateConfigNames.Contains(h.HostName, StringComparer.OrdinalIgnoreCase))) { if (hostInfo.Version == null || hostInfo.Version.CheckIfVersionIsValid(EnvironmentSettings.Host.Version)) { return TemplateConstraintResult.CreateAllowed(this); } } } string errorMessage = string.Format(LocalizableStrings.HostConstraint_Message_Restricted, EnvironmentSettings.Host.HostIdentifier, EnvironmentSettings.Host.Version, supportedHosts.ToCsvString()); return TemplateConstraintResult.CreateRestricted(this, errorMessage); } // configuration examples // "args": [ // { // "hostName": "dotnetcli", // "version": "5.0.100" // }, // { // "hostName": "ide", // "version": "[16.0-*]" // }] private static IEnumerable<HostInformation> ParseArgs(string? args) { List<HostInformation> hostInformation = new List<HostInformation>(); foreach (JsonObject jObj in args.ParseArrayOfConstraintJObjects()) { string? hostName = jObj.ToString("hostname"); string? version = jObj.ToString("version"); if (string.IsNullOrWhiteSpace(hostName)) { throw new ConfigurationException(string.Format(LocalizableStrings.HostConstraint_Error_MissingMandatoryProperty, jObj, "hostname")); } if (string.IsNullOrWhiteSpace(version)) { hostInformation.Add(new HostInformation(hostName!)); continue; } hostInformation.Add(new HostInformation(hostName!, version!.ParseVersionSpecification())); } return hostInformation; } private class HostInformation { public HostInformation(string host, IVersionSpecification? version = null) { if (string.IsNullOrWhiteSpace(host)) { throw new ArgumentException($"'{nameof(host)}' cannot be null or whitespace.", nameof(host)); } HostName = host; Version = version; } public string HostName { get; } public IVersionSpecification? Version { get; } public override string ToString() { return Version == null ? HostName : $"{HostName}({Version})"; } } } } }