| File: Constraints\ConstraintsExtensions.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; using System.Text.Json.Nodes; using Microsoft.TemplateEngine.Utils; namespace Microsoft.TemplateEngine.Edge.Constraints { internal static class Extensions { /// <summary> /// Attempts to parse input configuration string (presumably string or json array of strings) into enumeration of strings. /// </summary> /// <param name="args">Input configuration string.</param> /// <returns>Enumeration of parsed tokens.</returns> /// <exception cref="ConfigurationException">Thrown on unexpected input - not a valid json string or array of string or an empty array.</exception> public static IEnumerable<string> ParseArrayOfConstraintStrings(this string? args) { JsonNode token = ParseConstraintJsonNode(args); if (token.GetValueKind() == JsonValueKind.String) { return new[] { token.GetValue<string>() ?? throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args)) }; } JsonArray array = token.ToConstraintsJsonArray(args, true); return array.Select(value => { if (value == null || value.GetValueKind() != JsonValueKind.String) { throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args)); } string? strValue = value.GetValue<string>(); if (string.IsNullOrEmpty(strValue)) { throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArgumentHasEmptyString, args)); } return strValue!; }); } /// <summary> /// Attempts to parse input configuration string (presumably string or json array of strings) into enumeration of JObjects. /// </summary> /// <param name="args">Input configuration string.</param> /// <returns>Enumeration of parsed JObject tokens.</returns> /// <exception cref="ConfigurationException">Thrown on unexpected input - not a valid json array or an empty array.</exception> public static IEnumerable<JsonObject> ParseArrayOfConstraintJObjects(this string? args) { JsonNode token = ParseConstraintJsonNode(args); JsonArray array = token.ToConstraintsJsonArray(args, false); return array.Select(value => { if (value is not JsonObject jObj) { throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidJsonArray_Objects, args)); } return jObj; }); } /// <summary> /// Attempts to parse given string and return the version specification (throws <see cref="ConfigurationException"/> if unsuccessful). /// checks version in the following order: /// NuGet exact version /// NuGet floating version /// NuGet version range /// Legacy template engine exact version /// Legacy template engine version range. /// </summary> /// <param name="versionString">Version string to be parsed.</param> /// <returns>IVersionSpecification instance representing the given string representation of the version.</returns> /// <exception cref="ConfigurationException">Thrown if given string is not recognized as any valid version format.</exception> public static IVersionSpecification ParseVersionSpecification(this string versionString) { IVersionSpecification? versionInstance = null; if (NuGetVersionSpecification.TryParse(versionString, out NuGetVersionSpecification? exactNuGetVersion)) { versionInstance = exactNuGetVersion; } else if (NuGetFloatRangeSpecification.TryParse(versionString, out NuGetFloatRangeSpecification? floatVersion)) { versionInstance = floatVersion; } else if (NuGetVersionRangeSpecification.TryParse(versionString, out NuGetVersionRangeSpecification? rangeNuGetVersion)) { versionInstance = rangeNuGetVersion; } else if (ExactVersionSpecification.TryParse(versionString, out IVersionSpecification? exactVersion)) { versionInstance = exactVersion; } else if (RangeVersionSpecification.TryParse(versionString, out IVersionSpecification? rangeVersion)) { versionInstance = rangeVersion; } if (versionInstance == null) { throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidVersion, versionString)); } return versionInstance; } private static JsonNode ParseConstraintJsonNode(this string? args) { if (string.IsNullOrWhiteSpace(args)) { throw new ConfigurationException(LocalizableStrings.Constraint_Error_ArgumentsNotSpecified); } JsonNode? token; try { token = JsonNode.Parse(args!); } catch (Exception e) { throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidJson, args), e); } return token ?? throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_InvalidJson, args)); } private static JsonArray ToConstraintsJsonArray(this JsonNode token, string? args, bool isStringTypeAllowed) { if (token is not JsonArray array) { throw new ConfigurationException(string.Format( isStringTypeAllowed ? LocalizableStrings.Constraint_Error_InvalidJsonType_StringOrArray : LocalizableStrings.Constraint_Error_InvalidJsonType_Array, args)); } if (array.Count == 0) { throw new ConfigurationException(string.Format(LocalizableStrings.Constraint_Error_ArrayHasNoObjects, args)); } return array; } } }