-
Notifications
You must be signed in to change notification settings - Fork 3
Make main module optional for commands #242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
332bc13 to
35e2631
Compare
Main modules are now optional. Commands can have 0 or 1 main modules instead of requiring exactly 1. Arguments are only passed to commands that have a main module else they are ignored. Signed-off-by: Fabian Wienand <[email protected]>
35e2631 to
00781b3
Compare
There was a problem hiding this 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 refactors the command structure to make main modules optional, allowing commands to have 0 or 1 main modules instead of requiring exactly 1. Arguments are now only passed to commands that have a main module, and a new error type ErrNoMainForArgs is introduced to handle cases where arguments are provided without a main module. This change maintains backward compatibility while enabling more flexible command configurations.
Key changes:
- Modified validation logic to allow commands with 0 or 1 main modules (previously exactly 1)
- Updated
FindCmdsignature to accept arguments for validation - Added
ErrNoMainForArgserror for cases where arguments are provided without a main module
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/dut/dut.go | Updated FindCmd to accept args parameter, modified validation to allow 0-1 main modules, made CountMain method public, added ErrNoMainForArgs error, removed implicit main module assignment |
| pkg/dut/dut_test.go | Added comprehensive test cases for commands with/without main modules and argument validation scenarios |
| cmds/dutagent/runRPC.go | Updated findDUTCmd to pass command arguments to FindCmd and handle new ErrNoMainForArgs error |
| cmds/dutagent/rpc.go | Updated Details RPC to pass empty args to FindCmd, removed redundant main module validation since it's now optional |
| docs/dutagent-config.md | Updated documentation to reflect that main modules are now optional (0 or 1 instead of exactly 1) |
Comments suppressed due to low confidence (1)
pkg/dut/dut_test.go:202
- Consider adding a test case for a command with no modules (empty Modules slice) to verify that FindCmd properly returns ErrInvalidCommand as expected by the validation logic in dut.go:76.
tests := []struct {
name string
device string
command string
args []string
wantDev Device
wantCmd Command
err error
}{
{
name: "device and command found with main module and args",
device: "device1",
command: "cmd1",
args: []string{"arg1", "arg2"},
wantDev: devs["device1"],
wantCmd: devs["device1"].Cmds["cmd1"],
err: nil,
},
{
name: "device and command found with main module and no args",
device: "device1",
command: "cmd1",
args: []string{},
wantDev: devs["device1"],
wantCmd: devs["device1"].Cmds["cmd1"],
err: nil,
},
{
name: "command without main module and no args",
device: "device1",
command: "cmd4",
args: []string{},
wantDev: devs["device1"],
wantCmd: devs["device1"].Cmds["cmd4"],
err: nil,
},
{
name: "args provided but no main module",
device: "device1",
command: "cmd4",
args: []string{"arg1"},
wantDev: devs["device1"],
wantCmd: devs["device1"].Cmds["cmd4"],
err: ErrNoMainForArgs,
},
{
name: "device found, command not found",
device: "device1",
command: "cmd5",
args: []string{},
wantDev: devs["device1"],
wantCmd: Command{},
err: ErrCommandNotFound,
},
{
name: "device not found",
device: "device2",
command: "cmd1",
args: []string{},
wantDev: Device{},
wantCmd: Command{},
err: ErrDeviceNotFound,
},
{
name: "command with module but no main module",
device: "device1",
command: "cmd2",
args: []string{},
wantDev: devs["device1"],
wantCmd: devs["device1"].Cmds["cmd2"],
err: nil,
},
{
name: "invalid command with multiple main modules",
device: "device1",
command: "cmd3",
args: []string{},
wantDev: devs["device1"],
wantCmd: devs["device1"].Cmds["cmd3"],
err: ErrInvalidCommand,
},
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| break | ||
| } | ||
| } | ||
|
|
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] When a command has no main module, the Details RPC will return an empty help string. Consider providing a more informative response, such as a message indicating that this command has no main module and therefore no detailed help is available. This would improve the user experience when querying details for commands without a main module.
| if helpStr == "" { | |
| helpStr = "No main module found for this command; detailed help is not available." | |
| } |
| | module | string | | The module's name also serves as its identifier and must be unique. | yes | | ||
| | main | bool | false | All arguments to a command are passed to its main module. The main modules usage information is also used as the command help text. Can be omitted, if only one modules exists within the command. | exactly once per command | | ||
| | main | bool | false | Marks this module as the main module. All runtime arguments to a command are passed to its main module. The main module's usage information is also used as the command help text. | 0 or 1 times per command | | ||
| | args | []string | nil | If a module is **not** an commands main module, it does not get any arguments passed at runtime, instead arguments can be passed here. | no, only applies if `main` is set | |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation in the Mandatory column is confusing. It says "no, only applies if main is set" which contradicts itself - the args field should only be used when main is not set (as stated in the Description column). Consider changing this to "no, only for non-main modules" for clarity.
| | args | []string | nil | If a module is **not** an commands main module, it does not get any arguments passed at runtime, instead arguments can be passed here. | no, only applies if `main` is set | | |
| | args | []string | nil | If a module is **not** an commands main module, it does not get any arguments passed at runtime, instead arguments can be passed here. | no, only for non-main modules | |
|
Does this only cover cases where multiple modules are set? So, if there is only one module, will it automatically be set as the main module? |
|
No, the idea is to let the user decide if args are passed on to the cmd or not. I encountered the following issue: |
|
I see. Perhaps we should give it a name other than It should be something that intuitively indicates that the module handles the user command line. But I'm out of ideas for what to choose. 😅 What do you think, @jenstopp? We could create a gh discussion about this topic. |
|
Yes this came to my mind as well. If we change this behaviour, the name |
|
|
|
The naming can be part of discussion #191 |
|
closed in favor of #248 |
Main modules are now optional. Commands can have 0 or 1 main modules instead of requiring exactly 1. Arguments are only passed to commands that have a main module else they are ignored. This is not a breaking change as all old commands are still valid.
resolves #240