From 700dc715fb6a130087959847946783ce4bfa0209 Mon Sep 17 00:00:00 2001 From: Robert Morrison Date: Sat, 3 Jan 2026 04:00:54 +0000 Subject: [PATCH] chore(dependencies): Upgrade dependencies This commit brings the dependencies up to date. This more importantly brings the stable version of system.commandline and all the changes needed to make it work properly with the program. Importantly this changes how validation is done, and how defaults are passed to commandline. This also allows me to remove the original null protection as when the argument is not specified commandline defaults to the current directory. This has also meant I can remove unnecessary async calls that appear to have no performance benefits, and remove some null checking that isn't needed any more. --- Program.cs | 91 ++++++++++++++++++++---------------------------- csSiteGen.csproj | 10 +++--- 2 files changed, 42 insertions(+), 59 deletions(-) diff --git a/Program.cs b/Program.cs index 0da168c..d3dc83e 100644 --- a/Program.cs +++ b/Program.cs @@ -17,8 +17,6 @@ */ using Serilog; -using System.CommandLine.Builder; -using System.CommandLine.Parsing; using System.CommandLine; using System.Diagnostics; using System.Reflection; @@ -66,70 +64,59 @@ class Program Stopwatch TotalExecutionTime = Stopwatch.StartNew(); - /* !! IMPORTANT !! - WARN: - This code uses system.commandline which is still in pre-release + /* WARN: + This code uses system.commandline the following section of code will contain comments to explain the intent of the programmer which may be useful if system.commandline has breaking changes */ // First the option for the project directory is created - var ProjectDirectoryOption = new Option( - name: "--project", - description: "The Directory for the project"); - ProjectDirectoryOption.IsRequired = false; // it is not required as not providing it infers that the current directory is the project directory - // If the option is used then the input is validated before control passes to any of the actual code. - ProjectDirectoryOption.AddValidator(result => + Option ProjectDirectoryOption = new("--project","-p") + { + Description = "The directory of the project", + Required = false, + DefaultValueFactory = _ => { - if (!result.GetValueForOption(ProjectDirectoryOption)!.Exists) - { - result.ErrorMessage = $"Project directory {result.GetValueForOption(ProjectDirectoryOption)} does not exist."; - } + return new DirectoryInfo(Directory.GetCurrentDirectory()); } - ); + }; + + // Add a validator as we want the directory to exist. + ProjectDirectoryOption.Validators.Add(result => + { + if (! result.GetValue(ProjectDirectoryOption)!.Exists) + { + result.AddError($"Directory {result.GetValue(ProjectDirectoryOption)} does not exist"); + Log.Fatal($"Passed directory '{result.GetValue(ProjectDirectoryOption)}' does not exist"); + } + }); // The root command is the entry point for commandline but otherwise does nothing. - var rootCommand = new RootCommand("csSiteGen"); - - - // TODO: Verify if the use of async in these functions is necessary + RootCommand rootCommand = new("csSiteGen"); // This creates the command for cleaning a projects output directory. var cleanCommand = new Command("clean", "Clean the projects output directory"); - cleanCommand.AddOption(ProjectDirectoryOption); // This command can use the project directory option we created earlier - cleanCommand.SetHandler(async (ProjectDirectory) => + cleanCommand.Options.Add(ProjectDirectoryOption); // This command can use the project directory option we created earlier + cleanCommand.SetAction(parseResult => { - await Task.Run(() => - { - Clean(ProjectDirectory); - }); - },ProjectDirectoryOption); + Clean(parseResult.GetValue("--project")!); + }); // This creates the command for actually converting the project. var convertCommand = new Command("convert", "Convert the projects input directory and place the files in the output directory."); - convertCommand.AddOption(ProjectDirectoryOption); // This command can use the project directory option - convertCommand.SetHandler(async (ProjectDirectory) => + convertCommand.Options.Add(ProjectDirectoryOption); // This command can use the project directory option + convertCommand.SetAction(parseResult => { - await Task.Run(() => - { - Convert(ProjectDirectory); - }); - },ProjectDirectoryOption); + Convert(parseResult.GetValue("--project")!); + }); // Adding the commands to the root command makes them actually callable on the commandline - rootCommand.AddCommand(cleanCommand); - rootCommand.AddCommand(convertCommand); - - // The parser is what actually handles the arguments and dispatches them to the appropriate commands. - // This is used instead of the simpler method of just Invoking the root command as it automatically creates usage statements. - // It also makes a user aware that a subcommand needs to be used. - var parser = new CommandLineBuilder(rootCommand) - .UseDefaults() - .Build(); - - parser.Invoke(args); + rootCommand.Subcommands.Add(cleanCommand); + rootCommand.Subcommands.Add(convertCommand); + // Parse the commandline and immediately execute. + rootCommand.Parse(args).Invoke(); TotalExecutionTime.Stop(); Log.Information("TotalExecutionTime {time:000}ms", TotalExecutionTime.ElapsedMilliseconds); @@ -139,12 +126,12 @@ class Program return 0; } - static int Convert(DirectoryInfo? ProjectDirectory) + static int Convert(DirectoryInfo ProjectDirectory) { Log.Information("Convert command was called, beginning conversion."); // WARN: This is only temporary as Spectre.Console does not recognise some Linux terminals - // A better solution that checks the terminal value and sets this option should be added in the future. + // TODO: A better solution that checks the terminal value and sets this option should be added in the future. AnsiConsole.Console.Profile.Capabilities.Ansi = true; @@ -211,7 +198,7 @@ class Program return 0; } - static int Clean(DirectoryInfo? ProjectDirectory) + static int Clean(DirectoryInfo ProjectDirectory) { Log.Information("Clean command was called, Beginning cleaning"); @@ -283,15 +270,10 @@ class Program } - static ProjectSettings GetProjectSettings(DirectoryInfo? ProjectDirectory) + static ProjectSettings GetProjectSettings(DirectoryInfo ProjectDirectory) { // TODO: implement proper error handling where file access is performed. - if (ProjectDirectory is null) - { - // use the current directory if no project directory is passed. - ProjectDirectory = new DirectoryInfo("."); - } Log.Information("{projectdir} => fullname {pdfn}",ProjectDirectory, ProjectDirectory.FullName); FileInfo projectFile = new (Path.Combine(ProjectDirectory.FullName,"cssitegen.json")); @@ -299,6 +281,7 @@ class Program if (!projectFile.Exists) { Log.Fatal("Cannot locate project file {pf} in {dir}",projectFile,ProjectDirectory); + AnsiConsole.MarkupLineInterpolated($"[red]No project file found in [yellow]{ProjectDirectory}[/][/]"); Environment.Exit(1); } diff --git a/csSiteGen.csproj b/csSiteGen.csproj index 19e5c24..8c3cc04 100644 --- a/csSiteGen.csproj +++ b/csSiteGen.csproj @@ -16,11 +16,11 @@ - - - - - + + + + +