feat: migrate cli to urfave/cli v3
This commit is contained in:
128
cmd/goyco/cli.go
128
cmd/goyco/cli.go
@@ -1,14 +1,24 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"goyco/cmd/goyco/commands"
|
"goyco/cmd/goyco/commands"
|
||||||
|
"goyco/internal/config"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
"github.com/urfave/cli/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
helpPrinterOnce sync.Once
|
||||||
|
defaultHelpPrinter func(io.Writer, string, interface{})
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadDotEnv() {
|
func loadDotEnv() {
|
||||||
@@ -55,3 +65,121 @@ func printRunUsage() {
|
|||||||
fmt.Fprintln(os.Stderr, "Usage: goyco run")
|
fmt.Fprintln(os.Stderr, "Usage: goyco run")
|
||||||
fmt.Fprintln(os.Stderr, "\nStart the web application in foreground.")
|
fmt.Fprintln(os.Stderr, "\nStart the web application in foreground.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildRootCommand(cfg *config.Config) *cli.Command {
|
||||||
|
helpPrinterOnce.Do(func() {
|
||||||
|
defaultHelpPrinter = cli.HelpPrinter
|
||||||
|
cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) {
|
||||||
|
if cmd, ok := data.(*cli.Command); ok && cmd.Root() == cmd {
|
||||||
|
printRootUsage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defaultHelpPrinter(w, templ, data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
root := &cli.Command{
|
||||||
|
Name: "goyco",
|
||||||
|
Usage: "Y Combinator-style news aggregation platform API",
|
||||||
|
UsageText: "goyco <command> [<args>]",
|
||||||
|
HideVersion: true,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "json",
|
||||||
|
Usage: "output results in JSON format",
|
||||||
|
Value: cfg.CLI.JSONOutputDefault,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
|
||||||
|
commands.SetJSONOutput(cmd.Bool("json"))
|
||||||
|
return ctx, nil
|
||||||
|
},
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
if cmd.NArg() == 0 {
|
||||||
|
printRootUsage()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
printRootUsage()
|
||||||
|
return fmt.Errorf("unknown command: %s", cmd.Args().First())
|
||||||
|
},
|
||||||
|
Commands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "run",
|
||||||
|
Usage: "start the web application in foreground",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return handleRunCommand(cfg, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "start",
|
||||||
|
Usage: "start the web application in background",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandleStartCommand(cfg, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "stop",
|
||||||
|
Usage: "stop the daemon",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandleStopCommand(cfg, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "status",
|
||||||
|
Usage: "check if the daemon is running",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandleStatusCommand(cfg, cmd.Name, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "migrate",
|
||||||
|
Aliases: []string{"migrations"},
|
||||||
|
Usage: "apply database migrations",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandleMigrateCommand(cfg, cmd.Name, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "user",
|
||||||
|
Usage: "manage users (create, update, delete, lock, list)",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandleUserCommand(cfg, cmd.Name, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "post",
|
||||||
|
Usage: "manage posts (delete, list, search)",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandlePostCommand(cfg, cmd.Name, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "prune",
|
||||||
|
Usage: "hard delete users and posts (posts, all)",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandlePruneCommand(cfg, cmd.Name, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "seed",
|
||||||
|
Usage: "seed database with random data",
|
||||||
|
SkipFlagParsing: true,
|
||||||
|
Action: func(_ context.Context, cmd *cli.Command) error {
|
||||||
|
return commands.HandleSeedCommand(cfg, cmd.Name, cmd.Args().Slice())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Writer: os.Stdout,
|
||||||
|
ErrWriter: os.Stderr,
|
||||||
|
}
|
||||||
|
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -63,33 +63,9 @@ func run(args []string) error {
|
|||||||
docs.SwaggerInfo.Schemes = append(docs.SwaggerInfo.Schemes, "https")
|
docs.SwaggerInfo.Schemes = append(docs.SwaggerInfo.Schemes, "https")
|
||||||
}
|
}
|
||||||
|
|
||||||
rootFS := flag.NewFlagSet("goyco", flag.ContinueOnError)
|
root := buildRootCommand(cfg)
|
||||||
rootFS.SetOutput(os.Stderr)
|
runArgs := append([]string{os.Args[0]}, args...)
|
||||||
rootFS.Usage = printRootUsage
|
return root.Run(context.Background(), runArgs)
|
||||||
showHelp := rootFS.Bool("help", false, "show this help message")
|
|
||||||
jsonOutput := rootFS.Bool("json", cfg.CLI.JSONOutputDefault, "output results in JSON format")
|
|
||||||
|
|
||||||
if err := rootFS.Parse(args); err != nil {
|
|
||||||
if errors.Is(err, flag.ErrHelp) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed to parse arguments: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if *showHelp {
|
|
||||||
printRootUsage()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
commands.SetJSONOutput(*jsonOutput)
|
|
||||||
|
|
||||||
remaining := rootFS.Args()
|
|
||||||
if len(remaining) == 0 {
|
|
||||||
printRootUsage()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return dispatchCommand(cfg, remaining[0], remaining[1:])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dispatchCommand(cfg *config.Config, name string, args []string) error {
|
func dispatchCommand(cfg *config.Config, name string, args []string) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user