From 8f23c3b432ba9ba4f105cf35ea110bef143712e3 Mon Sep 17 00:00:00 2001 From: Joe Feser Date: Wed, 7 Aug 2024 19:13:21 -0500 Subject: [PATCH] feat(): format the files on the cmd line Signed-off-by: Joe Feser --- src/ApiGenerator/Generator/ApiGenerator.cs | 3 +- .../Generator/Razor/RazorGeneratorBase.cs | 3 + src/ApiGenerator/Program.cs | 90 ++++++++++++++++++- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/ApiGenerator/Generator/ApiGenerator.cs b/src/ApiGenerator/Generator/ApiGenerator.cs index 205d71467b..cfb5cbc629 100644 --- a/src/ApiGenerator/Generator/ApiGenerator.cs +++ b/src/ApiGenerator/Generator/ApiGenerator.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Dynamic; using System.IO; using System.Linq; using System.Threading; @@ -37,7 +36,6 @@ using ApiGenerator.Configuration; using ApiGenerator.Domain; using ApiGenerator.Domain.Code; -using ApiGenerator.Domain.Specification; using ApiGenerator.Generator.Razor; using NJsonSchema; using NSwag; @@ -49,6 +47,7 @@ namespace ApiGenerator.Generator public class ApiGenerator { public static List Warnings { get; private set; } = new(); + public static HashSet GeneratedFilePaths = []; public static async Task Generate(bool lowLevelOnly, RestApiSpec spec, CancellationToken token) { diff --git a/src/ApiGenerator/Generator/Razor/RazorGeneratorBase.cs b/src/ApiGenerator/Generator/Razor/RazorGeneratorBase.cs index b0ef460ee7..b242522af5 100644 --- a/src/ApiGenerator/Generator/Razor/RazorGeneratorBase.cs +++ b/src/ApiGenerator/Generator/Razor/RazorGeneratorBase.cs @@ -89,6 +89,9 @@ private static async Task WriteFormattedCsharpFile(string path, string contents) if (Directory.GetParent(path) is { Exists: false } dir) dir.Create(); + var directory = Directory.GetParent(path); + ApiGenerator.GeneratedFilePaths.Add($"{directory.FullName}\\"); //we must have a trailing slash + await File.WriteAllTextAsync(path, contents); } diff --git a/src/ApiGenerator/Program.cs b/src/ApiGenerator/Program.cs index 4a219ddf11..e310025447 100644 --- a/src/ApiGenerator/Program.cs +++ b/src/ApiGenerator/Program.cs @@ -27,6 +27,8 @@ */ using System; +using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -126,7 +128,8 @@ private static async Task Generate(bool download, string branch, bool inclu await RestSpecDownloader.DownloadAsync(downloadBranch, token); } - if (!generateCode) return 0; + if (!generateCode) + return 0; Console.WriteLine(); AnsiConsole.Write(new Rule("[b white on chartreuse4] Loading specification [/]").LeftJustified()); @@ -150,6 +153,8 @@ private static async Task Generate(bool download, string branch, bool inclu await Generator.ApiGenerator.Generate(lowLevelOnly, spec, token); + RunDotNetFormat(); + var warnings = Generator.ApiGenerator.Warnings; if (warnings.Count > 0) { @@ -164,9 +169,63 @@ private static async Task Generate(bool download, string branch, bool inclu return 0; } + private static void RunDotNetFormat() + { + var enviromentPath = System.Environment.GetEnvironmentVariable("PATH"); + var paths = enviromentPath.Split(';'); + var exePath = paths.Select(x => Path.Combine(x, "dotnet.exe")) + .Where(x => File.Exists(x)) + .FirstOrDefault(); + + Console.WriteLine(); + AnsiConsole.Write(new Rule("[b white on chartreuse4] Formatting Code using dotnet format [/]").LeftJustified()); + Console.WriteLine(); + + var rootPath = GetRootPath(typeof(Program).Assembly.Location); + + var relativeFolderList = new List(); + + foreach (var item in Generator.ApiGenerator.GeneratedFilePaths) + { + var relativePath = item.Replace(rootPath.FullName, string.Empty); + relativeFolderList.Add($".{relativePath.Replace("\\", "/")}"); + } + + var si = new System.Diagnostics.ProcessStartInfo + { + WorkingDirectory = rootPath.FullName, + FileName = "dotnet", + Arguments = "format -v diag --include " + string.Join(' ', relativeFolderList.Select(item => $"{item}")), + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + }; + + var process = System.Diagnostics.Process.Start(si); + + Console.WriteLine(); + Console.WriteLine($"Running dotnet format --include {string.Join(' ', relativeFolderList.Select(item => $"{item}"))} -v diag"); + + // hookup the eventhandlers to capture the data that is received + process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data); + process.ErrorDataReceived += (sender, args) => Console.WriteLine(args.Data); + + process.Start(); + + // start our event pumps + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + process.WaitForExit(); + Console.WriteLine(); + } + private static bool Ask(string question, bool defaultAnswer = true) { - if (!Interactive) return defaultAnswer; + if (!Interactive) + return defaultAnswer; var answer = "invalid"; var defaultResponse = defaultAnswer ? "y" : "n"; @@ -175,10 +234,35 @@ private static bool Ask(string question, bool defaultAnswer = true) { Console.Write($"{question}[y/N] (default {defaultResponse}): "); answer = Console.ReadLine()?.Trim().ToLowerInvariant(); - if (string.IsNullOrWhiteSpace(answer)) answer = defaultResponse; + if (string.IsNullOrWhiteSpace(answer)) + answer = defaultResponse; defaultAnswer = answer == "y"; } return defaultAnswer; } + + /// + /// Since we are most likely not running in the root of the project, we need to find the root path that contains the sln + /// + /// + /// + private static DirectoryInfo GetRootPath(string basePath) => RecursiveFindRoot(new FileInfo(basePath).Directory); + + private static DirectoryInfo RecursiveFindRoot(DirectoryInfo directory) + { + if (directory is null) + { + return null; + } + + var file = directory.GetFiles("*.sln").FirstOrDefault(item => item.Name.Equals("OpenSearch.sln", StringComparison.OrdinalIgnoreCase)); + + if (file is not null) + { + return directory; + } + + return RecursiveFindRoot(directory.Parent); + } } }