Skip to content

feat(cli): add --version - #195

Merged
HandyS11 merged 2 commits into
developfrom
feat/cli-version-flag
Sep 15, 2026
Merged

HandyS11 merged 2 commits into
developfrom
feat/cli-version-flag

Conversation

@HandyS11

Copy link
Copy Markdown
Owner

Summary

projgraph --version (and -v) failed with Unexpected option 'version' because no application version was configured. It has never worked, including in v1.1.0. I noticed it while checking the v1.2.0-beta.1 install.

$ projgraph --version
1.2.0-beta.1
  • Program.cs: sets the application version from the CLI assembly's AssemblyInformationalVersionAttribute, without the +<commit> build metadata. --help now lists -v, --version.
    • It doesn't use Spectre's UseAssemblyInformationalVersion(), which reads Assembly.GetEntryAssembly() (the test host under tests) and keeps the +37abcac… suffix.
  • Program.Configure: the app configuration moves out of the Main lambda into this method, with no behaviour change. The test then runs the real configuration against a TestConsole, not through Program.Main, because StrictParsingTests must stay the only test that reaches Spectre's cached default console.
  • CLI README: mentions projgraph --version after the install command.

Tests

  • VersionOptionTests (--version and -v): exit code 0, a plain package version with no + metadata, starting with the CLI assembly's version. It failed first with the same Unexpected option error as the published beta.
  • CliParityTests.Version_ShouldMatchReference: native vs JIT parity, because the version comes from an assembly attribute the AOT build must keep.

Test plan

  • dtk dotnet test ProjGraph.slnx: 1180 passed
  • Local dotnet publish -r linux-x64 (Native AOT) with -p:Version=1.2.0-beta.2: prints 1.2.0-beta.2 for --version and -v
  • Smoke suite locally against that native binary: Version_ShouldMatchReference, both Help_* tests and Stats_UnknownOption pass
  • aot-smoke CI job

🤖 Generated with Claude Code

`projgraph --version` and `-v` failed with "Unexpected option" because
no application version was configured. The CLI now prints the package
version, e.g. 1.2.0-beta.1, without the +commit build metadata the SDK
appends to the informational version.

The version is read from the CLI assembly rather than through Spectre's
UseAssemblyInformationalVersion, which reads the entry assembly (the
test host under tests) and keeps the build metadata.

Program's app configuration moves into Program.Configure, so the new
test runs the real configuration against a TestConsole instead of
Spectre's cached default console. The AOT smoke suite also compares
--version between the native and JIT builds.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 15, 2026 11:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

There are build/runtime safety issues in the new code (unused using and a null-forgiving reflection path that can crash --version) that should be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds first-class CLI version reporting by configuring Spectre.Console.Cli’s application version from the CLI assembly’s informational version (with +<commit> build metadata trimmed), and extends test coverage to ensure the option works and remains Native AOT–safe.

Changes:

  • Configure projgraph’s application version (enabling -v, --version) using the CLI assembly’s AssemblyInformationalVersionAttribute, trimming build metadata.
  • Refactor CLI command registration into Program.Configure so tests can run real app configuration against a TestConsole.
  • Add integration + AOT smoke tests for --version/-v, and document the option in the CLI README.
File summaries
File Description
tests/ProjGraph.Tests.Smoke.Aot/CliParityTests.cs Adds AOT parity coverage for --version output presence and parity.
tests/ProjGraph.Tests.Integration.Cli/VersionOptionTests.cs Adds integration tests asserting --version/-v succeed and print a plain SemVer without + metadata.
src/ProjGraph.Cli/README.md Documents projgraph --version after installation.
src/ProjGraph.Cli/Program.cs Sets application version and extracts shared CLI configuration into Program.Configure; adds version trimming helper.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/ProjGraph.Cli/Program.cs Outdated
Comment on lines +83 to +87
var version = typeof(Program).Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!.InformationalVersion;
var metadataStart = version.IndexOf('+', StringComparison.Ordinal);
return metadataStart < 0 ? version : version[..metadataStart];
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 160abd9. The SDK always generates the attribute, but the impact was wider than --version: Configure runs for every command, so a missing attribute would have broken them all. GetPackageVersion now takes the assembly and falls back to GetName().Version (2.3.4 for 2.3.4.5) before trimming the build metadata. GetPackageVersion_WithoutInformationalVersionAttribute_FallsBackToTheAssemblyVersion covers it with a dynamic assembly that has no attributes; before the fix it failed with the NullReferenceException you described.

Comment on lines +1 to +5
using ProjGraph.Cli;
using Spectre.Console.Cli;
using Spectre.Console.Testing;
using System.Reflection;
using System.Text.RegularExpressions;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

It was unused in the reviewed commit. The fallback test added in 160abd9 now needs it (AssemblyName), so it stays. For the record, CS8019 is a hidden diagnostic, so it doesn't fail the build under TreatWarningsAsErrors.

… attribute

Program.Configure runs for every command, so the null-forgiving attribute
lookup would have failed all of them, not only --version, in a build
without AssemblyInformationalVersionAttribute. GetPackageVersion now
takes the assembly and falls back to its version. A test covers the
fallback with a dynamic assembly that has no attributes; the test's
System.Reflection using is needed for it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@HandyS11
HandyS11 merged commit f4c3654 into develop Sep 15, 2026
14 checks passed
@HandyS11
HandyS11 deleted the feat/cli-version-flag branch September 15, 2026 12:04
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.

2 participants