From 51f7d645a13346bb6c1310aff74ebd5921d7b00c Mon Sep 17 00:00:00 2001 From: glopesdev Date: Mon, 14 Sep 2026 17:49:04 +0100 Subject: [PATCH] Take the firmware file as an update argument The firmware path is now the argument of the update command, matching how generate takes its metadata path, so the required input needs no option name at all. --path is kept as a hidden option for one version, and a parse-time validator rejects supplying both rather than preferring one, since a script migrating half way would otherwise flash a different file. Option descriptions follow the imperative voice for actions and a noun phrase for values, and --output no longer repeats a default that System.CommandLine already renders. That default is now constructed from a relative path, so help shows it as a dot. --- docs/README.md | 2 +- docs/articles/verify.md | 6 ++-- src/Harp.Toolkit/DevicePortNameOption.cs | 2 +- .../Generate/GenerateFirmwareCommand.cs | 2 +- src/Harp.Toolkit/Generate/OutputPathOption.cs | 4 +-- src/Harp.Toolkit/PortTimeoutOption.cs | 2 +- src/Harp.Toolkit/UpdateFirmwareCommand.cs | 33 +++++++++++++++---- 7 files changed, 35 insertions(+), 16 deletions(-) diff --git a/docs/README.md b/docs/README.md index 387985a..cd8ef6c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,7 +35,7 @@ Tool for inspecting, updating and interfacing with Harp devices, with automatic 6. To update the device firmware from a local HEX file: ```cmd - dotnet harp.toolkit update --port COM4 --path Behavior-fw3.2-harp1.13-hw2.0-ass0.hex + dotnet harp.toolkit update --port COM4 Behavior-fw3.2-harp1.13-hw2.0-ass0.hex ``` 7. To restore the tool at any point, run: diff --git a/docs/articles/verify.md b/docs/articles/verify.md index 8105f1c..09f1800 100644 --- a/docs/articles/verify.md +++ b/docs/articles/verify.md @@ -24,7 +24,7 @@ Verification stops at the first request left unanswered for 2000 ms, since a lat --port ``` -Specifies the name of the serial port used to communicate with the device. This option is required. +Name of the serial port used to communicate with the device. This option is required. #### Detailed results ```ps1 @@ -74,7 +74,7 @@ The report is titled with the device name and opens with a header describing the --report ``` -Path of the HTML report written after the run. Without it the results are printed and not saved. +Path to the HTML report written after the run. Without it the results are printed and not saved. ### Acting on a reported failure @@ -126,6 +126,6 @@ dotnet harp.toolkit verify --port COM3 --metadata device.yml --metadata ``` -Path of the file describing the device registers. The file must exist. +Path to the file describing the device registers. The file must exist. Unlike code generation, this option has no default, so a `device.yml` located in the current directory does not automatically enable these checks. diff --git a/src/Harp.Toolkit/DevicePortNameOption.cs b/src/Harp.Toolkit/DevicePortNameOption.cs index 8b445ee..516486b 100644 --- a/src/Harp.Toolkit/DevicePortNameOption.cs +++ b/src/Harp.Toolkit/DevicePortNameOption.cs @@ -5,7 +5,7 @@ public class DevicePortNameOption : PortNameOption public DevicePortNameOption() : base("--port") { - Description = "Specifies the name of the serial port used to communicate with the device."; + Description = "Name of the serial port used to communicate with the device."; Required = true; } } diff --git a/src/Harp.Toolkit/Generate/GenerateFirmwareCommand.cs b/src/Harp.Toolkit/Generate/GenerateFirmwareCommand.cs index 78f42d6..c3b70c7 100644 --- a/src/Harp.Toolkit/Generate/GenerateFirmwareCommand.cs +++ b/src/Harp.Toolkit/Generate/GenerateFirmwareCommand.cs @@ -14,7 +14,7 @@ public GenerateFirmwareCommand() Option generateImplementationOption = new("--implementation") { - Description = "Indicates whether to generate implementation (.c) files. The default is false." + Description = "Generate implementation (.c) files. The default is false." }; Arguments.Add(metadataPathArgument); diff --git a/src/Harp.Toolkit/Generate/OutputPathOption.cs b/src/Harp.Toolkit/Generate/OutputPathOption.cs index bb54983..cc9da96 100644 --- a/src/Harp.Toolkit/Generate/OutputPathOption.cs +++ b/src/Harp.Toolkit/Generate/OutputPathOption.cs @@ -7,7 +7,7 @@ public class OutputPathOption : Option public OutputPathOption() : base("-o", "--output") { - Description = "Location to place the generated output. The default is the current directory."; - DefaultValueFactory = _ => new DirectoryInfo(Environment.CurrentDirectory); + Description = "Location to place the generated output."; + DefaultValueFactory = _ => new DirectoryInfo("."); } } diff --git a/src/Harp.Toolkit/PortTimeoutOption.cs b/src/Harp.Toolkit/PortTimeoutOption.cs index f158957..bbb615e 100644 --- a/src/Harp.Toolkit/PortTimeoutOption.cs +++ b/src/Harp.Toolkit/PortTimeoutOption.cs @@ -7,7 +7,7 @@ public class PortTimeoutOption : Option public PortTimeoutOption() : base("--timeout") { - Description = "Specifies the timeout, in milliseconds, to receive a response from the device. Use -1 to wait indefinitely."; + Description = "Timeout in milliseconds to receive a response from the device. Use -1 to wait indefinitely."; DefaultValueFactory = _ => 2000; Validators.Add(result => { diff --git a/src/Harp.Toolkit/UpdateFirmwareCommand.cs b/src/Harp.Toolkit/UpdateFirmwareCommand.cs index 7f89a93..5d41f9e 100644 --- a/src/Harp.Toolkit/UpdateFirmwareCommand.cs +++ b/src/Harp.Toolkit/UpdateFirmwareCommand.cs @@ -9,23 +9,42 @@ public UpdateFirmwareCommand() : base("update", "Update the device firmware from a local HEX file.") { DevicePortNameOption portNameOption = new(); - Option firmwarePathOption = new("--path") - { - Description = "Specifies the path of the firmware file to write to the device.", - Required = true - }; + Argument firmwareArgument = ArgumentValidation.AcceptExistingOnly( + new Argument("firmware") + { + Description = "Path to the firmware file.", + Arity = ArgumentArity.ZeroOrOne + }); + + Option firmwarePathOption = OptionValidation.AcceptExistingOnly( + new Option("--path") + { + Description = "Path to the firmware file.", + Hidden = true + }); Option forceUpdateOption = new("--force") { - Description = "Indicates whether to force a firmware update on the device regardless of compatibility." + Description = "Force a firmware update regardless of compatibility." }; + Arguments.Add(firmwareArgument); Options.Add(portNameOption); Options.Add(firmwarePathOption); Options.Add(forceUpdateOption); + Validators.Add(result => + { + var hasArgument = result.GetResult(firmwareArgument) is not null; + var hasOption = result.GetResult(firmwarePathOption) is not null; + if (!hasArgument && !hasOption) + result.AddError("Required argument missing for command: 'update'."); + else if (hasArgument && hasOption) + result.AddError("The firmware file must be given either as an argument or with --path, not both."); + }); + SetAction(parseResult => { - var firmwarePath = parseResult.GetRequiredValue(firmwarePathOption); + var firmwarePath = parseResult.GetValue(firmwareArgument) ?? parseResult.GetValue(firmwarePathOption)!; var portName = parseResult.GetRequiredValue(portNameOption); var forceUpdate = parseResult.GetValue(forceUpdateOption);