diff --git a/source/Directory.Build.props b/source/Directory.Build.props index 90519da..91e1718 100644 --- a/source/Directory.Build.props +++ b/source/Directory.Build.props @@ -1,14 +1,30 @@ - 14.0 + 14.0 + 10.0 + 17.13 + + + + true + true + + + + enable + enable true 10.0 All - false + + + + true + true true diff --git a/source/Directory.Packages.props b/source/Directory.Packages.props index 1e47b24..4dd23bd 100644 --- a/source/Directory.Packages.props +++ b/source/Directory.Packages.props @@ -7,6 +7,10 @@ + + + + diff --git a/source/FlashOWare.CommandLine.slnx b/source/FlashOWare.CommandLine.slnx index 2378eea..705454d 100644 --- a/source/FlashOWare.CommandLine.slnx +++ b/source/FlashOWare.CommandLine.slnx @@ -5,4 +5,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/examples/.globalconfig b/source/examples/.globalconfig new file mode 100644 index 0000000..80884de --- /dev/null +++ b/source/examples/.globalconfig @@ -0,0 +1,4 @@ +is_global = true + +# CA2007: Consider calling ConfigureAwait on the awaited task +dotnet_diagnostic.CA2007.severity = none diff --git a/source/examples/Directory.Build.props b/source/examples/Directory.Build.props new file mode 100644 index 0000000..f485270 --- /dev/null +++ b/source/examples/Directory.Build.props @@ -0,0 +1,16 @@ + + + + + + false + + + + true + true + true + + + diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj new file mode 100644 index 0000000..1ee3081 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj @@ -0,0 +1,25 @@ + + + + Exe + net10.0 + FlashOWare.CommandLine.Example.CSharp + FlashOWare.CommandLine.Example + + + + + + + + + + + + + + + + + + diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs new file mode 100644 index 0000000..5b50bb6 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs @@ -0,0 +1,111 @@ +using System.CommandLine; +using System.CommandLine.Invocation; +using System.CommandLine.Parsing; +using System.Reflection; +using Octokit; + +RootCommand rootCommand = new("C# sample app."); + +Option option = new("--language", ["-l", "--lang"]) +{ + Description = "Display the .NET language in use.", + Arity = ArgumentArity.Zero, + Action = new LanguageCommandLineAction(), +}; +rootCommand.Options.Add(option); + +Command command = new("repository", "Display GitHub repository information."); +command.Aliases.Add("repo"); +Argument argument = new("FULL-NAME") +{ + Description = """The full name of the repository in the form of "owner/repo".""", + Arity = ArgumentArity.ZeroOrOne, + DefaultValueFactory = static string (ArgumentResult argumentResult) => "FlashOWare/command-line-interfaces", +}; +argument.Validators.Add(void (ArgumentResult argumentResult) => +{ + string value = argumentResult.GetRequiredValue(argument); + + int index = value.IndexOf('/'); + if (index == -1 || index != value.LastIndexOf('/') || index == 0 || index + 1 == value.Length) + { + argumentResult.AddError("""The full name of the repository must be in the form of "owner/repo"."""); + } +}); +command.Arguments.Add(argument); +command.SetAction(async Task (ParseResult parseResult, CancellationToken cancellationToken) => +{ + string fullName = parseResult.GetRequiredValue(argument); + int index = fullName.IndexOf('/'); + string owner = fullName[..index]; + string repo = fullName[(index + 1)..]; + + AssemblyName name = typeof(Program).Assembly.GetName(); + GitHubClient client = new(new ProductHeaderValue(name.Name, name.Version?.ToString())); + Repository repository = await client.Repository.Get(owner, repo); + RateLimit rateLimit = client.GetLastApiInfo().RateLimit; + + const string TabString = " "; + TextWriter output = parseResult.InvocationConfiguration.Output; + + await output.WriteLineAsync($""" + Repository + {TabString}Full Name: {repository.FullName} + {TabString}Stargazers: {repository.StargazersCount} + {TabString}Watchers: {repository.SubscribersCount} + {TabString}Forks: {repository.ForksCount} + {TabString}Open Issues: {repository.OpenIssuesCount} + """); + await output.WriteLineAsync($""" + Rate Limiting + {TabString}Requests per hour: {rateLimit.Limit - rateLimit.Remaining} / {rateLimit.Limit} + {TabString}Window resets at: {rateLimit.Reset.LocalDateTime:yyyy-MM-dd HH:mm:ss.fffffff} + """); + + return 0; +}); +rootCommand.Subcommands.Add(command); + +Directive directive = new("config") +{ + Description = "Show the command-line configuration that would have been used if the given command line were run.", + Action = new ConfigCommandLineAction(), +}; +rootCommand.Directives.Add(directive); + +ParseResult parseResult = rootCommand.Parse(args); +return await parseResult.InvokeAsync(); + +internal sealed class LanguageCommandLineAction : SynchronousCommandLineAction +{ + public override int Invoke(ParseResult parseResult) + { + TextWriter output = parseResult.InvocationConfiguration.Output; + output.WriteLine("C#"); + return 0; + } +} + +internal sealed class ConfigCommandLineAction : SynchronousCommandLineAction +{ + public override int Invoke(ParseResult parseResult) + { + const string TabString = " "; + TextWriter output = parseResult.InvocationConfiguration.Output; + + output.WriteLine($""" + Configuration + {TabString}EnablePosixBundling: {parseResult.Configuration.EnablePosixBundling} + """); + + output.WriteLine($""" + Invocation + {TabString}EnableDefaultExceptionHandler: {parseResult.InvocationConfiguration.EnableDefaultExceptionHandler} + {TabString}ProcessTerminationTimeout: {(parseResult.InvocationConfiguration.ProcessTerminationTimeout is { } timeout ? timeout.ToString("c") : "")} + {TabString}Output: {parseResult.InvocationConfiguration.Output} + {TabString}Error: {parseResult.InvocationConfiguration.Error} + """); + + return 0; + } +} diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/Properties/AssemblyInfo.cs b/source/examples/FlashOWare.CommandLine.Example.CSharp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..476abce --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Reflection; + +[assembly: AssemblyCopyright("Copyright © FlashOWare 2026")] diff --git a/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj new file mode 100644 index 0000000..cc23b19 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj @@ -0,0 +1,30 @@ + + + + Exe + net10.0 + FlashOWare.CommandLine.Example.FSharp + FlashOWare.CommandLine.Example + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs new file mode 100644 index 0000000..051c9ff --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs @@ -0,0 +1,99 @@ +open System +open System.CommandLine +open System.CommandLine.Invocation +open System.CommandLine.Parsing +open System.Reflection +open System.Threading +open System.Threading.Tasks +open Octokit + +[] +type private LanguageCommandLineAction() = + inherit SynchronousCommandLineAction() + + override this.Invoke(parseResult: ParseResult) : int = + let output = parseResult.InvocationConfiguration.Output + output.WriteLine("F#") + 0 + +[] +type private ConfigCommandLineAction() = + inherit SynchronousCommandLineAction() + + override this.Invoke(parseResult: ParseResult) : int = + let tabString = " " + let output = parseResult.InvocationConfiguration.Output + + output.WriteLine("Configuration") + output.WriteLine($"{tabString}EnablePosixBundling: %b{parseResult.Configuration.EnablePosixBundling}") + + output.WriteLine("Invocation") + output.WriteLine($"{tabString}EnableDefaultExceptionHandler: %b{parseResult.InvocationConfiguration.EnableDefaultExceptionHandler}") + output.WriteLine($"""{tabString}ProcessTerminationTimeout: {(if parseResult.InvocationConfiguration.ProcessTerminationTimeout.HasValue then parseResult.InvocationConfiguration.ProcessTerminationTimeout.Value.ToString("c") else "")}""") + output.WriteLine($"{tabString}Output: {parseResult.InvocationConfiguration.Output}") + output.WriteLine($"{tabString}Error: {parseResult.InvocationConfiguration.Error}") + + 0 + +let rootCommand = RootCommand("F# sample app.") + +let option = Option("--language", [| "-l"; "--lang" |], + Description = "Display the .NET language in use.", + Arity = ArgumentArity.Zero, + Action = LanguageCommandLineAction() +) +rootCommand.Options.Add(option) + +let command = Command("repository", "Display GitHub repository information.") +command.Aliases.Add("repo") +let argument = Argument("FULL-NAME", + Description = """The full name of the repository in the form of "owner/repo".""", + Arity = ArgumentArity.ZeroOrOne, + DefaultValueFactory = fun (argumentResult: ArgumentResult) -> "FlashOWare/command-line-interfaces" +) +argument.Validators.Add(fun (argumentResult : ArgumentResult) -> + let value = argumentResult.GetRequiredValue(argument) + + let index = value.IndexOf('/') + if index = -1 || index <> value.LastIndexOf('/') || index = 0 || index + 1 = value.Length then + argumentResult.AddError("""The full name of the repository must be in the form of "owner/repo".""") +) +command.Arguments.Add(argument) +command.SetAction(fun (parseResult: ParseResult) (cancellationToken: CancellationToken) -> (task { + let fullName = parseResult.GetRequiredValue(argument) + let index = fullName.IndexOf('/') + let owner = fullName.Substring(0, index) + let repo = fullName.Substring(index + 1) + + let name = Assembly.GetExecutingAssembly().GetName() + let client = GitHubClient(ProductHeaderValue(name.Name, match name.Version with | null -> null | version -> version.ToString())) + let! repository = client.Repository.Get(owner, repo) + let rateLimit = client.GetLastApiInfo().RateLimit + + let tabString = " " + let output = parseResult.InvocationConfiguration.Output + + do! output.WriteLineAsync("Repository") + do! output.WriteLineAsync($"{tabString}Full Name: {repository.FullName}") + do! output.WriteLineAsync($"{tabString}Stargazers: {repository.StargazersCount}") + do! output.WriteLineAsync($"{tabString}Watchers: {repository.SubscribersCount}") + do! output.WriteLineAsync($"{tabString}Forks: {repository.ForksCount}") + do! output.WriteLineAsync($"{tabString}Open Issues: {repository.OpenIssuesCount}") + + do! output.WriteLineAsync("Rate Limiting") + do! output.WriteLineAsync($"{tabString}Requests per hour: {rateLimit.Limit - rateLimit.Remaining} / {rateLimit.Limit}") + do! output.WriteLineAsync($"""{tabString}Window resets at: {rateLimit.Reset.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss.fffffff")}""") + + return 0 +} : Task)) +rootCommand.Subcommands.Add(command) + +let directive = Directive("config", + Description = "Show the command-line configuration that would have been used if the given command line were run.", + Action = ConfigCommandLineAction() +) +rootCommand.Directives.Add(directive) + +let parseResult = rootCommand.Parse(Environment.GetCommandLineArgs() |> Array.skip 1) +let exitCode = parseResult.Invoke() +exit exitCode diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj new file mode 100644 index 0000000..0f10238 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj @@ -0,0 +1,25 @@ + + + + Exe + net10.0 + FlashOWare.CommandLine.Example.VisualBasic + FlashOWare.CommandLine.Example + + + + + + + + + + + + + + + + + + diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb new file mode 100644 index 0000000..a95df87 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb @@ -0,0 +1,108 @@ +Imports System.CommandLine +Imports System.CommandLine.Invocation +Imports System.CommandLine.Parsing +Imports System.IO +Imports System.Reflection +Imports System.Threading +Imports Octokit + +Friend Module Program + Friend Function Main(args As String()) As Integer + Dim rootCommand As New RootCommand("Visual Basic sample app.") + + Dim [option] As New [Option](Of Boolean)("--language", New String() {"-l", "--lang"}) With { + .Description = "Display the .NET language in use.", + .Arity = ArgumentArity.Zero, + .Action = New LanguageCommandLineAction() + } + rootCommand.Options.Add([option]) + + Dim command As New Command("repository", "Display GitHub repository information.") + command.Aliases.Add("repo") + Dim argument As New Argument(Of String)("FULL-NAME") With { + .Description = "The full name of the repository in the form of ""owner/repo"".", + .Arity = ArgumentArity.ZeroOrOne, + .DefaultValueFactory = Function(argumentResult As ArgumentResult) "FlashOWare/command-line-interfaces" + } + argument.Validators.Add( + Sub(argumentResult As ArgumentResult) + Dim value As String = argumentResult.GetRequiredValue(argument) + + Dim index As Integer = value.IndexOf("/"c) + If index = -1 OrElse index <> value.LastIndexOf("/"c) OrElse index = 0 OrElse index + 1 = value.Length Then + argumentResult.AddError("The full name of the repository must be in the form of ""owner/repo"".") + End If + End Sub) + command.Arguments.Add(argument) + command.SetAction( + Async Function(parseResult As ParseResult, cancellationToken As CancellationToken) As Task(Of Integer) + Dim fullName As String = parseResult.GetRequiredValue(argument) + Dim index As Integer = fullName.IndexOf("/"c) + Dim owner As String = fullName.Substring(0, index) + Dim repo As String = fullName.Substring(index + 1) + + Dim name As AssemblyName = GetType(Program).Assembly.GetName() + Dim client As New GitHubClient(New ProductHeaderValue(name.Name, name.Version?.ToString())) + Dim repository As Repository = Await client.Repository.Get(owner, repo) + Dim rateLimit As RateLimit = client.GetLastApiInfo().RateLimit + + Const TabString As String = " " + Dim output As TextWriter = parseResult.InvocationConfiguration.Output + + Await output.WriteLineAsync("Repository") + Await output.WriteLineAsync($"{TabString}Full Name: {repository.FullName}") + Await output.WriteLineAsync($"{TabString}Stargazers: {repository.StargazersCount}") + Await output.WriteLineAsync($"{TabString}Watchers: {repository.SubscribersCount}") + Await output.WriteLineAsync($"{TabString}Forks: {repository.ForksCount}") + Await output.WriteLineAsync($"{TabString}Open Issues: {repository.OpenIssuesCount}") + + Await output.WriteLineAsync("Rate Limiting") + Await output.WriteLineAsync($"{TabString}Requests per hour: {rateLimit.Limit - rateLimit.Remaining} / {rateLimit.Limit}") + Await output.WriteLineAsync($"{TabString}Window resets at: {rateLimit.Reset.LocalDateTime:yyyy-MM-dd HH:mm:ss.fffffff}") + + Return 0 + End Function) + rootCommand.Subcommands.Add(command) + + Dim directive As New Directive("config") With { + .Description = "Show the command-line configuration that would have been used if the given command line were run.", + .Action = New ConfigCommandLineAction() + } + rootCommand.Directives.Add(directive) + + Dim result As ParseResult = rootCommand.Parse(args) + Return result.Invoke() + End Function +End Module + +Friend NotInheritable Class LanguageCommandLineAction + Inherits SynchronousCommandLineAction + + Public Overrides Function Invoke(parseResult As ParseResult) As Integer + Dim output As TextWriter = parseResult.InvocationConfiguration.Output + output.WriteLine("Visual Basic") + Return 0 + End Function +End Class + +Friend NotInheritable Class ConfigCommandLineAction + Inherits SynchronousCommandLineAction + + Public Overrides Function Invoke(parseResult As ParseResult) As Integer + Const TabString As String = " " + Dim output As TextWriter = parseResult.InvocationConfiguration.Output + + output.WriteLine("Configuration") + output.WriteLine($"{TabString}EnablePosixBundling: {parseResult.Configuration.EnablePosixBundling}") + + output.WriteLine("Invocation") + output.WriteLine($"{TabString}EnableDefaultExceptionHandler: {parseResult.InvocationConfiguration.EnableDefaultExceptionHandler}") + output.WriteLine($"{TabString}ProcessTerminationTimeout: {If(parseResult.InvocationConfiguration.ProcessTerminationTimeout.HasValue, + parseResult.InvocationConfiguration.ProcessTerminationTimeout.Value.ToString("c"), + "")}") + output.WriteLine($"{TabString}Output: {parseResult.InvocationConfiguration.Output}") + output.WriteLine($"{TabString}Error: {parseResult.InvocationConfiguration.Error}") + + Return 0 + End Function +End Class diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/AssemblyInfo.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/AssemblyInfo.vb new file mode 100644 index 0000000..661b034 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/AssemblyInfo.vb @@ -0,0 +1,3 @@ +Imports System.Reflection + + diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/GlobalSuppressions.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/GlobalSuppressions.vb new file mode 100644 index 0000000..e5be563 --- /dev/null +++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/GlobalSuppressions.vb @@ -0,0 +1,5 @@ +' Global Suppressions + +Imports System.Diagnostics.CodeAnalysis + + diff --git a/source/lib/.globalconfig b/source/lib/.globalconfig new file mode 100644 index 0000000..7874532 --- /dev/null +++ b/source/lib/.globalconfig @@ -0,0 +1 @@ +is_global = true diff --git a/source/lib/Directory.Build.props b/source/lib/Directory.Build.props new file mode 100644 index 0000000..05eca01 --- /dev/null +++ b/source/lib/Directory.Build.props @@ -0,0 +1,26 @@ + + + + + + true + + + + true + + + + + true + true + + + + + true + true + + + diff --git a/source/lib/FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj b/source/lib/FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj new file mode 100644 index 0000000..cdb55a5 --- /dev/null +++ b/source/lib/FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj @@ -0,0 +1,10 @@ + + + + Library + net10.0 + FlashOWare.CommandLine.CliSchema + FlashOWare.CommandLine + + + diff --git a/source/lib/FlashOWare.CommandLine.CliSchema/Properties/AssemblyInfo.cs b/source/lib/FlashOWare.CommandLine.CliSchema/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c0d560e --- /dev/null +++ b/source/lib/FlashOWare.CommandLine.CliSchema/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: CLSCompliant(true)] diff --git a/source/lib/FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj b/source/lib/FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj new file mode 100644 index 0000000..386e7c2 --- /dev/null +++ b/source/lib/FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj @@ -0,0 +1,10 @@ + + + + Library + net10.0 + FlashOWare.CommandLine.OpenCli + FlashOWare.CommandLine + + + diff --git a/source/lib/FlashOWare.CommandLine.OpenCli/Properties/AssemblyInfo.cs b/source/lib/FlashOWare.CommandLine.OpenCli/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c0d560e --- /dev/null +++ b/source/lib/FlashOWare.CommandLine.OpenCli/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: CLSCompliant(true)] diff --git a/source/perf/.globalconfig b/source/perf/.globalconfig new file mode 100644 index 0000000..c290eca --- /dev/null +++ b/source/perf/.globalconfig @@ -0,0 +1,13 @@ +is_global = true + +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = none + +# CA1515: Consider making public types internal +dotnet_diagnostic.CA1515.severity = none + +# CA1822: Mark members as static +dotnet_diagnostic.CA1822.severity = none + +# CA1852: Seal internal types +dotnet_diagnostic.CA1852.severity = none diff --git a/source/perf/Directory.Build.props b/source/perf/Directory.Build.props new file mode 100644 index 0000000..4a05b80 --- /dev/null +++ b/source/perf/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + + false + + + + + + + diff --git a/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/FlashOWare.CommandLine.CliSchema.Benchmarks.csproj b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/FlashOWare.CommandLine.CliSchema.Benchmarks.csproj new file mode 100644 index 0000000..b7f9d1c --- /dev/null +++ b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/FlashOWare.CommandLine.CliSchema.Benchmarks.csproj @@ -0,0 +1,18 @@ + + + + Exe + net10.0 + FlashOWare.CommandLine.CliSchema.Benchmarks + FlashOWare.CommandLine.Benchmarks + + + + + + + + + + + diff --git a/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Program.cs b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Program.cs new file mode 100644 index 0000000..a7eb5e7 --- /dev/null +++ b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Program.cs @@ -0,0 +1,20 @@ +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; + +#if DEBUG +IConfig config = new DebugInProcessConfig(); +#else +IConfig config = ManualConfig.Create(DefaultConfig.Instance) + .WithOptions(ConfigOptions.DisableLogFile) + .AddDiagnoser(MemoryDiagnoser.Default); +#endif + +IEnumerable summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); + +Console.WriteLine("Summaries:"); +foreach (Summary summary in summaries) +{ + Console.WriteLine($"- Ran {summary.Title} with {summary.ValidationErrors.Length} validation errors."); +} diff --git a/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Properties/AssemblyInfo.cs b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..476abce --- /dev/null +++ b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Reflection; + +[assembly: AssemblyCopyright("Copyright © FlashOWare 2026")] diff --git a/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/FlashOWare.CommandLine.OpenCli.Benchmarks.csproj b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/FlashOWare.CommandLine.OpenCli.Benchmarks.csproj new file mode 100644 index 0000000..73e8aca --- /dev/null +++ b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/FlashOWare.CommandLine.OpenCli.Benchmarks.csproj @@ -0,0 +1,18 @@ + + + + Exe + net10.0 + FlashOWare.CommandLine.OpenCli.Benchmarks + FlashOWare.CommandLine.Benchmarks + + + + + + + + + + + diff --git a/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Program.cs b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Program.cs new file mode 100644 index 0000000..a7eb5e7 --- /dev/null +++ b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Program.cs @@ -0,0 +1,20 @@ +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; + +#if DEBUG +IConfig config = new DebugInProcessConfig(); +#else +IConfig config = ManualConfig.Create(DefaultConfig.Instance) + .WithOptions(ConfigOptions.DisableLogFile) + .AddDiagnoser(MemoryDiagnoser.Default); +#endif + +IEnumerable summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); + +Console.WriteLine("Summaries:"); +foreach (Summary summary in summaries) +{ + Console.WriteLine($"- Ran {summary.Title} with {summary.ValidationErrors.Length} validation errors."); +} diff --git a/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Properties/AssemblyInfo.cs b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..476abce --- /dev/null +++ b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Reflection; + +[assembly: AssemblyCopyright("Copyright © FlashOWare 2026")] diff --git a/source/tests/.globalconfig b/source/tests/.globalconfig new file mode 100644 index 0000000..06dfdf7 --- /dev/null +++ b/source/tests/.globalconfig @@ -0,0 +1,11 @@ +is_global = true + +# CA1515: Consider making public types internal +dotnet_diagnostic.CA1515.severity = none + +# https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/overview +dotnet_diagnostic.MSTEST0015.severity = warning +dotnet_diagnostic.MSTEST0019.severity = none +dotnet_diagnostic.MSTEST0020.severity = warning +dotnet_diagnostic.MSTEST0021.severity = warning +dotnet_diagnostic.MSTEST0022.severity = none diff --git a/source/tests/Directory.Build.props b/source/tests/Directory.Build.props new file mode 100644 index 0000000..9229631 --- /dev/null +++ b/source/tests/Directory.Build.props @@ -0,0 +1,18 @@ + + + + + + false + + + + true + + + + + + + diff --git a/source/tests/FlashOWare.CommandLine.CliSchema.Tests/FlashOWare.CommandLine.CliSchema.Tests.csproj b/source/tests/FlashOWare.CommandLine.CliSchema.Tests/FlashOWare.CommandLine.CliSchema.Tests.csproj new file mode 100644 index 0000000..4a6c213 --- /dev/null +++ b/source/tests/FlashOWare.CommandLine.CliSchema.Tests/FlashOWare.CommandLine.CliSchema.Tests.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + FlashOWare.CommandLine.CliSchema.Tests + FlashOWare.CommandLine.Tests + + + + + + + diff --git a/source/tests/FlashOWare.CommandLine.CliSchema.Tests/Properties/AssemblyInfo.cs b/source/tests/FlashOWare.CommandLine.CliSchema.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..300f5b1 --- /dev/null +++ b/source/tests/FlashOWare.CommandLine.CliSchema.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/source/tests/FlashOWare.CommandLine.OpenCli.Tests/FlashOWare.CommandLine.OpenCli.Tests.csproj b/source/tests/FlashOWare.CommandLine.OpenCli.Tests/FlashOWare.CommandLine.OpenCli.Tests.csproj new file mode 100644 index 0000000..b6b144f --- /dev/null +++ b/source/tests/FlashOWare.CommandLine.OpenCli.Tests/FlashOWare.CommandLine.OpenCli.Tests.csproj @@ -0,0 +1,13 @@ + + + + net10.0 + FlashOWare.CommandLine.OpenCli.Tests + FlashOWare.CommandLine.Tests + + + + + + + diff --git a/source/tests/FlashOWare.CommandLine.OpenCli.Tests/Properties/AssemblyInfo.cs b/source/tests/FlashOWare.CommandLine.OpenCli.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..300f5b1 --- /dev/null +++ b/source/tests/FlashOWare.CommandLine.OpenCli.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]