| File: PostActionProcessors\PostActionProcessorBase.cs | Web Access |
| Project: src\sdk\src\Cli\Microsoft.TemplateEngine.Cli\Microsoft.TemplateEngine.Cli.csproj (Microsoft.TemplateEngine.Cli) |
// 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.Utils; using System.Text.Json; using System.Text.Json.Nodes; namespace Microsoft.TemplateEngine.Cli.PostActionProcessors { public abstract class PostActionProcessorBase : IPostActionProcessor { public abstract Guid Id { get; } public bool Process( IEngineEnvironmentSettings environment, IPostAction action, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath) { if (string.IsNullOrWhiteSpace(outputBasePath)) { throw new ArgumentException($"'{nameof(outputBasePath)}' cannot be null or whitespace.", nameof(outputBasePath)); } outputBasePath = Path.GetFullPath(outputBasePath); return ProcessInternal(environment, action, creationEffects, templateCreationResult, outputBasePath); } /// <summary> /// Gets absolute normalized path for a target matching <paramref name="sourcePathGlob"/>. /// </summary> protected static IReadOnlyList<string> GetTargetForSource(ICreationEffects2 creationEffects, string sourcePathGlob, string outputBasePath) { Glob g = Glob.Parse(sourcePathGlob); List<string> results = new(); if (creationEffects.FileChanges != null) { foreach (IFileChange2 change in creationEffects.FileChanges) { if (g.IsMatch(change.SourceRelativePath)) { results.Add(Path.GetFullPath(change.TargetRelativePath, outputBasePath)); } } } return results; } protected static IReadOnlyList<string> GetConfiguredFiles( IReadOnlyDictionary<string, string> postActionArgs, ICreationEffects creationEffects, string argName, string outputBasePath, Func<string, bool>? matchCriteria = null) { if (creationEffects is not ICreationEffects2 creationEffects2) { return new List<string>(); } if (!postActionArgs.TryGetValue(argName, out string? targetFiles)) { return new List<string>(); } if (string.IsNullOrWhiteSpace(targetFiles)) { return new List<string>(); } if (TryParseAsJson(targetFiles, out IReadOnlyList<string> paths)) { return ProcessPaths(paths); } return ProcessPaths(targetFiles.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); IReadOnlyList<string> ProcessPaths(IReadOnlyList<string> paths) { matchCriteria ??= p => true; return paths .SelectMany(t => GetTargetForSource(creationEffects2, t, outputBasePath)) .Where(t => matchCriteria(t)) .ToArray(); } } protected static IReadOnlyList<string>? GetTargetFilesPaths( IReadOnlyDictionary<string, string> postActionArgs, string outputBasePath) { postActionArgs.TryGetValue("targetFiles", out string? targetFiles); if (string.IsNullOrWhiteSpace(targetFiles)) { return null; } // try to parse the argument as json; if it is not valid json, use it as a string if (TryParseAsJson(targetFiles, out IReadOnlyList<string> paths)) { return GetFullPaths(paths); } return GetFullPaths(targetFiles.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); IReadOnlyList<string> GetFullPaths(IEnumerable<string> paths) { var fullPaths = paths .Select(p => Path.GetFullPath(p, outputBasePath)) .ToList(); return fullPaths.AsReadOnly(); } } protected abstract bool ProcessInternal( IEngineEnvironmentSettings environment, IPostAction action, ICreationEffects creationEffects, ICreationResult templateCreationResult, string outputBasePath); private static bool TryParseAsJson(string targetFiles, out IReadOnlyList<string> paths) { paths = new List<string>(); targetFiles.TryParse(out JsonNode? config); if (config is null) { return false; } if (config.GetValueKind() == JsonValueKind.String) { paths = config.GetValue<string>().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); return true; } if (config is not JsonArray arr) { return false; } var parts = arr .Where(token => token != null && token.GetValueKind() == JsonValueKind.String) .Select(token => token!.GetValue<string>()).ToList(); if (parts.Count == 0) { return false; } paths = parts.AsReadOnly(); return true; } } }