Skip to content

Commit ea9f048

Browse files
committed
Document 2.0 contracts and migration guidance
1 parent cbf4cc8 commit ea9f048

8 files changed

Lines changed: 107 additions & 3 deletions

File tree

doc/advanced.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ var result = app.Parse(["--name", "Alice", "--port", "8080"]);
4949
- Help/version requests are surfaced via `HelpRequested`/`VersionRequested`.
5050
- Errors are collected in `Errors` instead of being written to stderr.
5151
- If `runConfig` is null, `Out` and `Error` default to `TextWriter.Null` to suppress output.
52+
- Parsing mutates per-run option state (`WasSet` tracking), so command graphs are intended for one invocation at a time.
53+
54+
### Invocation Concurrency Contract
55+
56+
- Command graphs are **not thread-safe for concurrent `RunAsync`/`Parse` calls** on the same command tree.
57+
- Sequential invocations on the same graph are supported.
58+
- Create separate command graph instances if you need true parallel invocations.
5259

5360
### Testing Sub-Commands
5461

doc/help-output.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,14 @@ The `CommandOutputHelper` class provides utility methods for building custom ren
252252
- `GetOptionValueName(option, valueIndex)` — value placeholder name
253253
- `GetDescriptionText(description)` — processed description text
254254

255+
## Descriptor Contracts
256+
257+
For custom outputs and custom command nodes, the following contracts apply:
258+
259+
- `ICommandNodeDescriptor.Description` should be plain help text intent (not renderer-specific markup).
260+
- `IHelpPreformattedContent.WriteTo(...)` is the preformatted contract for verbatim text output.
261+
- If a node provides both interfaces, text outputs should prefer `IHelpPreformattedContent` and use `Description` as fallback when preformatted rendering is not supported.
262+
255263
## Terminal Package
256264

257265
For rich colored and visual help output, install the optional `XenoAtom.CommandLine.Terminal` package:

doc/migration-2.0.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Migration Guide — 2.0
2+
3+
This guide summarizes the 2.0 API changes that require code updates.
4+
5+
## Breaking Renames
6+
7+
| 1.x | 2.0 |
8+
|---|---|
9+
| `OptionException` | `CommandOptionException` |
10+
| `CommandNode.IsThisNodeActive` | `CommandNode.ActivePredicate` |
11+
| `Command.OptionsName` | `Command.OptionsSectionName` |
12+
13+
## `ICommandOutput` Unknown Token API
14+
15+
`WriteUnknownTokens` now receives a single report object:
16+
17+
```csharp
18+
void WriteUnknownTokens(Command command, CommandRunConfig runConfig, UnknownTokenReport report);
19+
```
20+
21+
`UnknownTokenReport` includes:
22+
- `Kind`
23+
- `UnknownTokens`
24+
- `InvocationTokens` (when available)
25+
26+
Update custom outputs to use `report.Kind`, `report.UnknownTokens`, and `report.InvocationTokens`.
27+
28+
## Metadata Mutability Changes
29+
30+
These members now use construction-time initialization:
31+
32+
- `Command.Hidden` (`init`)
33+
- `Command.OptionsSectionName` (`init`)
34+
- `Option.EnvironmentVariable` (`init`)
35+
- `Option.EnvironmentVariableDelimiter` (`init`)
36+
37+
### Before
38+
39+
```csharp
40+
var hidden = new Command("secret");
41+
hidden.Hidden = true;
42+
43+
app.Options["name"].EnvironmentVariable = "APP_NAME";
44+
```
45+
46+
### After
47+
48+
```csharp
49+
var hidden = new Command("secret")
50+
{
51+
Hidden = true
52+
};
53+
54+
app.Add("n|name=", "Name", value => { }, envVar: "APP_NAME");
55+
```
56+
57+
## New Clarity Helpers
58+
59+
The following helpers were added to reduce overload ambiguity and improve intent:
60+
61+
- `AddRemainder(string? description = null)`
62+
- `AddText(string text)`
63+
- `AddSection(string header)` (auto-appends `:` when missing)
64+
65+
## Overload Parity Additions
66+
67+
Typed and list families now support `hidden` parity:
68+
69+
- `Add<T>(..., Action<T> action, bool hidden)`
70+
- `Add<T>(..., ICollection<T> list, bool hidden)`
71+
- Validation and env-var variants with `hidden` support are available for typed/list overloads.
72+
73+
## Notes
74+
75+
- Key/value (`Action<TKey, TValue>`) overloads intentionally still do **not** support env-var fallback or validation delegates.
76+
- Command graphs remain single-invocation-at-a-time; avoid concurrent `RunAsync`/`Parse` on the same graph instance.

doc/options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ Options can be hidden from help output:
265265
```
266266

267267
Hidden options are still functional — they just don't appear in `--help`.
268+
Set metadata (`hidden`, `envVar`, `envVarDelimiter`) while declaring options; these settings are part of construction-time configuration.
268269

269270
## Environment Variable Fallback
270271

doc/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ await app.RunAsync(args);
3434
| [Validation & Constraints](validation.md) | Value validation (`Validate.Range`, `Validate.NonEmpty`, `Validate.FileExists`, …), mutually exclusive options, requires constraints |
3535
| [Help & Output](help-output.md) | Help text, `CommandUsage`, custom `ICommandOutput` rendering, Terminal markup and visual output |
3636
| [Advanced Topics](advanced.md) | Parse API for testing, shell completions, response files, `CommandConfig`, `CommandRunConfig`, localization, `EnumWrapper<T>`, NativeAOT, performance |
37+
| [Migration 2.0](migration-2.0.md) | Breaking changes and upgrade checklist from 1.x |
3738

3839
## Quick Links
3940

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ Notes:
110110
- `CommandUsage()` defaults to `Usage: {NAME} {SYNTAX}` and `{SYNTAX}` is derived from your declared options/commands/arguments.
111111
- Positional arguments are strict by default: declare `<arg>` / `<arg>?` / `<arg>*` / `<arg>+`, or declare `<>` to forward remaining arguments to the command action.
112112
- Convenience helpers are available when not using collection initializers: `AddRemainder(...)`, `AddSection(...)`, and `AddText(...)`.
113+
- A command graph instance is intended for one invocation at a time (`RunAsync`/`Parse` are not concurrent-safe on the same graph).
113114

114115
Running `myexe --help` will output:
115116

@@ -227,6 +228,7 @@ Example of the advanced sample with an error:
227228
| [Validation & Constraints](doc/validation.md) | Value validation, mutually exclusive options, requires constraints |
228229
| [Help & Output](doc/help-output.md) | Help text, `CommandUsage`, custom output rendering, Terminal package |
229230
| [Advanced Topics](doc/advanced.md) | Parse API, shell completions, response files, configuration, environment variables, performance |
231+
| [Migration 2.0](doc/migration-2.0.md) | Breaking changes and upgrade steps |
230232

231233
## 🏗️ Build
232234

src/XenoAtom.CommandLine/ICommandNodeDescriptor.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
namespace XenoAtom.CommandLine;
66

77
/// <summary>
8-
/// Interface used to add a description to a <see cref="CommandNode"/>>.
8+
/// Provides plain-text help description intent for a <see cref="CommandNode"/>.
99
/// </summary>
1010
public interface ICommandNodeDescriptor
1111
{
1212
/// <summary>
13-
/// Gets the description of this command node (option, command...).
13+
/// Gets the plain help text associated with this node.
1414
/// </summary>
15+
/// <remarks>
16+
/// This text should represent semantic help content (for example command/option/argument descriptions)
17+
/// and should not contain renderer-specific markup.
18+
/// </remarks>
1519
string? Description { get; }
16-
}
20+
}

src/XenoAtom.CommandLine/IHelpPreformattedContent.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ namespace XenoAtom.CommandLine;
99
/// <summary>
1010
/// Provides preformatted help content that should be written verbatim.
1111
/// </summary>
12+
/// <remarks>
13+
/// When a node implements both <see cref="IHelpPreformattedContent"/> and <see cref="ICommandNodeDescriptor"/>,
14+
/// text outputs should prefer <see cref="WriteTo"/> and use descriptor text as fallback only when preformatted
15+
/// rendering is not supported.
16+
/// </remarks>
1217
public interface IHelpPreformattedContent
1318
{
1419
/// <summary>

0 commit comments

Comments
 (0)