Skip to content

Adopt POSIX-style CLI arguments#4840

Open
arturcic wants to merge 24 commits intoGitTools:next/v7from
arturcic:feature/posix-argument-parser
Open

Adopt POSIX-style CLI arguments#4840
arturcic wants to merge 24 commits intoGitTools:next/v7from
arturcic:feature/posix-argument-parser

Conversation

@arturcic
Copy link
Member

@arturcic arturcic commented Mar 3, 2026

Description

Introduces a new command-line argument parser that adopts POSIX-style --long-name arguments and short aliases. This change updates all internal GitVersion usages and documentation, while retaining the legacy parser for backward compatibility.

Related Issue

Fixes #4844

Motivation and Context

Modernize the command-line interface for GitVersion, providing a more consistent and standardized argument parsing experience using POSIX conventions. This improves usability and alignment with current CLI best practices.

How Has This Been Tested?

Integration tests were updated, and new dedicated tests for both the POSIX-style and the legacy argument parsers were added to confirm functionality and backward compatibility.

Screenshots (if appropriate):

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Copilot AI review requested due to automatic review settings March 3, 2026 12:05
@arturcic arturcic added this to the 7.x milestone Mar 3, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the GitVersion CLI by adopting POSIX-style --long-name arguments with short aliases (e.g., -l, -b). It introduces a new ArgumentParser backed by System.CommandLine and retains the existing logic as LegacyArgumentParser for backward compatibility. All internal usages, tests, build scripts, and documentation are updated to use the new argument style.

Changes:

  • Introduces a new POSIX-style ArgumentParser using System.CommandLine and moves the old logic to LegacyArgumentParser.
  • Updates all internal invocations, build scripts, and tests to use the new --long-name argument style.
  • Updates documentation and arguments.md help text to reflect the new CLI argument conventions.

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/GitVersion.App/ArgumentParser.cs Core rewrite to use System.CommandLine for POSIX-style argument parsing
src/GitVersion.App/LegacyArgumentParser.cs Old ArgumentParser logic preserved as LegacyArgumentParser
src/GitVersion.App/GitVersionAppModule.cs DI registration updated to conditionally wire legacy or new parser
src/GitVersion.App/HelpWriter.cs Method renamed to match legacy context
src/GitVersion.App/GitVersion.App.csproj Adds System.CommandLine package reference
src/Directory.Packages.props Adds System.CommandLine version entry
src/GitVersion.App.Tests/ArgumentParserTests.cs Tests updated to new POSIX-style arguments
src/GitVersion.App.Tests/LegacyArgumentParserTests.cs New test file covering legacy parser behavior
src/GitVersion.App.Tests/HelpWriterTests.cs Updated to use legacy parser and new argument format
src/GitVersion.App.Tests/ExecCmdLineArgumentTest.cs Integration tests updated to new argument style
src/GitVersion.App.Tests/JsonOutputOnBuildServerTest.cs Integration tests updated to new argument style
src/GitVersion.App.Tests/UpdateWixVersionFileTests.cs Integration tests updated to new argument style
src/GitVersion.App.Tests/Helpers/ArgumentBuilder.cs Helper updated to new argument style
src/GitVersion.App.Tests/Helpers/ProgramFixture.cs Fixture updated to new argument style
src/GitVersion.App.Tests/VersionWriterTests.cs Updated to use legacy parser
src/GitVersion.MsBuild/msbuild/tools/GitVersion.MsBuild.props Partially updated to new argument style
build/common/Addins/GitVersion/GitVersionRunner.cs Build addin arguments updated
build/common/Utilities/DockerContextExtensions.cs Docker test arguments updated
build/build/Tasks/ValidateVersion.cs Validation task argument updated
build/build/Tasks/Package/PackagePrepare.cs Package prepare argument updated
tests/scripts/test-native-tool.sh Shell script updated to new argument style
tests/scripts/test-global-tool.sh Shell script updated to new argument style
docs/input/docs/usage/cli/arguments.md CLI argument documentation updated
docs/input/docs/usage/cli/output.md Output documentation updated
docs/input/docs/usage/cli/assembly-patch.md Assembly patch documentation updated
docs/input/docs/reference/configuration.md Configuration docs updated
docs/input/docs/reference/mdsource/configuration.source.md Source config docs updated
docs/input/docs/reference/build-servers/*.md Build server docs updated
docs/input/docs/learn/dynamic-repositories.md Dynamic repositories docs updated

@arturcic arturcic marked this pull request as draft March 3, 2026 12:13
@arturcic arturcic force-pushed the feature/posix-argument-parser branch 4 times, most recently from 94d4c2a to b7fa4c0 Compare March 3, 2026 13:00
@arturcic arturcic requested a review from Copilot March 3, 2026 14:38
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 39 out of 39 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (5)

src/GitVersion.App/CliHost.cs:1

  • The logic is inverted. The env var is named USE_V6_ARGUMENT_PARSER, but the code maps it to useLegacyParser = true. "V6" refers to the new parser, while the legacy parser is the pre-v6 style. Setting USE_V6_ARGUMENT_PARSER=true should select the new parser, but instead it selects the legacy parser. The variable name and the assignment are contradictory. Either rename the env var to USE_LEGACY_ARGUMENT_PARSER, or invert the assignment to useLegacyParser = !string.Equals(envValue, "true", ...).
    src/GitVersion.App/ArgumentParser.cs:1
  • The /? check here will never be satisfied because in the new POSIX-style parser, /? is not a registered argument and will be caught as an unrecognized token error earlier, or it would be treated as a path argument. More critically, /? is a legacy Windows-style help argument that the new parser should not need to handle. Keeping it here creates an inconsistency: the -- prefix convention is being adopted, but /? is silently accepted as a help trigger in the new parser.
    src/GitVersion.App/ArgumentParser.cs:1
  • The short alias -c is now assigned to --config, but according to BREAKING_CHANGES.md, -c previously referred to the commit id. The breaking changes document this reassignment and marks it as critical. However, the --commit option defined on line 329 has no short alias, which matches the table, but this means any existing scripts using -c <commit-id> (which was documented in the old CLI and appears in several legacy parsers) will silently be interpreted as config file path instead of commit id. This is a silent semantic change that will be very difficult to diagnose. Consider at minimum a runtime warning when -c is used without a value that looks like a file path.
    src/GitVersion.App/ArgumentParser.cs:1
  • Blocking on InvokeAsync() with .GetAwaiter().GetResult() in what may be a synchronous call context can lead to deadlocks, particularly in environments with a synchronization context (e.g., certain test runners or UI frameworks). Since this method is on a code path that simply needs to print help and return, consider using a synchronous invoke or ensuring the call chain is truly async-safe.
    src/GitVersion.App/ArgumentParser.cs:1
  • The version option is defined and added to the RootCommand, but it is never read back via parseResult.GetValue(options.Version) in MapParsedValues. The --version handling is done earlier via a manual Any() check before parsing, which means the option is effectively dead in the command schema. Having an unused declared option in the schema may confuse System.CommandLine's own --version handling (it has a built-in --version option concept), and could cause conflicts or unexpected behavior.

@arturcic arturcic force-pushed the feature/posix-argument-parser branch from 57b99f2 to 0075eeb Compare March 3, 2026 14:52
@arturcic arturcic force-pushed the feature/posix-argument-parser branch 2 times, most recently from c9a2529 to 0cb892a Compare March 4, 2026 10:41
@arturcic arturcic force-pushed the feature/posix-argument-parser branch from 9752a3b to 7ca8fad Compare March 4, 2026 14:03
@arturcic arturcic marked this pull request as ready for review March 4, 2026 22:35
arturcic added 12 commits March 5, 2026 16:20
Renames the `SystemCommandLineArgumentParser` class and file to `ArgumentParser` for improved clarity. Applies minor code improvements like using the null-conditional operator and sealing the `CommandOptions` record.
Introduce lazy initialization for the System.CommandLine schema to improve performance on subsequent argument parsing calls. Refactors the ArgumentParser for enhanced efficiency.
Migrates GitVersion command-line arguments to use double-dash long options for improved clarity and consistency with modern CLI standards.
Introduce an environment variable to switch between argument parser implementations.
arturcic added 9 commits March 5, 2026 16:20
Include details on the POSIX-style CLI arguments
Adds tests to confirm -c maps to --config and --commit sets the commit ID, aligning with updated parser behavior.
Add a new `arguments.md` file detailing POSIX-style CLI arguments. Create separate run configurations to facilitate testing both existing and new argument parsing behaviors.
Ensures HelpWriterTests correctly asserts /switch argument syntax when configured for the legacy parser.
Improve clarity and detail of argument descriptions in the CLI parser. Configure help system to wrap text for better readability in large outputs.
@arturcic arturcic force-pushed the feature/posix-argument-parser branch from f3ae6db to 4f0e272 Compare March 5, 2026 15:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 49 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (6)

src/GitVersion.App/CliHost.cs:1

  • The environment variable name USE_V6_ARGUMENT_PARSER is a magic string duplicated across CliHost.cs, the run configurations, BREAKING_CHANGES.md, and the migration guide. Consider extracting it to a named constant (e.g., in a CliConstants class) to make future renames easier and reduce the risk of typos.
    src/GitVersion.App/GitVersionAppModule.cs:1
  • When useLegacyParser is false (the new ArgumentParser is used), IHelpWriter and IVersionWriter are never registered. However, ArgumentParser itself no longer depends on them (they were removed from its constructor in this PR), so anything else in the DI container that may require IHelpWriter or IVersionWriter (e.g., tests that resolve IHelpWriter directly via ConfigureServices) will fail to resolve. HelpWriterTests and VersionWriterTests already pass useLegacyParser: true, but any future consumer using the default module without the legacy flag will be missing these registrations. Consider always registering IHelpWriter and IVersionWriter, or at minimum registering them outside the if/else block.
    src/GitVersion.App/ArgumentParser.cs:1
  • The short alias -c is now mapped to --config (config file path), whereas in v6 it was mapped to the commit ID. This is documented as a breaking change, but the alias collision means users who muscle-memory -c <commit> will silently set the config file path instead, which could produce confusing behavior rather than an error. Consider omitting the -c short alias for --config so users are forced to use --config explicitly and -c <commit> triggers an "unrecognized option" error instead of silently misrouting.
    src/GitVersion.App/LegacyArgumentParser.cs:1
  • This error message uses the old -ensureassemblyinfo / updateprojectfiles switch names rather than the legacy /ensureassemblyinfo / /updateprojectfiles style that the legacy parser uses throughout. For consistency within the legacy parser, all switch references in error messages should use the /switch form (as seen elsewhere in this file, e.g., line 424).
    src/GitVersion.App.Tests/LegacyArgumentParserTests.cs:1
  • This assertion expects the message from ParseUpdateAssemblyInfo (line 520 of LegacyArgumentParser.cs), but the test case "-updateAssemblyInfo Assembly.cs Assembly1.cs -ensureassemblyinfo" actually triggers ParseEnsureAssemblyInfo last (because -ensureassemblyinfo is parsed after -updateAssemblyInfo). ParseEnsureAssemblyInfo at line 424 throws the same message with /ensureassemblyinfo wording, so the test should still pass — however the path through ParseUpdateAssemblyInfo at line 520 uses -ensureassemblyinfo (different from the expected /ensureassemblyinfo). Verify which code path is actually exercised and ensure the expected message string exactly matches the thrown exception to avoid a false-passing test.
    src/GitVersion.App/HelpWriter.cs:1
  • C# raw string literal indentation stripping uses the column of the closing """ as the baseline. The closing """ is indented by 23 spaces, so 23 spaces will be stripped from each interpolated line. If args contains lines with less than 23 leading spaces (or lines that use different indentation), those lines will either be trimmed incorrectly or cause a compile error. The version variable and any blank lines in args should be unaffected, but multi-line content in args read from the markdown stream may not align to this indentation baseline. Consider using a simple string concatenation or string.Format to avoid the raw-literal indentation pitfall.

@arturcic arturcic linked an issue Mar 5, 2026 that may be closed by this pull request
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 5, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Track migration to POSIX-style CLI arguments

3 participants