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 @@ - - - - - + + + + +