From c814f27c54054317c819d99c61ddfc58955ed511 Mon Sep 17 00:00:00 2001 From: Aleksandr Trushkin Date: Sun, 28 Jan 2024 17:08:45 +0300 Subject: [PATCH] migrate to cli v3 --- cmd/cli/main.go | 219 ++++++++++++++++++++++++------------------------ go.mod | 5 +- go.sum | 8 ++ 3 files changed, 123 insertions(+), 109 deletions(-) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 60aa9ae..a8d6164 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -25,7 +25,7 @@ import ( "github.com/brianvoe/gofakeit/v6" "github.com/rodaine/table" "github.com/rs/zerolog" - "github.com/urfave/cli" + "github.com/urfave/cli/v3" ) func main() { @@ -45,13 +45,13 @@ func main() { } func runcli(ctx context.Context) (err error) { - app := setupCLI(ctx) - return app.Run(os.Args) + app := setupCLI() + return app.Run(ctx, os.Args) } -func setupDI(ctx context.Context) cli.BeforeFunc { - return func(c *cli.Context) error { - cfgpath := c.String("config") +func setupDI() cli.BeforeFunc { + return func(ctx context.Context, cmd *cli.Command) error { + cfgpath := cmd.String("config") err := components.SetupDI(ctx, cfgpath) if err != nil { @@ -62,81 +62,85 @@ func setupDI(ctx context.Context) cli.BeforeFunc { } } -func releaseDI(c *cli.Context) error { - log, err := components.GetLogger() - if err != nil { - return fmt.Errorf("getting logger: %w", err) - } - - start := time.Now() - defer func() { - since := time.Since(start) - if err == nil { - return +func releaseDI() cli.AfterFunc { + return func(ctx context.Context, c *cli.Command) error { + log, err := components.GetLogger() + if err != nil { + return fmt.Errorf("getting logger: %w", err) } - log.Err(err).Dur("elapsed", since).Msg("shutdown finished") - }() + start := time.Now() + defer func() { + since := time.Since(start) + if err == nil { + return + } - return components.Shutdown() + log.Err(err).Dur("elapsed", since).Msg("shutdown finished") + }() + + return components.Shutdown() + + } } -func setupCLI(ctx context.Context) *cli.App { - app := cli.NewApp() - app.Flags = append( - app.Flags, - cli.StringFlag{ - Name: "config", - Usage: "path to config in TOML format", - Value: "config.toml", - TakesFile: true, +func setupCLI() *cli.Command { + app := &cli.Command{ + Name: "cli", + Description: "a cli for running eway logic", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "config", + Usage: "path to config in TOML format", + Value: "config.toml", + TakesFile: true, + }, }, - ) - app.Before = setupDI(ctx) - app.After = releaseDI - app.Commands = cli.Commands{ - newParseCmd(ctx), - newImportCmd(ctx), - newExportCmd(ctx), - newViewCmd(ctx), + Before: setupDI(), + After: releaseDI(), + + Commands: []*cli.Command{ + newParseCmd(), + newImportCmd(), + newExportCmd(), + newViewCmd(), + }, } - app.EnableBashCompletion = true - app.BashComplete = cli.DefaultAppComplete return app } -func newParseCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newParseCmd() *cli.Command { + return &cli.Command{ Name: "parse", Usage: "category for parsing items from various sources", - Subcommands: cli.Commands{ - newParseEwayCmd(ctx), + Commands: []*cli.Command{ + newParseEwayCmd(), }, } } -func newParseEwayCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newParseEwayCmd() *cli.Command { + return &cli.Command{ Name: "eway", Usage: "parse all available eway goods", - Action: decorateAction(ctx, parseEwayAction), + Action: decorateAction(parseEwayAction), } } -func newImportCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newImportCmd() *cli.Command { + return &cli.Command{ Name: "import", Usage: "category for importing data from sources", - Subcommands: cli.Commands{ - newImportFromFileCmd(ctx), + Commands: []*cli.Command{ + newImportFromFileCmd(), }, } } -func newImportFromFileCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newImportFromFileCmd() *cli.Command { + return &cli.Command{ Name: "file", Usage: "imports from file into db", Flags: []cli.Flag{ @@ -147,29 +151,28 @@ func newImportFromFileCmd(ctx context.Context) cli.Command { Required: true, }, }, - Action: decorateAction(ctx, importFromFileAction), + Action: decorateAction(importFromFileAction), } } -func newExportCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newExportCmd() *cli.Command { + return &cli.Command{ Name: "export", Usage: "category for exporting stored data", - Subcommands: cli.Commands{ - newExportYMLCatalogCmd(ctx), + Commands: []*cli.Command{ + newExportYMLCatalogCmd(), }, } } -func newExportYMLCatalogCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newExportYMLCatalogCmd() *cli.Command { + return &cli.Command{ Name: "yml_catalog", Usage: "export data into as yml_catalog in xml format", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "dst", + Name: "out", Usage: "destination path", - Required: true, Value: "yml_catalog.xml", TakesFile: true, }, @@ -182,70 +185,70 @@ func newExportYMLCatalogCmd(ctx context.Context) cli.Command { Usage: "prettify output", }, }, - Action: decorateAction(ctx, exportYMLCatalogAction), + Action: decorateAction(exportYMLCatalogAction), } } -func newTestCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newTestCmd(ctx context.Context) *cli.Command { + return &cli.Command{ Name: "test", Usage: "various commands for testing", - Subcommands: cli.Commands{ - newTestFBSCmd(ctx), + Commands: []*cli.Command{ + newTestFBSCmd(), }, } } -func newTestFBSCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newTestFBSCmd() *cli.Command { + return &cli.Command{ Name: "fbs", Usage: "serialize and deserialize gooditem entity", - Action: decorateAction(ctx, testFBSAction), + Action: decorateAction(testFBSAction), } } -func newViewCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newViewCmd() *cli.Command { + return &cli.Command{ Name: "view", Usage: "Set of commands to view the data inside db", - Subcommands: []cli.Command{ - newViewCategoriesCmd(ctx), - newViewItemsCmd(ctx), + Commands: []*cli.Command{ + newViewCategoriesCmd(), + newViewItemsCmd(), }, } } -func newViewCategoriesCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newViewCategoriesCmd() *cli.Command { + return &cli.Command{ Name: "categories", Usage: "Set of commands to work with categories", - Subcommands: []cli.Command{ - newViewCategoriesListCmd(ctx), + Commands: []*cli.Command{ + newViewCategoriesListCmd(), }, } } -func newViewItemsCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newViewItemsCmd() *cli.Command { + return &cli.Command{ Name: "items", Usage: "Set of command to work with items", - Subcommands: cli.Commands{ - newViewItemsGetCmd(ctx), - newViewItemsCountCmd(ctx), + Commands: []*cli.Command{ + newViewItemsGetCmd(), + newViewItemsCountCmd(), }, } } -func newViewItemsCountCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newViewItemsCountCmd() *cli.Command { + return &cli.Command{ Name: "count", Usage: "iterates over collection and counts number of items", - Action: decorateAction(ctx, viewItemsCountAction), + Action: decorateAction(viewItemsCountAction), } } -func newViewItemsGetCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newViewItemsGetCmd() *cli.Command { + return &cli.Command{ Name: "get", Usage: "gets goods item by its id", Flags: []cli.Flag{ @@ -253,17 +256,17 @@ func newViewItemsGetCmd(ctx context.Context) cli.Command { Name: "id", Usage: "id of the goods item. Either id or cart-id should be set", }, - &cli.Int64Flag{ + &cli.IntFlag{ Name: "cart-id", Usage: "cart-id of the item. Either cart-id or id should be set", }, }, - Action: decorateAction(ctx, viewItemsGetAction), + Action: decorateAction(viewItemsGetAction), } } -func newViewCategoriesListCmd(ctx context.Context) cli.Command { - return cli.Command{ +func newViewCategoriesListCmd() *cli.Command { + return &cli.Command{ Name: "list", Usage: "lists stored categories stored in database", Flags: []cli.Flag{ @@ -282,22 +285,22 @@ func newViewCategoriesListCmd(ctx context.Context) cli.Command { Usage: "prints total count of categories", }, }, - Action: decorateAction(ctx, viewCategoriesListAction), + Action: decorateAction(viewCategoriesListAction), } } -func viewItemsGetAction(ctx context.Context, c *cli.Context) error { +func viewItemsGetAction(ctx context.Context, c *cli.Command) error { r, err := components.GetRepository() if err != nil { return fmt.Errorf("getting repository: %w", err) } id := c.String("id") - cartID := c.Int64("cart-id") + cartID := c.Int("cart-id") if id == "" && cartID == 0 { - return cli.NewExitError("oneof: id or cart-id should be set", 1) + return cli.Exit("oneof: id or cart-id should be set", 1) } else if id != "" && cartID != 0 { - return cli.NewExitError("oneof: id or cart-id should be set", 1) + return cli.Exit("oneof: id or cart-id should be set", 1) } var item entity.GoodsItem @@ -321,7 +324,7 @@ func viewItemsGetAction(ctx context.Context, c *cli.Context) error { return nil } -func viewItemsCountAction(ctx context.Context, c *cli.Context) error { +func viewItemsCountAction(ctx context.Context, c *cli.Command) error { r, err := components.GetRepository() if err != nil { return fmt.Errorf("getting repository: %w", err) @@ -360,7 +363,7 @@ func viewItemsCountAction(ctx context.Context, c *cli.Context) error { return nil } -func viewCategoriesListAction(ctx context.Context, c *cli.Context) error { +func viewCategoriesListAction(ctx context.Context, c *cli.Command) error { r, err := components.GetRepository() if err != nil { return fmt.Errorf("getting repository: %w", err) @@ -371,8 +374,8 @@ func viewCategoriesListAction(ctx context.Context, c *cli.Context) error { return fmt.Errorf("listing categories: %w", err) } - limit := c.Int("limit") - page := c.Int("page") + limit := int(c.Int("limit")) + page := int(c.Int("page")) total := len(categories) if page == 0 { @@ -410,7 +413,7 @@ func viewCategoriesListAction(ctx context.Context, c *cli.Context) error { return nil } -func importFromFileAction(ctx context.Context, c *cli.Context) error { +func importFromFileAction(ctx context.Context, c *cli.Command) error { const maxBatch = 2000 r, err := components.GetRepository() @@ -526,10 +529,10 @@ func importFromFileAction(ctx context.Context, c *cli.Context) error { return nil } -type action func(ctx context.Context, c *cli.Context) error +type action func(ctx context.Context, c *cli.Command) error -func decorateAction(ctx context.Context, a action) cli.ActionFunc { - return func(c *cli.Context) error { +func decorateAction(a action) cli.ActionFunc { + return func(ctx context.Context, c *cli.Command) error { var data [3]byte _, _ = rand.Read(data[:]) reqid := hex.EncodeToString(data[:]) @@ -552,7 +555,7 @@ func decorateAction(ctx context.Context, a action) cli.ActionFunc { } } -func exportYMLCatalogAction(ctx context.Context, c *cli.Context) error { +func exportYMLCatalogAction(ctx context.Context, c *cli.Command) error { path := c.String("dst") limit := c.Int("limit") pretty := c.Bool("pretty") @@ -639,7 +642,7 @@ func exportYMLCatalogAction(ctx context.Context, c *cli.Context) error { return enc.Encode(container) } -func parseEwayAction(ctx context.Context, c *cli.Context) error { +func parseEwayAction(ctx context.Context, c *cli.Command) error { client, err := components.GetEwayClient() if err != nil { return fmt.Errorf("getting eway client: %w", err) @@ -806,7 +809,7 @@ func goodsItemAsOffer(in entity.GoodsItem, categoryIDByName map[string]int64) (o return out } -func testFBSAction(ctx context.Context, c *cli.Context) error { +func testFBSAction(ctx context.Context, c *cli.Command) error { var gooditem entity.GoodsItem err := gofakeit.Struct(&gooditem) if err != nil { diff --git a/go.mod b/go.mod index a15fc44..d3691f4 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.0.0 // indirect @@ -29,6 +29,9 @@ require ( github.com/mattn/go-isatty v0.0.19 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/urfave/cli/v2 v2.27.1 // indirect + github.com/urfave/cli/v3 v3.0.0-alpha8 // indirect + github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect go.opencensus.io v0.22.5 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect diff --git a/go.sum b/go.sum index f766c36..2f4ab96 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -82,6 +84,12 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v3 v3.0.0-alpha8 h1:H+qxFPoCkGzdF8KUMs2fEOZl5io/1QySgUiGfar8occ= +github.com/urfave/cli/v3 v3.0.0-alpha8/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=