| File: Templating\TemplateEngineHost.cs | Web Access |
| Project: src\src\Aspire.Cli\Aspire.Cli.csproj (aspire) |
// 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.PhysicalFileSystem; using Microsoft.TemplateEngine.Utils; namespace Aspire.Cli.Templating; internal sealed class TemplateEngineHost(IReadOnlyList<(Type InterfaceType, IIdentifiedComponent Instance)> components) : Microsoft.TemplateEngine.Edge.DefaultTemplateEngineHost("aspirecli", "1.0.0", builtIns: components, fallbackHostTemplateConfigNames: ["dotnetcli"]), ITemplateEngineHost { // Filter the source view rather than copying or modifying a user's checkout. // A .git entry can be a directory or a worktree/submodule pointer file. private IPhysicalFileSystem _fileSystem = new GitMetadataExcludingFileSystem(new PhysicalFileSystem()); IPhysicalFileSystem ITemplateEngineHost.FileSystem => _fileSystem; void ITemplateEngineHost.VirtualizeDirectory(string path) { _fileSystem = new InMemoryFileSystem(path, _fileSystem); } private sealed class GitMetadataExcludingFileSystem(IPhysicalFileSystem inner) : IPhysicalFileSystem { public bool DirectoryExists(string directory) => !IsGitMetadata(directory) && inner.DirectoryExists(directory); public bool FileExists(string file) => !IsGitMetadata(file) && inner.FileExists(file); public Stream CreateFile(string path) => inner.CreateFile(path); public void CreateDirectory(string path) => inner.CreateDirectory(path); public string GetCurrentDirectory() => inner.GetCurrentDirectory(); public void FileCopy(string sourcePath, string targetPath, bool overwrite) => inner.FileCopy(ReadablePath(sourcePath), targetPath, overwrite); public void DirectoryDelete(string path, bool recursive) => inner.DirectoryDelete(path, recursive); public string ReadAllText(string path) => inner.ReadAllText(ReadablePath(path)); public byte[] ReadAllBytes(string path) => inner.ReadAllBytes(ReadablePath(path)); public void WriteAllText(string path, string value) => inner.WriteAllText(path, value); public Stream OpenRead(string path) => inner.OpenRead(ReadablePath(path)); public void FileDelete(string path) => inner.FileDelete(path); public FileAttributes GetFileAttributes(string file) => inner.GetFileAttributes(ReadablePath(file)); public void SetFileAttributes(string file, FileAttributes attributes) => inner.SetFileAttributes(file, attributes); public IDisposable WatchFileChanges(string filePath, FileSystemEventHandler fileChanged) => inner.WatchFileChanges(filePath, fileChanged); public DateTime GetLastWriteTimeUtc(string file) => inner.GetLastWriteTimeUtc(ReadablePath(file)); public void SetLastWriteTimeUtc(string file, DateTime lastWriteTimeUtc) => inner.SetLastWriteTimeUtc(file, lastWriteTimeUtc); public string PathRelativeTo(string target, string relativeTo) => inner.PathRelativeTo(target, relativeTo); public IEnumerable<string> EnumerateFileSystemEntries(string path, string pattern, SearchOption searchOption) => Enumerate(path, pattern, searchOption, inner.EnumerateFileSystemEntries); public IEnumerable<string> EnumerateDirectories(string path, string pattern, SearchOption searchOption) => Enumerate(path, pattern, searchOption, inner.EnumerateDirectories); public IEnumerable<string> EnumerateFiles(string path, string pattern, SearchOption searchOption) => Enumerate(path, pattern, searchOption, inner.EnumerateFiles); private IEnumerable<string> Enumerate( string path, string pattern, SearchOption searchOption, Func<string, string, SearchOption, IEnumerable<string>> enumerate) { if (IsGitMetadata(path)) { yield break; } foreach (var entry in enumerate(path, pattern, SearchOption.TopDirectoryOnly)) { if (!IsGitMetadata(entry)) { yield return entry; } } if (searchOption == SearchOption.AllDirectories) { foreach (var directory in EnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly)) { foreach (var entry in Enumerate(directory, pattern, searchOption, enumerate)) { yield return entry; } } } } private static bool IsGitMetadata(string path) => path.Split([Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar]) .Any(segment => string.Equals(segment, ".git", StringComparison.OrdinalIgnoreCase)); private static string ReadablePath(string path) => IsGitMetadata(path) ? throw new FileNotFoundException(null, path) : path; } }