-
Notifications
You must be signed in to change notification settings - Fork 105
feat: command - add support for typed cli arguments #1199
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
Changes from 8 commits
9185f34
211794f
e8d5afa
47604ec
687e51d
6559400
5b57460
d79c7ce
66afa01
72910e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,11 +5,13 @@ import ( | |||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||
| "slices" | ||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||
| "time" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| "github.com/urfave/cli/v3" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| "github.com/goravel/framework/contracts/console" | ||||||||||||||||||||||||||||||||||
| "github.com/goravel/framework/contracts/console/command" | ||||||||||||||||||||||||||||||||||
| "github.com/goravel/framework/errors" | ||||||||||||||||||||||||||||||||||
| "github.com/goravel/framework/support/color" | ||||||||||||||||||||||||||||||||||
| "github.com/goravel/framework/support/env" | ||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||
|
|
@@ -50,6 +52,10 @@ func NewApplication(name, usage, usageText, version string, useArtisan bool) con | |||||||||||||||||||||||||||||||||
| func (r *Application) Register(commands []console.Command) { | ||||||||||||||||||||||||||||||||||
| for _, item := range commands { | ||||||||||||||||||||||||||||||||||
| item := item | ||||||||||||||||||||||||||||||||||
| arguments, err := argumentsToCliArgs(item.Extend().Arguments) | ||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||
| color.Errorln(errors.ConsoleCommandRegistrationFailed.Args(item.Signature(), err).Error()) | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| cliCommand := cli.Command{ | ||||||||||||||||||||||||||||||||||
| Name: item.Signature(), | ||||||||||||||||||||||||||||||||||
| Usage: item.Description(), | ||||||||||||||||||||||||||||||||||
|
|
@@ -59,6 +65,7 @@ func (r *Application) Register(commands []console.Command) { | |||||||||||||||||||||||||||||||||
| Category: item.Extend().Category, | ||||||||||||||||||||||||||||||||||
| ArgsUsage: item.Extend().ArgsUsage, | ||||||||||||||||||||||||||||||||||
| Flags: flagsToCliFlags(item.Extend().Flags), | ||||||||||||||||||||||||||||||||||
| Arguments: arguments, | ||||||||||||||||||||||||||||||||||
| OnUsageError: onUsageError, | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| r.instance.Commands = append(r.instance.Commands, &cliCommand) | ||||||||||||||||||||||||||||||||||
|
|
@@ -229,3 +236,258 @@ func flagsToCliFlags(flags []command.Flag) []cli.Flag { | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| return cliFlags | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| func argumentsToCliArgs(args []command.Argument) ([]cli.Argument, error) { | ||||||||||||||||||||||||||||||||||
| len := len(args) | ||||||||||||||||||||||||||||||||||
| if len == 0 { | ||||||||||||||||||||||||||||||||||
| return nil, nil | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| cliArgs := make([]cli.Argument, 0, len) | ||||||||||||||||||||||||||||||||||
| previousIsRequired := true | ||||||||||||||||||||||||||||||||||
| for _, v := range args { | ||||||||||||||||||||||||||||||||||
| if v.MinOccurrences() != 0 && !previousIsRequired { | ||||||||||||||||||||||||||||||||||
| return nil, errors.ConsoleCommandRequiredArgumentWrongOrder.Args(v.ArgumentName()) | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
| if v.MinOccurrences() != 0 { | ||||||||||||||||||||||||||||||||||
| previousIsRequired = true | ||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||
| previousIsRequired = false | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+246
to
+254
|
||||||||||||||||||||||||||||||||||
| previousIsRequired := true | |
| for _, v := range args { | |
| if v.MinOccurrences() != 0 && !previousIsRequired { | |
| return nil, errors.ConsoleCommandRequiredArgumentWrongOrder.Args(v.ArgumentName()) | |
| } | |
| if v.MinOccurrences() != 0 { | |
| previousIsRequired = true | |
| } else { | |
| previousIsRequired = false | |
| hasNonRequiredArgument := false | |
| for _, v := range args { | |
| if hasNonRequiredArgument && v.MinOccurrences() != 0 { | |
| return nil, errors.ConsoleCommandRequiredArgumentWrongOrder.Args(v.ArgumentName()) | |
| } | |
| if v.MinOccurrences() == 0 { | |
| hasNonRequiredArgument = true |
Outdated
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.
How about adding a time format configuration option to command.ArgumentTimestamp? This would allow users to specify their desired format, making it more flexible and user-friendly.
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.
added support for Layouts
Outdated
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.
Ditto
Copilot
AI
Sep 19, 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 error formatting passes the same argument twice. The second parameter should be the argument's value or a different property. This will result in redundant information in the error message.
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.
After printing the error here, it might be better to use
continueto skip the iteration, right?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.
added
continueI did it without
continuebecause for me it provides at least some context for userwith
continue