Skip to content

Commit

Permalink
feat(): format the files on the cmd line
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Feser <[email protected]>

# Conflicts:
#	src/ApiGenerator/Generator/Razor/RazorGeneratorBase.cs
  • Loading branch information
joefeser committed Aug 8, 2024
1 parent f3bae74 commit c45c05c
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 29 deletions.
3 changes: 1 addition & 2 deletions src/ApiGenerator/Generator/ApiGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ApiGenerator.Configuration;
using ApiGenerator.Domain;
using ApiGenerator.Domain.Code;
using ApiGenerator.Domain.Specification;
using ApiGenerator.Generator.Razor;
using NJsonSchema;
using NSwag;
Expand All @@ -49,6 +47,7 @@ namespace ApiGenerator.Generator
public class ApiGenerator
{
public static List<string> Warnings { get; private set; } = new();
public static HashSet<string> GeneratedFilePaths = [];

public static async Task Generate(bool lowLevelOnly, RestApiSpec spec, CancellationToken token)
{
Expand Down
54 changes: 30 additions & 24 deletions src/ApiGenerator/Generator/Razor/RazorGeneratorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
using System.Threading;
using System.Threading.Tasks;
using ApiGenerator.Domain;
using CSharpier;
using RazorLight;
using RazorLight.Generation;
using RazorLight.Razor;
Expand All @@ -44,22 +43,23 @@ public abstract class RazorGeneratorBase
{
private static readonly RazorLightEngine Engine = new RazorLightEngineBuilder()
.UseProject(new EmbeddedRazorProject(typeof(CodeTemplatePage<>).Assembly, "ApiGenerator.Views"))
.SetOperatingAssembly(typeof(CodeTemplatePage<>).Assembly)
.UseMemoryCachingProvider()
.EnableDebugMode()
.SetOperatingAssembly(typeof(CodeTemplatePage<>).Assembly)
.UseMemoryCachingProvider()
.EnableDebugMode()
.Build();

protected static async Task DoRazor<TModel>(TModel model, string viewLocation, string targetLocation, CancellationToken token)
{
try
{
token.ThrowIfCancellationRequested();
var generated = await Engine.CompileRenderAsync(viewLocation, model);
var generated = await Engine.CompileRenderAsync(viewLocation, model);
await WriteFormattedCsharpFile(targetLocation, generated);
}
catch (TemplateGenerationException e)
{
foreach (var d in e.Diagnostics) Console.WriteLine(d.GetMessage());
foreach (var d in e.Diagnostics)
Console.WriteLine(d.GetMessage());
throw;
}
}
Expand All @@ -69,31 +69,37 @@ protected async Task DoRazorDependantFiles<TModel>(
Func<TModel, string> identifier, Func<string, string> target,
CancellationToken token
)
{
using var c = pbar.Spawn(items.Count, "Generating namespaces", new ProgressBarOptions
{
ProgressCharacter = '─',
ForegroundColor = ConsoleColor.Yellow
});
foreach (var item in items)
{
var id = identifier(item);
var targetLocation = target(id);
await DoRazor(item, viewLocation, targetLocation, token);
c.Tick($"{Title}: {id}");
}
}
{
using var c = pbar.Spawn(items.Count, "Generating namespaces", new ProgressBarOptions
{
ProgressCharacter = '─',
ForegroundColor = ConsoleColor.Yellow
});
foreach (var item in items)
{
var id = identifier(item);
var targetLocation = target(id);
await DoRazor(item, viewLocation, targetLocation, token);
c.Tick($"{Title}: {id}");
}
}

private static async Task WriteFormattedCsharpFile(string path, string contents)
{
contents = (await CodeFormatter.FormatAsync(contents)).Code;
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

if (Directory.GetParent(path) is { Exists: false } dir) dir.Create();
await File.WriteAllTextAsync(path, contents);
}

await File.WriteAllTextAsync(path, contents);
public abstract string Title
{
get;
}

public abstract string Title { get; }
public abstract Task Generate(RestApiSpec spec, ProgressBar progressBar, CancellationToken token);
}
}
90 changes: 87 additions & 3 deletions src/ApiGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -126,7 +128,8 @@ private static async Task<int> 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());
Expand All @@ -150,6 +153,8 @@ private static async Task<int> Generate(bool download, string branch, bool inclu

await Generator.ApiGenerator.Generate(lowLevelOnly, spec, token);

RunDotNetFormat();

var warnings = Generator.ApiGenerator.Warnings;
if (warnings.Count > 0)
{
Expand All @@ -164,9 +169,63 @@ private static async Task<int> 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<string>();

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";
Expand All @@ -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;
}

/// <summary>
/// Since we are most likely not running in the root of the project, we need to find the root path that contains the sln
/// </summary>
/// <param name="basePath"></param>
/// <returns></returns>
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);
}
}
}

0 comments on commit c45c05c

Please sign in to comment.