diff --git a/docs/migrate-v1-to-v2.md b/docs/migrate-v1-to-v2.md index 7c703c847f..8d3e284b47 100644 --- a/docs/migrate-v1-to-v2.md +++ b/docs/migrate-v1-to-v2.md @@ -9,7 +9,7 @@ If you find any issues not covered by this document, please post a comment on [Issue 921](https://github.com/urfave/cli/issues/921) or consider sending a PR to help improve this guide. -# Flags before args +## Flags before args In v2 flags must come before args. This is more POSIX-compliant. You may need to update scripts, user documentation, etc. @@ -26,61 +26,75 @@ This will not: cli hello rick --shout ``` -# Import string changed +## Import string changed -* OLD: `import "github.com/urfave/cli"` -* NEW: `import "github.com/urfave/cli/v2"` +=== "v1" + + `import "github.com/urfave/cli"` + +=== "v2" + + `import "github.com/urfave/cli/v2"` Check each file for this and make the change. Shell command to find them all: `fgrep -rl github.com/urfave/cli *` -# Flag aliases are done differently +## Flag aliases are done differently Change `Name: "foo, f"` to `Name: "foo", Aliases: []string{"f"}` -* OLD: -```go -cli.StringFlag{ - Name: "config, cfg" -} -``` +=== "v1" -* NEW: -```go -cli.StringFlag{ - Name: "config", - Aliases: []string{"cfg"}, -} -``` + ```go + cli.StringFlag{ + Name: "config, cfg" + } + ``` + +=== "v2" + + ```go + cli.StringFlag{ + Name: "config", + Aliases: []string{"cfg"}, + } + ``` Sadly v2 doesn't warn you if a comma is in the name. (https://github.com/urfave/cli/issues/1103) -# EnvVar is now a list (EnvVars) +## EnvVar is now a list (EnvVars) Change `EnvVar: "XXXXX"` to `EnvVars: []string{"XXXXX"}` (plural). -* OLD: -```go -cli.StringFlag{ - EnvVar: "APP_LANG" -} -``` +=== "v1" -* NEW: -```go -cli.StringFlag{ - EnvVars: []string{"APP_LANG"} -} -``` + ```go + cli.StringFlag{ + EnvVar: "APP_LANG" + } + ``` -# Actions returns errors +=== "v2" + + ```go + cli.StringFlag{ + EnvVars: []string{"APP_LANG"} + } + ``` + +## Actions returns errors A command's `Action:` now returns an `error`. -* OLD: `Action: func(c *cli.Context) {` -* NEW: `Action: func(c *cli.Context) error {` +=== "v1" + + `Action: func(c *cli.Context) {` + +=== "v2" + + `Action: func(c *cli.Context) error {` Compiler messages you might see: @@ -88,7 +102,7 @@ Compiler messages you might see: cannot use func literal (type func(*cli.Context)) as type cli.ActionFunc in field value ``` -# cli.Flag changed +## cli.Flag changed `cli.Flag` is now a list of pointers. @@ -97,17 +111,19 @@ What this means to you: If you make a list of flags, add a `&` in front of each item. cli.BoolFlag, cli.StringFlag, etc. -* OLD: -```go - app.Flags = []cli.Flag{ - cli.BoolFlag{ -``` +=== "v1" -* NEW: -```go - app.Flags = []cli.Flag{ - &cli.BoolFlag{ -``` + ```go + app.Flags = []cli.Flag{ + cli.BoolFlag{ + ``` + +=== "v2" + + ```go + app.Flags = []cli.Flag{ + &cli.BoolFlag{ + ``` Compiler messages you might see: @@ -115,7 +131,7 @@ Compiler messages you might see: cli.StringFlag does not implement cli.Flag (Apply method has pointer receiver) ``` -# Commands are now lists of pointers +## Commands are now lists of pointers Occurrences of `[]Command` have been changed to `[]*Command`. @@ -125,8 +141,13 @@ Look for `[]cli.Command{}` and change it to `[]*cli.Command{}` Example: -* OLD: `var commands = []cli.Command{}` -* NEW: `var commands = []*cli.Command{}` +=== "v1" + + `var commands = []cli.Command{}` + +=== "v2" + + `var commands = []*cli.Command{}` Compiler messages you might see: @@ -135,13 +156,18 @@ cannot convert commands (type []cli.Command) to type cli.CommandsByName cannot use commands (type []cli.Command) as type []*cli.Command in assignment ``` -# Lists of commands should be pointers +## Lists of commands should be pointers If you are building up a list of commands, the individual items should now be pointers. -* OLD: `cli.Command{` -* NEW: `&cli.Command{` +=== "v1" + + `cli.Command{` + +=== "v2" + + `&cli.Command{` Compiler messages you might see: @@ -149,13 +175,18 @@ Compiler messages you might see: cannot use cli.Command literal (type cli.Command) as type *cli.Command in argument to ``` -# Appending Commands +## Appending Commands Appending to a list of commands needs to be changed since the list is now pointers. -* OLD: `commands = append(commands, *c)` -* NEW: `commands = append(commands, c)` +=== "v1" + + `commands = append(commands, *c)` + +=== "v2" + + `commands = append(commands, c)` Compiler messages you might see: @@ -163,53 +194,56 @@ Compiler messages you might see: cannot use c (type *cli.Command) as type cli.Command in append ``` -# GlobalString, GlobalBool and its likes are deprecated +## GlobalString, GlobalBool and its likes are deprecated Use simply `String` instead of `GlobalString`, `Bool` instead of `GlobalBool` -# BoolTFlag and BoolT are deprecated +## BoolTFlag and BoolT are deprecated BoolTFlag was a Bool Flag with its default value set to true and BoolT was used to find any BoolTFlag used locally, so both are deprecated. -* OLD: - -```go -cli.BoolTFlag{ - Name: FlagName, - Usage: FlagUsage, - EnvVar: "FLAG_ENV_VAR", -} -``` -* NEW: -```go -cli.BoolFlag{ - Name: FlagName, - Value: true, - Usage: FlagUsage, - EnvVar: "FLAG_ENV_VAR", -} -``` +=== "v1" + + ```go + cli.BoolTFlag{ + Name: FlagName, + Usage: FlagUsage, + EnvVar: "FLAG_ENV_VAR", + } + ``` + +=== "v2" + + ```go + cli.BoolFlag{ + Name: FlagName, + Value: true, + Usage: FlagUsage, + EnvVar: "FLAG_ENV_VAR", + } + ``` + +## &cli.StringSlice{""} replaced with cli.NewStringSlice("") +Example: -# &cli.StringSlice{""} replaced with cli.NewStringSlice("") +=== "v1" -Example: + ```go + Value: &cli.StringSlice{""}, + ``` -* OLD: +=== "v2" + + ```go + Value: cli.NewStringSlice(""), + ``` -```go -Value: &cli.StringSlice{""}, -``` -* NEW: -```go -Value: cli.NewStringSlice(""), -} -``` -# Replace deprecated functions +## Replace deprecated functions `cli.NewExitError()` is deprecated. Use `cli.Exit()` instead. ([Staticcheck](https://staticcheck.io/) detects this automatically and recommends replacement code.) -# Everything else +## Everything else Compile the code and work through any errors. Most should relate to issues listed above. diff --git a/docs/migrate-v2-to-v3.md b/docs/migrate-v2-to-v3.md index 4f5b4020b6..625f8f0388 100644 --- a/docs/migrate-v2-to-v3.md +++ b/docs/migrate-v2-to-v3.md @@ -9,102 +9,121 @@ If you find any issues not covered by this document, please post a comment on [the discussion](https://github.com/urfave/cli/discussions/2084) or consider sending a PR to help improve this guide. -# Import string changed +## Import string changed -* OLD: `import "github.com/urfave/cli/v2"` -* NEW: `import "github.com/urfave/cli/v3"` +=== "v2" + + `import "github.com/urfave/cli/v2"` + +=== "v3" + + `import "github.com/urfave/cli/v3"` Check each file for this and make the change. Shell command to find them all: `fgrep -rl github.com/urfave/cli/v2 *` -# FilePath +## FilePath Change `FilePath: "XXXXX"` to `Sources: Files("XXXXX")`. -* OLD: -```go -cli.StringFlag{ - FilePath: "/path/to/foo", -} -``` +=== "v2" -* NEW: -```go -cli.StringFlag{ - Sources: Files("/path/to/foo"), -} -``` + ```go + cli.StringFlag{ + FilePath: "/path/to/foo", + } + ``` + +=== "v3" -# EnvVars + ```go + cli.StringFlag{ + Sources: Files("/path/to/foo"), + } + ``` + +## EnvVars Change `EnvVars: "XXXXX"` to `Sources: EnvVars("XXXXX")`. -* OLD: -```go -cli.StringFlag{ - EnvVars: []string{"APP_LANG"}, -} -``` +=== "v2" -* NEW: -```go -cli.StringFlag{ - Sources: EnvVars("APP_LANG"), -} -``` + ```go + cli.StringFlag{ + EnvVars: []string{"APP_LANG"}, + } + ``` -# Altsrc has been moved out of the cli library into its own repo +=== "v3" -* OLD: `import "github.com/urfave/cli/v2/altsrc"` -* NEW: `import "github.com/urfave/cli-altsrc/v3"` + ```go + cli.StringFlag{ + Sources: EnvVars("APP_LANG"), + } + ``` -# Altsrc is now a value source for cli +## Altsrc has been moved out of the cli library into its own repo -* OLD: -```go -altsrc.StringFlag{ - &cli.String{....} -} -``` +=== "v2" -* NEW: -```go -cli.StringFlag{ - Sources: altsrc.JSON("key", "/tmp/foo") -} -``` + `import "github.com/urfave/cli/v2/altsrc"` -# Order of precedence of envvars, filepaths, altsrc now depends on the order in which they are defined +=== "v3" -* OLD: -```go -cli.StringFlag{ - EnvVars: []string{"APP_LANG"}, -} -cli.StringFlag{ - FilePath: "/path/to/foo", -} -``` + `import "github.com/urfave/cli-altsrc/v3"` -* NEW: -```go -cli.StringFlag{ - Sources: cli.ValueSourceChain{ - Chain: { - EnvVars("APP_LANG"), - Files("/path/to/foo"), - altsrc.JSON("foo", "/path/to/"), - } - }, -} -``` +## Altsrc is now a value source for cli + +=== "v2" + + ```go + altsrc.StringFlag{ + &cli.String{....} + } + ``` -In the above case the Envs are checked first and if not found then files are looked at and then finally the altsrc +=== "v3" + + ```go + cli.StringFlag{ + Sources: altsrc.JSON("key", "/tmp/foo") + } + ``` -# cli.Context has been removed +## Order of precedence of envvars, filepaths, altsrc now depends on the order in which they are defined -All functions handled previously by cli.Context have been incorporated into cli.Command + +=== "v2" + + ```go + cli.StringFlag{ + EnvVars: []string{"APP_LANG"}, + } + cli.StringFlag{ + FilePath: "/path/to/foo", + } + ``` + +=== "v3" + + ```go + cli.StringFlag{ + Sources: cli.ValueSourceChain{ + Chain: { + EnvVars("APP_LANG"), + Files("/path/to/foo"), + altsrc.JSON("foo", "/path/to/"), + } + }, + } + ``` + +In the above case the Envs are checked first and if not found then files are looked at and then finally the `altsrc` + +## cli.Context has been removed + +All functions handled previously by cli.Context have been incorporated into `cli.Command`: * Change `cli.Context.IsSet` -> `cli.Command.IsSet` * Change `cli.Context.NumFlags` -> `cli.Command.NumFlags` @@ -116,36 +135,108 @@ All functions handled previously by cli.Context have been incorporated into cli. * Change `cli.Context.Args` -> `cli.Command.Args` * Change `cli.Context.NArg` -> `cli.Command.NArg` -# Handler func signatures have changed +## Handler func signatures have changed + +All handler functions now take at least 2 arguments a `context.Context` and a pointer to `Cli.Command` +in addition to other specific args. This allows handler functions to utilize `context.Context` for +blocking/time-specific operations and so on. + +### BeforeFunc + +=== "v2" + + `type BeforeFunc func(*Context) error` + +=== "v3" + + `type BeforeFunc func(context.Context, *cli.Command) (context.Context, error)` + +### AfterFunc -All handler functions now take atleast 2 arguments a context.Context and a pointer to Cli.Command -in addition to other specific args. This allows handler functions to utilize context.Context for -blocking/time-specific operations and so on +=== "v2" -* OLD: `type BeforeFunc func(*Context) error` -* NEW: `type BeforeFunc func(context.Context, *cli.Command) (context.Context, error)` + `type AfterFunc func(*Context) error` -* OLD: `type AfterFunc func(*Context) error` -* NEW: `type AfterFunc func(context.Context, *cli.Command) error` +=== "v3" -* OLD: `type ActionFunc func(*Context) error` -* NEW: `type ActionFunc func(context.Context, *cli.Command) error` + `type AfterFunc func(context.Context, *cli.Command) error` -* OLD: `type CommandNotFoundFunc func(*Context, string) error` -* NEW: `type CommandNotFoundFunc func(context.Context, *cli.Command, string) error` +### ActionFunc -* OLD: `type OnUsageErrorFunc func(*Context, err error, isSubcommand bool) error` -* NEW: `type OnUsageErrorFunc func(context.Context, *cli.Command, err error, isSubcommand bool) error` +=== "v2" -* OLD: `type InvalidAccessFunc func(*Context, string) error` -* NEW: `type InvalidAccessFunc func(context.Context, *cli.Command, string) error` + `type ActionFunc func(*Context) error` -* OLD: `type ExitErrHandlerFunc func(*Context, err error) error` -* NEW: `type ExitErrHandlerFunc func(context.Context, *cli.Command, err error) error` +=== "v3" + + `type ActionFunc func(context.Context, *cli.Command) error` + +### CommandNotFoundFunc + +=== "v2" + + `type CommandNotFoundFunc func(*Context, string) error` + +=== "v3" + + `type CommandNotFoundFunc func(context.Context, *cli.Command, string) error` + +### OnUsageErrorFunc + +=== "v2" + + `type OnUsageErrorFunc func(*Context, err error, isSubcommand bool) error` + +=== "v3" + + `type OnUsageErrorFunc func(context.Context, *cli.Command, err error, isSubcommand bool) error` + +### InvalidAccessFunc + +=== "v2" + + `type InvalidAccessFunc func(*Context, string) error` + +=== "v3" + + `type InvalidAccessFunc func(context.Context, *cli.Command, string) error` + +### ExitErrHandlerFunc + +=== "v2" + + `type ExitErrHandlerFunc func(*Context, err error) error` + +=== "v3" + + `type ExitErrHandlerFunc func(context.Context, *cli.Command, err error) error` Compiler messages you might see(for ActionFunc): ``` cannot use func literal (type func(*cli.Context) error) as type cli.ActionFunc in field value ``` -Similar messages would be shown for other funcs + +Similar messages would be shown for other funcs. + +## TimestampFlag + +=== "v2" + + ```go + &cli.TimestampFlag{ + Name: "foo", + Layout: time.RFC3339, + } + ``` + +=== "v3" + + ```go + &cli.TimestampFlag{ + Name: "foo", + Config: cli.TimestampConfig{ + Layouts: []string{time.RFC3339}, + }, + } + ```