From 5f8dc40c739920ca7ac35171bcdd092606a6e7c5 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Sat, 8 Aug 2026 10:07:11 +0200
Subject: [PATCH 01/13] chore: add projects for CLI introspection
---
source/Directory.Build.props | 20 ++++++++++++++--
source/Directory.Packages.props | 2 ++
source/FlashOWare.CommandLine.slnx | 23 +++++++++++++++++++
source/examples/.globalconfig | 4 ++++
source/examples/Directory.Build.props | 11 +++++++++
...ashOWare.CommandLine.Example.CSharp.csproj | 15 ++++++++++++
.../Program.cs | 1 +
.../Properties/AssemblyInfo.cs | 3 +++
...ashOWare.CommandLine.Example.FSharp.fsproj | 23 +++++++++++++++++++
.../Program.fs | 1 +
...are.CommandLine.Example.VisualBasic.vbproj | 15 ++++++++++++
.../Program.vb | 7 ++++++
.../Properties/AssemblyInfo.vb | 3 +++
source/lib/.globalconfig | 1 +
source/lib/Directory.Build.props | 15 ++++++++++++
...CommandLine.Introspection.CliSchema.csproj | 10 ++++++++
.../Properties/AssemblyInfo.cs | 1 +
...e.CommandLine.Introspection.OpenCli.csproj | 10 ++++++++
.../Properties/AssemblyInfo.cs | 1 +
source/perf/.globalconfig | 13 +++++++++++
source/perf/Directory.Build.props | 10 ++++++++
...ommandLine.Introspection.Benchmarks.csproj | 19 +++++++++++++++
.../Program.cs | 20 ++++++++++++++++
.../Properties/AssemblyInfo.cs | 3 +++
source/tests/.globalconfig | 11 +++++++++
source/tests/Directory.Build.props | 10 ++++++++
...are.CommandLine.Introspection.Tests.csproj | 14 +++++++++++
.../Properties/AssemblyInfo.cs | 1 +
28 files changed, 265 insertions(+), 2 deletions(-)
create mode 100644 source/examples/.globalconfig
create mode 100644 source/examples/Directory.Build.props
create mode 100644 source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
create mode 100644 source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
create mode 100644 source/examples/FlashOWare.CommandLine.Example.CSharp/Properties/AssemblyInfo.cs
create mode 100644 source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
create mode 100644 source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
create mode 100644 source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
create mode 100644 source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
create mode 100644 source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/AssemblyInfo.vb
create mode 100644 source/lib/.globalconfig
create mode 100644 source/lib/Directory.Build.props
create mode 100644 source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
create mode 100644 source/lib/FlashOWare.CommandLine.Introspection.CliSchema/Properties/AssemblyInfo.cs
create mode 100644 source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
create mode 100644 source/lib/FlashOWare.CommandLine.Introspection.OpenCli/Properties/AssemblyInfo.cs
create mode 100644 source/perf/.globalconfig
create mode 100644 source/perf/Directory.Build.props
create mode 100644 source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
create mode 100644 source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Program.cs
create mode 100644 source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Properties/AssemblyInfo.cs
create mode 100644 source/tests/.globalconfig
create mode 100644 source/tests/Directory.Build.props
create mode 100644 source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
create mode 100644 source/tests/FlashOWare.CommandLine.Introspection.Tests/Properties/AssemblyInfo.cs
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..4561c4d 100644
--- a/source/Directory.Packages.props
+++ b/source/Directory.Packages.props
@@ -7,6 +7,8 @@
+
+
diff --git a/source/FlashOWare.CommandLine.slnx b/source/FlashOWare.CommandLine.slnx
index 2378eea..15a36b5 100644
--- a/source/FlashOWare.CommandLine.slnx
+++ b/source/FlashOWare.CommandLine.slnx
@@ -5,4 +5,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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..7d55cb4
--- /dev/null
+++ b/source/examples/Directory.Build.props
@@ -0,0 +1,11 @@
+
+
+
+
+
+ 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..d46bb7a
--- /dev/null
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
@@ -0,0 +1,15 @@
+
+
+
+ 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..9fe1ad3
--- /dev/null
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
@@ -0,0 +1 @@
+Console.WriteLine("Hello from C#");
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..6c60583
--- /dev/null
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
@@ -0,0 +1,23 @@
+
+
+
+ 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..0a01d41
--- /dev/null
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
@@ -0,0 +1 @@
+printfn "Hello from F#"
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..7d09f18
--- /dev/null
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
@@ -0,0 +1,15 @@
+
+
+
+ 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..470ea70
--- /dev/null
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
@@ -0,0 +1,7 @@
+Imports System
+
+Module Program
+ Sub Main(args As String())
+ Console.WriteLine("Hello from Visual Basic")
+ End Sub
+End Module
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/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..531e0c9
--- /dev/null
+++ b/source/lib/Directory.Build.props
@@ -0,0 +1,15 @@
+
+
+
+
+
+ true
+
+
+
+ true
+ true
+
+
+
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj b/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
new file mode 100644
index 0000000..399a212
--- /dev/null
+++ b/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Library
+ net10.0
+ FlashOWare.CommandLine.Introspection.CliSchema
+ FlashOWare.CommandLine
+
+
+
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/Properties/AssemblyInfo.cs b/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c0d560e
--- /dev/null
+++ b/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/Properties/AssemblyInfo.cs
@@ -0,0 +1 @@
+[assembly: CLSCompliant(true)]
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj b/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
new file mode 100644
index 0000000..8d2ca90
--- /dev/null
+++ b/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Library
+ net10.0
+ FlashOWare.CommandLine.Introspection.OpenCli
+ FlashOWare.CommandLine
+
+
+
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/Properties/AssemblyInfo.cs b/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c0d560e
--- /dev/null
+++ b/source/lib/FlashOWare.CommandLine.Introspection.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..4512da4
--- /dev/null
+++ b/source/perf/Directory.Build.props
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
new file mode 100644
index 0000000..9a7f442
--- /dev/null
+++ b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ net10.0
+ FlashOWare.CommandLine.Introspection.Benchmarks
+ FlashOWare.CommandLine.Benchmarks
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Program.cs b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Program.cs
new file mode 100644
index 0000000..a7eb5e7
--- /dev/null
+++ b/source/perf/FlashOWare.CommandLine.Introspection.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.Introspection.Benchmarks/Properties/AssemblyInfo.cs b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..476abce
--- /dev/null
+++ b/source/perf/FlashOWare.CommandLine.Introspection.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..4512da4
--- /dev/null
+++ b/source/tests/Directory.Build.props
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
new file mode 100644
index 0000000..0cb62ff
--- /dev/null
+++ b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net10.0
+ FlashOWare.CommandLine.Introspection.Tests
+ FlashOWare.CommandLine.Tests
+
+
+
+
+
+
+
+
diff --git a/source/tests/FlashOWare.CommandLine.Introspection.Tests/Properties/AssemblyInfo.cs b/source/tests/FlashOWare.CommandLine.Introspection.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..300f5b1
--- /dev/null
+++ b/source/tests/FlashOWare.CommandLine.Introspection.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1 @@
+[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
From cfd6ced09e5376e0e4f6c23e6ff1c5093e0a856c Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Mon, 10 Aug 2026 17:34:09 +0200
Subject: [PATCH 02/13] chore: add C# sample app
---
source/Directory.Packages.props | 2 +
...ashOWare.CommandLine.Example.CSharp.csproj | 5 +
.../Program.cs | 112 +++++++++++++++++-
3 files changed, 118 insertions(+), 1 deletion(-)
diff --git a/source/Directory.Packages.props b/source/Directory.Packages.props
index 4561c4d..81d5a27 100644
--- a/source/Directory.Packages.props
+++ b/source/Directory.Packages.props
@@ -9,6 +9,8 @@
+
+
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
index d46bb7a..d25cd82 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
@@ -7,6 +7,11 @@
FlashOWare.CommandLine.Example
+
+
+
+
+
diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
index 9fe1ad3..62ce1f4 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
@@ -1 +1,111 @@
-Console.WriteLine("Hello from C#");
+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.");
+Argument argument = new("FULL-NAME")
+{
+ Description = """The full name of the repository in the form of "owner/repo".""",
+ Arity = ArgumentArity.ZeroOrOne,
+ DefaultValueFactory = static (ArgumentResult argumentResult) => "FlashOWare/command-line-interfaces",
+};
+argument.Validators.Add((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 (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;
+ }
+}
From d23e1928e8ff242773b0d7a9477f5818b22ce265 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Tue, 11 Aug 2026 11:42:12 +0200
Subject: [PATCH 03/13] chore: add Visual Basic sample app
---
...are.CommandLine.Example.VisualBasic.vbproj | 5 +
.../Program.vb | 111 +++++++++++++++++-
.../Properties/GlobalSuppressions.vb | 5 +
3 files changed, 116 insertions(+), 5 deletions(-)
create mode 100644 source/examples/FlashOWare.CommandLine.Example.VisualBasic/Properties/GlobalSuppressions.vb
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
index 7d09f18..ea21746 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
@@ -7,6 +7,11 @@
FlashOWare.CommandLine.Example
+
+
+
+
+
diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
index 470ea70..ec36652 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
@@ -1,7 +1,108 @@
-Imports System
+Imports System.CommandLine
+Imports System.CommandLine.Invocation
+Imports System.CommandLine.Parsing
+Imports System.IO
+Imports System.Reflection
+Imports System.Threading
+Imports Octokit
-Module Program
- Sub Main(args As String())
- Console.WriteLine("Hello from Visual Basic")
- End Sub
+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.")
+ 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/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
+
+
From ecb05d3e4c91f01be7f70290675e00f1e89dcadb Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Tue, 11 Aug 2026 16:13:36 +0200
Subject: [PATCH 04/13] chore: add F# sample app
---
...ashOWare.CommandLine.Example.FSharp.fsproj | 2 +
.../Program.fs | 97 ++++++++++++++++++-
2 files changed, 98 insertions(+), 1 deletion(-)
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
index 6c60583..b29c347 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
@@ -13,6 +13,8 @@
+
+
diff --git a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
index 0a01d41..798c499 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
@@ -1 +1,96 @@
-printfn "Hello from F#"
+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) =
+ let output = parseResult.InvocationConfiguration.Output
+ output.WriteLine("F#")
+ 0
+
+[]
+type private ConfigCommandLineAction() =
+ inherit SynchronousCommandLineAction()
+ override this.Invoke(parseResult: ParseResult) =
+ 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.")
+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 result = parseResult.Invoke()
+exit result
From c29c2cd63532a89fe75a03118bc088d3e615a479 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Tue, 11 Aug 2026 16:51:29 +0200
Subject: [PATCH 05/13] style: align format of sample apps
---
.../FlashOWare.CommandLine.Example.CSharp/Program.cs | 9 ++++-----
.../FlashOWare.CommandLine.Example.FSharp/Program.fs | 2 ++
.../Program.vb | 11 +++++------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
index 62ce1f4..69de71b 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
@@ -5,6 +5,7 @@
using Octokit;
RootCommand rootCommand = new("C# sample app.");
+
Option option = new("--language", ["-l", "--lang"])
{
Description = "Display the .NET language in use.",
@@ -18,9 +19,9 @@
{
Description = """The full name of the repository in the form of "owner/repo".""",
Arity = ArgumentArity.ZeroOrOne,
- DefaultValueFactory = static (ArgumentResult argumentResult) => "FlashOWare/command-line-interfaces",
+ DefaultValueFactory = static string (ArgumentResult argumentResult) => "FlashOWare/command-line-interfaces",
};
-argument.Validators.Add((ArgumentResult argumentResult) =>
+argument.Validators.Add(void (ArgumentResult argumentResult) =>
{
string value = argumentResult.GetRequiredValue(argument);
@@ -31,7 +32,7 @@
}
});
command.Arguments.Add(argument);
-command.SetAction(async (ParseResult parseResult, CancellationToken cancellationToken) =>
+command.SetAction(async Task (ParseResult parseResult, CancellationToken cancellationToken) =>
{
string fullName = parseResult.GetRequiredValue(argument);
int index = fullName.IndexOf('/');
@@ -79,9 +80,7 @@ internal sealed class LanguageCommandLineAction : SynchronousCommandLineAction
public override int Invoke(ParseResult parseResult)
{
TextWriter output = parseResult.InvocationConfiguration.Output;
-
output.WriteLine("C#");
-
return 0;
}
}
diff --git a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
index 798c499..f359481 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
@@ -10,6 +10,7 @@ open Octokit
[]
type private LanguageCommandLineAction() =
inherit SynchronousCommandLineAction()
+
override this.Invoke(parseResult: ParseResult) =
let output = parseResult.InvocationConfiguration.Output
output.WriteLine("F#")
@@ -18,6 +19,7 @@ type private LanguageCommandLineAction() =
[]
type private ConfigCommandLineAction() =
inherit SynchronousCommandLineAction()
+
override this.Invoke(parseResult: ParseResult) =
let tabString = " "
let output = parseResult.InvocationConfiguration.Output
diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
index ec36652..c3e1b96 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
@@ -9,6 +9,7 @@ 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,
@@ -47,14 +48,14 @@ Friend Module Program
Const tabString As String = " "
Dim output As TextWriter = parseResult.InvocationConfiguration.Output
- Await output.WriteLineAsync($"Repository")
+ 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("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}")
@@ -78,9 +79,7 @@ Friend NotInheritable Class LanguageCommandLineAction
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
@@ -92,10 +91,10 @@ Friend NotInheritable Class ConfigCommandLineAction
Const tabString As String = " "
Dim output As TextWriter = parseResult.InvocationConfiguration.Output
- output.WriteLine($"Configuration")
+ output.WriteLine("Configuration")
output.WriteLine($"{tabString}EnablePosixBundling: {parseResult.Configuration.EnablePosixBundling}")
- output.WriteLine($"Invocation")
+ 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"),
From 649f0dc00fa1c564d269301c386dd56211916e2a Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Tue, 11 Aug 2026 17:26:23 +0200
Subject: [PATCH 06/13] style: change names of local constants from camelCase
to PascalCase
---
.../Program.cs | 28 +++++++++----------
.../Program.vb | 28 +++++++++----------
2 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
index 69de71b..3db9845 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
@@ -44,21 +44,21 @@
Repository repository = await client.Repository.Get(owner, repo);
RateLimit rateLimit = client.GetLastApiInfo().RateLimit;
- const string tabString = " ";
+ 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}
+ {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}
+ {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;
@@ -89,20 +89,20 @@ internal sealed class ConfigCommandLineAction : SynchronousCommandLineAction
{
public override int Invoke(ParseResult parseResult)
{
- const string tabString = " ";
+ const string TabString = " ";
TextWriter output = parseResult.InvocationConfiguration.Output;
output.WriteLine($"""
Configuration
- {tabString}EnablePosixBundling: {parseResult.Configuration.EnablePosixBundling}
+ {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}
+ {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.VisualBasic/Program.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
index c3e1b96..1a2d53d 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
@@ -45,19 +45,19 @@ Friend Module Program
Dim repository As Repository = Await client.Repository.Get(owner, repo)
Dim rateLimit As RateLimit = client.GetLastApiInfo().RateLimit
- Const tabString As String = " "
+ 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($"{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}")
+ 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)
@@ -88,19 +88,19 @@ Friend NotInheritable Class ConfigCommandLineAction
Inherits SynchronousCommandLineAction
Public Overrides Function Invoke(parseResult As ParseResult) As Integer
- Const tabString As String = " "
+ Const TabString As String = " "
Dim output As TextWriter = parseResult.InvocationConfiguration.Output
output.WriteLine("Configuration")
- output.WriteLine($"{tabString}EnablePosixBundling: {parseResult.Configuration.EnablePosixBundling}")
+ 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,
+ 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}")
+ output.WriteLine($"{TabString}Output: {parseResult.InvocationConfiguration.Output}")
+ output.WriteLine($"{TabString}Error: {parseResult.InvocationConfiguration.Error}")
Return 0
End Function
From 58373ea2dc2ef78c072932c9b39183b4f96abed7 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Tue, 11 Aug 2026 22:06:19 +0200
Subject: [PATCH 07/13] chore: add repo alias to repository command
---
.../FlashOWare.CommandLine.Example.CSharp/Program.cs | 1 +
.../FlashOWare.CommandLine.Example.FSharp/Program.fs | 9 +++++----
.../Program.vb | 1 +
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
index 3db9845..5b50bb6 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/Program.cs
@@ -15,6 +15,7 @@
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".""",
diff --git a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
index f359481..051c9ff 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/Program.fs
@@ -11,7 +11,7 @@ open Octokit
type private LanguageCommandLineAction() =
inherit SynchronousCommandLineAction()
- override this.Invoke(parseResult: ParseResult) =
+ override this.Invoke(parseResult: ParseResult) : int =
let output = parseResult.InvocationConfiguration.Output
output.WriteLine("F#")
0
@@ -20,7 +20,7 @@ type private LanguageCommandLineAction() =
type private ConfigCommandLineAction() =
inherit SynchronousCommandLineAction()
- override this.Invoke(parseResult: ParseResult) =
+ override this.Invoke(parseResult: ParseResult) : int =
let tabString = " "
let output = parseResult.InvocationConfiguration.Output
@@ -45,6 +45,7 @@ let option = Option("--language", [| "-l"; "--lang" |],
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,
@@ -94,5 +95,5 @@ let directive = Directive("config",
rootCommand.Directives.Add(directive)
let parseResult = rootCommand.Parse(Environment.GetCommandLineArgs() |> Array.skip 1)
-let result = parseResult.Invoke()
-exit result
+let exitCode = parseResult.Invoke()
+exit exitCode
diff --git a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
index 1a2d53d..a95df87 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/Program.vb
@@ -18,6 +18,7 @@ Friend Module Program
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,
From bb84ee1cdb5830f90478d15c27d0b88790c79eaa Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Wed, 12 Aug 2026 21:21:41 +0200
Subject: [PATCH 08/13] feat: emit trimming and AOT-compatibility metadata
---
source/examples/Directory.Build.props | 1 +
.../FlashOWare.CommandLine.Example.CSharp.csproj | 5 +++++
.../FlashOWare.CommandLine.Example.FSharp.fsproj | 5 +++++
.../FlashOWare.CommandLine.Example.VisualBasic.vbproj | 5 +++++
source/lib/Directory.Build.props | 11 +++++++++--
5 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/source/examples/Directory.Build.props b/source/examples/Directory.Build.props
index 7d55cb4..3776bab 100644
--- a/source/examples/Directory.Build.props
+++ b/source/examples/Directory.Build.props
@@ -4,6 +4,7 @@
Condition="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../')) != ''" />
+ 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
index d25cd82..94ab511 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
@@ -17,4 +17,9 @@
+
+
+
+
+
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
index b29c347..f6ca9a7 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
@@ -22,4 +22,9 @@
+
+
+
+
+
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
index ea21746..bdea4a5 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
@@ -17,4 +17,9 @@
+
+
+
+
+
diff --git a/source/lib/Directory.Build.props b/source/lib/Directory.Build.props
index 531e0c9..173c56d 100644
--- a/source/lib/Directory.Build.props
+++ b/source/lib/Directory.Build.props
@@ -7,9 +7,16 @@
true
+
- true
- true
+ true
+ true
+
+
+
+
+ true
+ true
From 00871090632a7e49022bcb4f47aa54be6df3d45a Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Wed, 12 Aug 2026 21:32:07 +0200
Subject: [PATCH 09/13] style: remove BOM from UTF-8 encoding
---
.../FlashOWare.CommandLine.Example.CSharp.csproj | 2 +-
.../FlashOWare.CommandLine.Example.FSharp.fsproj | 2 +-
.../FlashOWare.CommandLine.Example.VisualBasic.vbproj | 2 +-
.../FlashOWare.CommandLine.Introspection.CliSchema.csproj | 2 +-
.../FlashOWare.CommandLine.Introspection.OpenCli.csproj | 2 +-
.../FlashOWare.CommandLine.Introspection.Benchmarks.csproj | 2 +-
.../FlashOWare.CommandLine.Introspection.Tests.csproj | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
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
index 94ab511..d1b95fa 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
@@ -1,4 +1,4 @@
-
+
Exe
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
index f6ca9a7..6b3db9b 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
@@ -1,4 +1,4 @@
-
+
Exe
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
index bdea4a5..b5b95b7 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
@@ -1,4 +1,4 @@
-
+
Exe
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj b/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
index 399a212..97b5bcc 100644
--- a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
+++ b/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
@@ -1,4 +1,4 @@
-
+
Library
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj b/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
index 8d2ca90..74bafe2 100644
--- a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
+++ b/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
@@ -1,4 +1,4 @@
-
+
Library
diff --git a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
index 9a7f442..8c83763 100644
--- a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
+++ b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
@@ -1,4 +1,4 @@
-
+
Exe
diff --git a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
index 0cb62ff..d38d400 100644
--- a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
+++ b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
@@ -1,4 +1,4 @@
-
+
net10.0
From c11e2842cc55249fa9cdf5f7cb01602f49708d4d Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Wed, 12 Aug 2026 21:42:08 +0200
Subject: [PATCH 10/13] build: explicit IsPackable property
---
source/examples/Directory.Build.props | 4 ++++
source/lib/Directory.Build.props | 4 ++++
source/perf/Directory.Build.props | 4 ++++
source/tests/Directory.Build.props | 8 ++++++++
4 files changed, 20 insertions(+)
diff --git a/source/examples/Directory.Build.props b/source/examples/Directory.Build.props
index 3776bab..f485270 100644
--- a/source/examples/Directory.Build.props
+++ b/source/examples/Directory.Build.props
@@ -3,6 +3,10 @@
+
+ false
+
+
true
true
diff --git a/source/lib/Directory.Build.props b/source/lib/Directory.Build.props
index 173c56d..05eca01 100644
--- a/source/lib/Directory.Build.props
+++ b/source/lib/Directory.Build.props
@@ -3,6 +3,10 @@
+
+ true
+
+
true
diff --git a/source/perf/Directory.Build.props b/source/perf/Directory.Build.props
index 4512da4..4a05b80 100644
--- a/source/perf/Directory.Build.props
+++ b/source/perf/Directory.Build.props
@@ -3,6 +3,10 @@
+
+ false
+
+
diff --git a/source/tests/Directory.Build.props b/source/tests/Directory.Build.props
index 4512da4..9229631 100644
--- a/source/tests/Directory.Build.props
+++ b/source/tests/Directory.Build.props
@@ -3,6 +3,14 @@
+
+ false
+
+
+
+ true
+
+
From cb3d9c6394ea2fefcdcee2cda02263b50b6a4ba6 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Thu, 13 Aug 2026 12:28:37 +0200
Subject: [PATCH 11/13] chore: update packages
---
source/Directory.Packages.props | 2 +-
.../FlashOWare.CommandLine.Introspection.Tests.csproj | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/source/Directory.Packages.props b/source/Directory.Packages.props
index 81d5a27..4dd23bd 100644
--- a/source/Directory.Packages.props
+++ b/source/Directory.Packages.props
@@ -10,7 +10,7 @@
-
+
diff --git a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
index d38d400..57196c5 100644
--- a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
+++ b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
@@ -1,4 +1,4 @@
-
+
net10.0
From e1e804a3dea49ba03d09f48b0e17fa487e53b432 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Thu, 20 Aug 2026 10:50:21 +0200
Subject: [PATCH 12/13] chore: rename packable projects
---
source/FlashOWare.CommandLine.slnx | 10 ++++++----
...ashOWare.CommandLine.Example.CSharp.csproj | 8 ++++----
...ashOWare.CommandLine.Example.FSharp.fsproj | 8 ++++----
...are.CommandLine.Example.VisualBasic.vbproj | 8 ++++----
.../FlashOWare.CommandLine.CliSchema.csproj} | 2 +-
.../Properties/AssemblyInfo.cs | 0
.../FlashOWare.CommandLine.OpenCli.csproj} | 2 +-
.../Properties/AssemblyInfo.cs | 0
...re.CommandLine.CliSchema.Benchmarks.csproj | 18 +++++++++++++++++
.../Program.cs | 0
.../Properties/AssemblyInfo.cs | 0
...ommandLine.Introspection.Benchmarks.csproj | 19 ------------------
...Ware.CommandLine.OpenCli.Benchmarks.csproj | 18 +++++++++++++++++
.../Program.cs | 20 +++++++++++++++++++
.../Properties/AssemblyInfo.cs | 3 +++
...shOWare.CommandLine.CliSchema.Tests.csproj | 13 ++++++++++++
.../Properties/AssemblyInfo.cs | 0
...are.CommandLine.Introspection.Tests.csproj | 14 -------------
...lashOWare.CommandLine.OpenCli.Tests.csproj | 13 ++++++++++++
.../Properties/AssemblyInfo.cs | 1 +
20 files changed, 106 insertions(+), 51 deletions(-)
rename source/lib/{FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj => FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj} (74%)
rename source/lib/{FlashOWare.CommandLine.Introspection.CliSchema => FlashOWare.CommandLine.CliSchema}/Properties/AssemblyInfo.cs (100%)
rename source/lib/{FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj => FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj} (73%)
rename source/lib/{FlashOWare.CommandLine.Introspection.OpenCli => FlashOWare.CommandLine.OpenCli}/Properties/AssemblyInfo.cs (100%)
create mode 100644 source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/FlashOWare.CommandLine.CliSchema.Benchmarks.csproj
rename source/perf/{FlashOWare.CommandLine.Introspection.Benchmarks => FlashOWare.CommandLine.CliSchema.Benchmarks}/Program.cs (100%)
rename source/perf/{FlashOWare.CommandLine.Introspection.Benchmarks => FlashOWare.CommandLine.CliSchema.Benchmarks}/Properties/AssemblyInfo.cs (100%)
delete mode 100644 source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
create mode 100644 source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/FlashOWare.CommandLine.OpenCli.Benchmarks.csproj
create mode 100644 source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Program.cs
create mode 100644 source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/Properties/AssemblyInfo.cs
create mode 100644 source/tests/FlashOWare.CommandLine.CliSchema.Tests/FlashOWare.CommandLine.CliSchema.Tests.csproj
rename source/tests/{FlashOWare.CommandLine.Introspection.Tests => FlashOWare.CommandLine.CliSchema.Tests}/Properties/AssemblyInfo.cs (100%)
delete mode 100644 source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
create mode 100644 source/tests/FlashOWare.CommandLine.OpenCli.Tests/FlashOWare.CommandLine.OpenCli.Tests.csproj
create mode 100644 source/tests/FlashOWare.CommandLine.OpenCli.Tests/Properties/AssemblyInfo.cs
diff --git a/source/FlashOWare.CommandLine.slnx b/source/FlashOWare.CommandLine.slnx
index 15a36b5..705454d 100644
--- a/source/FlashOWare.CommandLine.slnx
+++ b/source/FlashOWare.CommandLine.slnx
@@ -15,17 +15,19 @@
-
-
+
+
-
+
+
-
+
+
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
index d1b95fa..1ee3081 100644
--- a/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
+++ b/source/examples/FlashOWare.CommandLine.Example.CSharp/FlashOWare.CommandLine.Example.CSharp.csproj
@@ -13,13 +13,13 @@
-
-
+
+
-
-
+
+
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
index 6b3db9b..cc23b19 100644
--- a/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
+++ b/source/examples/FlashOWare.CommandLine.Example.FSharp/FlashOWare.CommandLine.Example.FSharp.fsproj
@@ -18,13 +18,13 @@
-
-
+
+
-
-
+
+
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
index b5b95b7..0f10238 100644
--- a/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
+++ b/source/examples/FlashOWare.CommandLine.Example.VisualBasic/FlashOWare.CommandLine.Example.VisualBasic.vbproj
@@ -13,13 +13,13 @@
-
-
+
+
-
-
+
+
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj b/source/lib/FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj
similarity index 74%
rename from source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
rename to source/lib/FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj
index 74bafe2..cdb55a5 100644
--- a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/FlashOWare.CommandLine.Introspection.OpenCli.csproj
+++ b/source/lib/FlashOWare.CommandLine.CliSchema/FlashOWare.CommandLine.CliSchema.csproj
@@ -3,7 +3,7 @@
Library
net10.0
- FlashOWare.CommandLine.Introspection.OpenCli
+ FlashOWare.CommandLine.CliSchema
FlashOWare.CommandLine
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/Properties/AssemblyInfo.cs b/source/lib/FlashOWare.CommandLine.CliSchema/Properties/AssemblyInfo.cs
similarity index 100%
rename from source/lib/FlashOWare.CommandLine.Introspection.CliSchema/Properties/AssemblyInfo.cs
rename to source/lib/FlashOWare.CommandLine.CliSchema/Properties/AssemblyInfo.cs
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj b/source/lib/FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj
similarity index 73%
rename from source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
rename to source/lib/FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj
index 97b5bcc..386e7c2 100644
--- a/source/lib/FlashOWare.CommandLine.Introspection.CliSchema/FlashOWare.CommandLine.Introspection.CliSchema.csproj
+++ b/source/lib/FlashOWare.CommandLine.OpenCli/FlashOWare.CommandLine.OpenCli.csproj
@@ -3,7 +3,7 @@
Library
net10.0
- FlashOWare.CommandLine.Introspection.CliSchema
+ FlashOWare.CommandLine.OpenCli
FlashOWare.CommandLine
diff --git a/source/lib/FlashOWare.CommandLine.Introspection.OpenCli/Properties/AssemblyInfo.cs b/source/lib/FlashOWare.CommandLine.OpenCli/Properties/AssemblyInfo.cs
similarity index 100%
rename from source/lib/FlashOWare.CommandLine.Introspection.OpenCli/Properties/AssemblyInfo.cs
rename to source/lib/FlashOWare.CommandLine.OpenCli/Properties/AssemblyInfo.cs
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..c7df831
--- /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.CliSchema.Benchmarks
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Program.cs b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Program.cs
similarity index 100%
rename from source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Program.cs
rename to source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Program.cs
diff --git a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Properties/AssemblyInfo.cs b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Properties/AssemblyInfo.cs
similarity index 100%
rename from source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/Properties/AssemblyInfo.cs
rename to source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/Properties/AssemblyInfo.cs
diff --git a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj b/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
deleted file mode 100644
index 8c83763..0000000
--- a/source/perf/FlashOWare.CommandLine.Introspection.Benchmarks/FlashOWare.CommandLine.Introspection.Benchmarks.csproj
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Exe
- net10.0
- FlashOWare.CommandLine.Introspection.Benchmarks
- FlashOWare.CommandLine.Benchmarks
-
-
-
-
-
-
-
-
-
-
-
-
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..c9ab746
--- /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.OpenCli.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/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..35da442
--- /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.CliSchema.Tests
+
+
+
+
+
+
+
diff --git a/source/tests/FlashOWare.CommandLine.Introspection.Tests/Properties/AssemblyInfo.cs b/source/tests/FlashOWare.CommandLine.CliSchema.Tests/Properties/AssemblyInfo.cs
similarity index 100%
rename from source/tests/FlashOWare.CommandLine.Introspection.Tests/Properties/AssemblyInfo.cs
rename to source/tests/FlashOWare.CommandLine.CliSchema.Tests/Properties/AssemblyInfo.cs
diff --git a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj b/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
deleted file mode 100644
index 57196c5..0000000
--- a/source/tests/FlashOWare.CommandLine.Introspection.Tests/FlashOWare.CommandLine.Introspection.Tests.csproj
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- net10.0
- FlashOWare.CommandLine.Introspection.Tests
- FlashOWare.CommandLine.Tests
-
-
-
-
-
-
-
-
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..4172878
--- /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.OpenCli.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)]
From 3045e39491dcd9da681f288c66d5651cd15835f3 Mon Sep 17 00:00:00 2001
From: Flash0ver <38893694+Flash0ver@users.noreply.github.com>
Date: Thu, 20 Aug 2026 22:48:19 +0200
Subject: [PATCH 13/13] chore: move root namespace
---
.../FlashOWare.CommandLine.CliSchema.Benchmarks.csproj | 2 +-
.../FlashOWare.CommandLine.OpenCli.Benchmarks.csproj | 2 +-
.../FlashOWare.CommandLine.CliSchema.Tests.csproj | 2 +-
.../FlashOWare.CommandLine.OpenCli.Tests.csproj | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
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
index c7df831..b7f9d1c 100644
--- a/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/FlashOWare.CommandLine.CliSchema.Benchmarks.csproj
+++ b/source/perf/FlashOWare.CommandLine.CliSchema.Benchmarks/FlashOWare.CommandLine.CliSchema.Benchmarks.csproj
@@ -4,7 +4,7 @@
Exe
net10.0
FlashOWare.CommandLine.CliSchema.Benchmarks
- FlashOWare.CommandLine.CliSchema.Benchmarks
+ FlashOWare.CommandLine.Benchmarks
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
index c9ab746..73e8aca 100644
--- a/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/FlashOWare.CommandLine.OpenCli.Benchmarks.csproj
+++ b/source/perf/FlashOWare.CommandLine.OpenCli.Benchmarks/FlashOWare.CommandLine.OpenCli.Benchmarks.csproj
@@ -4,7 +4,7 @@
Exe
net10.0
FlashOWare.CommandLine.OpenCli.Benchmarks
- FlashOWare.CommandLine.OpenCli.Benchmarks
+ FlashOWare.CommandLine.Benchmarks
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
index 35da442..4a6c213 100644
--- a/source/tests/FlashOWare.CommandLine.CliSchema.Tests/FlashOWare.CommandLine.CliSchema.Tests.csproj
+++ b/source/tests/FlashOWare.CommandLine.CliSchema.Tests/FlashOWare.CommandLine.CliSchema.Tests.csproj
@@ -3,7 +3,7 @@
net10.0
FlashOWare.CommandLine.CliSchema.Tests
- FlashOWare.CommandLine.CliSchema.Tests
+ FlashOWare.CommandLine.Tests
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
index 4172878..b6b144f 100644
--- a/source/tests/FlashOWare.CommandLine.OpenCli.Tests/FlashOWare.CommandLine.OpenCli.Tests.csproj
+++ b/source/tests/FlashOWare.CommandLine.OpenCli.Tests/FlashOWare.CommandLine.OpenCli.Tests.csproj
@@ -3,7 +3,7 @@
net10.0
FlashOWare.CommandLine.OpenCli.Tests
- FlashOWare.CommandLine.OpenCli.Tests
+ FlashOWare.CommandLine.Tests