-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Optional exit code support #361
Conversation
The function used by BashComplete, Before, After, Action and CommandNotFound have their won type. This makes easier to change/update the API
} | ||
command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) | ||
err := command.Run(c) | ||
command := &cli.Command{ |
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.
👍
@meatballhat overall 👍, I like the idea of allowing the centralization of error handling. Did you also consider this approach in comparison to having |
tbh I feel weird about // ...
app.Action = func(ctx *cli.Context) error {
// ... bleep bloop
return cli.NewExitError("invalid blooping", 3)
} ... which we would handle internally a la: err := app.Action(ctx)
if exitErr, ok := err.(*ExitError); ok {
// do stuff maybe
os.Exit(exitErr.Code)
}
// else don't os.Exit... whaddya think? |
I am a big fan of this approach over the |
@txgruppi Please jump in and let us know your thoughts! 😻 |
@meatballhat I like the idea of having an error that can bubble up the exit code. 😄 |
@meatballhat for sure it will be great, I believe the great majority of the users don't use any type of versioning for Go packages. Sadly I am one of them 😞 I'm not sure about performance costs of using reflection but I believe it doesn't apply to this package |
@txgruppi yep, I have a few projects kicking around that don't version pin 😺 I seriously doubt this will have any performance impact 🔬 |
@meatballhat nice, I really like the use of reflection to support backwards compatibility (still reviewing to leave inline notes). |
Action func(context *Context) | ||
Action interface{} | ||
// TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind | ||
// of deprecation period has passed, maybe? |
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.
👍
I left one comment that may need action taken, but otherwise this is great. I like that you were able to preserve backwards compatibility (at the cost of type safety, but I think it is acceptable in this case). We can remove support for the deprecated signature in the future. The only other way I can think of preserving backwards compatibility is to add another field on the struct, but I think this would introduce a more complexity into the code (thus causing bugs) so I think your approach is appropriate. |
// ActionFunc or LegacyActionFunc, the func is run! | ||
func HandleAction(action interface{}, context *Context) error { | ||
if reflect.TypeOf(action).Kind() != reflect.Func { | ||
panic("given Action must be a func") |
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.
Can't this be a returned error?
@@ -404,16 +417,16 @@ func HandleAction(action interface{}, context *Context) error { | |||
if len(vals) == 0 { | |||
fmt.Fprintln(os.Stderr, | |||
"DEPRECATED Action signature. Must be `cli.ActionFunc`") | |||
return nil | |||
return err |
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.
I kinda like return nil
here -- return err
visually implies to me that it it is not nil
.
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.
Aaah, nvm, I think I see now that this would end up being a real error if there is a panic.
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.
Wait, maybe, now I've confused myself. Is there a case where this wouldn't return nil
?
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.
I think this branch will only allow nil
, yep. I think I was being overly zealous with the defer
impl above.
@@ -14,11 +14,13 @@ import ( | |||
var ( | |||
appActionDeprecationURL = "https://github.com/codegangsta/cli/blob/master/CHANGELOG.md#deprecated-cli-app-action-signature" | |||
|
|||
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you." |
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.
👏
Doing so limits the ability for users to have only some of their errors cause the application to terminate while allowing others to bubble up. This was originally an adjustment to #361 in #496 to fix #495, but, in hindsight, I believe that the better approach is to recommend the use of `RunAndExitOnError` for this use case (which is undeprecated here). Fixes #565 #594
This began as a merge resolution of #266 with some whitespace formatting fixes in README, exposed definition of default "success" and "error" exit codes, and style change from
.*Fn$
to.*Func$
func type names. Based on discussion below, the patch is evolving:int
in return signature to optional customerror
typeSee changes to
CHANGELOG.md
for more details.Closes #266