diff --git a/netxml2kml/Methods/CliOptionsHandlers.cs b/netxml2kml/Methods/CliOptionsHandlers.cs index 304ab28..ac4bf58 100644 --- a/netxml2kml/Methods/CliOptionsHandlers.cs +++ b/netxml2kml/Methods/CliOptionsHandlers.cs @@ -87,7 +87,11 @@ public static class CliOptionsHandlers } else { - Log.Warning("Options combination is unsupported."); + Log.Warning("Options combination is unsupported: " + + "-i: {input}; -o {output}; -d {useDatabase}; " + + "-q: {sqlQuery}; -c: {concatFiles}; -v: {verbosityLevel}.", + inputFile!, outputFile!, useDatabase, + sqlQuery!, concatFiles!, isVerbose); } } catch (Exception e) diff --git a/netxml2kml/Methods/RuntimeStorage.cs b/netxml2kml/Methods/RuntimeStorage.cs index 012ae51..aa2a7a7 100644 --- a/netxml2kml/Methods/RuntimeStorage.cs +++ b/netxml2kml/Methods/RuntimeStorage.cs @@ -17,7 +17,7 @@ public static class RuntimeStorage { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() - .WriteTo.Console(IsVerbose ? LogEventLevel.Verbose : LogEventLevel.Fatal, + .WriteTo.Console(IsVerbose ? LogEventLevel.Verbose : LogEventLevel.Warning, outputTemplate: "{Message:lj}{NewLine}{Exception}") .WriteTo.File(Path.Join(LogsFolder, "log.txt"), restrictedToMinimumLevel: IsVerbose ? LogEventLevel.Verbose : LogEventLevel.Warning, diff --git a/netxml2kml/Program.cs b/netxml2kml/Program.cs index d54680d..e77c63d 100644 --- a/netxml2kml/Program.cs +++ b/netxml2kml/Program.cs @@ -1,4 +1,7 @@ using System.CommandLine; +using System.CommandLine.Builder; +using System.CommandLine.Help; +using System.CommandLine.Parsing; using System.Xml.Linq; using netxml2kml.Methods; @@ -12,11 +15,13 @@ class Program var inputOption = new Option( aliases: new[] {"-i", "--input"}, - description: "Path to the file to be converted.") + description: "Path to the file to be converted") { Arity = ArgumentArity.ZeroOrOne }; + inputOption.ArgumentHelpName = "file_path[.netxml]"; + inputOption.AddValidator(result => { var inputFile = result.GetValueForOption(inputOption); @@ -24,13 +29,13 @@ class Program if (inputFile == null) { result.ErrorMessage = - "Argument for input option is not specified."; + "Argument for input option is not specified"; return; } if (!inputFile.Exists) { - result.ErrorMessage = "Input file doesn't exist."; + result.ErrorMessage = "Input file doesn't exist"; return; } }); @@ -39,7 +44,7 @@ class Program var outputOption = new Option( aliases: new[] {"-o", "--output"}, - description: "The name of the file to be created.", + description: "Path to the file to be created", parseArgument: result => { // If output file with the same name already exists – @@ -82,6 +87,8 @@ class Program Arity = ArgumentArity.ZeroOrOne }; + outputOption.ArgumentHelpName = "file_path[.kml]"; + outputOption.AddValidator(result => { var outputFile = result.GetValueForOption(outputOption); @@ -89,13 +96,13 @@ class Program if (outputFile == null) { result.ErrorMessage = - "Argument for output option is not specified."; + "Argument for output option is not specified"; return; } if (!Directory.Exists(outputFile.DirectoryName)) { - result.ErrorMessage = "Output directory doesn't exist."; + result.ErrorMessage = "Output directory doesn't exist"; return; } }); @@ -104,11 +111,13 @@ class Program var concatOption = new Option?>( aliases: new[] {"-c", "--concat"}, - description: "Concatenate multiple kml files. ") + description: "Concatenate multiple kml files") { Arity = ArgumentArity.OneOrMore, AllowMultipleArgumentsPerToken = true }; + + concatOption.ArgumentHelpName = "file_path[.kml] file_path[.kml] ..."; concatOption.AddValidator(result => { @@ -117,7 +126,7 @@ class Program if (inputFiles == null) { result.ErrorMessage = - "Argument for concat option is not specified."; + "Argument for concat option is not specified"; return; } @@ -128,7 +137,7 @@ class Program if (!inputFile.Exists) { result.ErrorMessage = - $"File {inputFile.FullName} doesen't exist."; + $"File {inputFile.FullName} doesen't exist"; return; } } @@ -138,7 +147,7 @@ class Program XDocument.Load(fi.FullName).Root?.Name != "kml")) { result.ErrorMessage = - "Some files passed to concat option have invalid content."; + "Some files passed to concat option have invalid content"; return; } }); @@ -148,7 +157,7 @@ class Program var databaseOption = new Option( aliases: new[] {"-d", "--use-database"}, description: - "Use database (save/retrieve data from database).") + "Use database (save/retrieve data)") { Arity = ArgumentArity.ZeroOrOne }; @@ -157,23 +166,25 @@ class Program var queryOption = new Option( aliases: new[] {"-q", "--query"}, - description: "Filter input/output using sql query.") + description: "Filter input/output using sql query") { Arity = ArgumentArity.ZeroOrOne }; + + queryOption.ArgumentHelpName = "\"sql_query\""; /*----------------------Verbosity Option---------------------------*/ - var verbosityOption = new Option( - aliases: new[] {"-v", "--verbosity"}, - description: "Set console output verbosity level.") + var verboseOption = new Option( + aliases: new[] {"-v", "--verbose"}, + description: "Show verbose output") { Arity = ArgumentArity.ZeroOrOne }; - verbosityOption.AddValidator(result => + verboseOption.AddValidator(result => { - RuntimeStorage.IsVerbose = result.GetValueForOption(verbosityOption); + RuntimeStorage.IsVerbose = result.GetValueForOption(verboseOption); }); RuntimeStorage.ConfigureLogger(); @@ -181,25 +192,49 @@ class Program /*----------------------Root Command Setup-------------------------*/ var rootCommand = - new RootCommand("netxml2kml – .netxml to .kml converter."); + new RootCommand("netxml2kml – .netxml to .kml CLI converter & tools"); rootCommand.AddOption(inputOption); rootCommand.AddOption(outputOption); rootCommand.AddOption(databaseOption); rootCommand.AddOption(queryOption); rootCommand.AddOption(concatOption); - rootCommand.AddOption(verbosityOption); + rootCommand.AddOption(verboseOption); /*----------------------Handlers Setup-----------------------------*/ rootCommand.SetHandler(CliOptionsHandlers.UniversalHandler, inputOption, outputOption, databaseOption, queryOption, - concatOption, verbosityOption); + concatOption, verboseOption); /*----------------------------------------------------------------*/ + var rootCommandParser = new CommandLineBuilder(rootCommand) + .UseDefaults().UseHelp(ctx => + { + ctx.HelpBuilder.CustomizeLayout(_ => + HelpBuilder.Default + .GetLayout() + .Skip(HelpBuilder.Default.GetLayout().Count()) + .Append(_ => Console.WriteLine( + "netxml2kml – .netxml to .kml CLI converter & tools" + + "\n" + + "\nUsage:" + + "\n netxml2kml [options]" + + "\n" + + "\nOptions:" + + "\n -i, --input Path to the file to be converted" + + "\n -o, --output Path to the file to be created" + + "\n -c, --concat Concatenate multiple kml files" + + "\n -d, --use-database Use database (save/retrieve data)" + + "\n -q, --query <\"sql_query\"> Filter input/output using sql query" + + "\n -v, --verbose Show verbose output" + + "\n -h, --help Show help and usage information" + + "\n --version Show version information"))); + }).Build(); + try { - return await rootCommand.InvokeAsync(args); + return await rootCommandParser.InvokeAsync(args); } catch (Exception e) {