Move to urfave/cli

This commit is contained in:
Daniel Ponte 2024-11-24 10:38:19 -05:00
parent f1e65aaa68
commit 4bee6840dc
8 changed files with 130 additions and 97 deletions

View file

@ -13,28 +13,52 @@ import (
"dynatron.me/x/stillbox/pkg/cmd/serve" "dynatron.me/x/stillbox/pkg/cmd/serve"
"dynatron.me/x/stillbox/pkg/config" "dynatron.me/x/stillbox/pkg/config"
"github.com/spf13/cobra" "github.com/urfave/cli/v2"
) )
const DefaultConfig = "config.yaml"
func main() { func main() {
configFile := DefaultConfig
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: common.TimeFormat}) log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: common.TimeFormat})
rootCmd := &cobra.Command{ cfg := config.New(&configFile)
Use: common.AppName, app := &cli.App{
} Name: common.AppName,
rootCmd.PersistentFlags().BoolP("version", "V", false, "show version") Usage: "a scanner call server",
cfg := config.New(rootCmd) UseShortOptionHandling: true,
rootCmd.PreRun = func(cmd *cobra.Command, args []string) { Before: cfg.Before,
v, _ := rootCmd.PersistentFlags().GetBool("version") Flags: []cli.Flag{
if v { &cli.StringFlag{
fmt.Print(version.String()) Name: "config",
os.Exit(0) Value: DefaultConfig,
} Usage: "configuration file",
Destination: &configFile,
Aliases: []string{"c"},
},
&cli.BoolFlag{
Name: "version",
Aliases: []string{"V"},
Action: func(_ *cli.Context, v bool) error {
if v {
fmt.Print(version.String())
os.Exit(0)
}
return nil
},
DisableDefaultText: true,
},
},
Commands: []*cli.Command{
serve.Command(cfg),
admin.Command(cfg),
},
} }
cmds := append([]*cobra.Command{serve.Command(cfg)}, admin.Command(cfg)...) err := app.Run(os.Args)
rootCmd.AddCommand(cmds...) if err != nil {
os.Stderr.Write([]byte("Error: " + err.Error() + "\n"))
// cobra is already checking for errors and will print them os.Exit(1)
_ = rootCmd.Execute() }
} }

7
go.mod
View file

@ -23,9 +23,9 @@ require (
github.com/knadh/koanf/v2 v2.1.2 github.com/knadh/koanf/v2 v2.1.2
github.com/nikoksr/notify v1.1.0 github.com/nikoksr/notify v1.1.0
github.com/rs/zerolog v1.33.0 github.com/rs/zerolog v1.33.0
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300 github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300
github.com/urfave/cli/v2 v2.27.5
golang.org/x/crypto v0.29.0 golang.org/x/crypto v0.29.0
golang.org/x/sync v0.9.0 golang.org/x/sync v0.9.0
golang.org/x/term v0.26.0 golang.org/x/term v0.26.0
@ -36,6 +36,7 @@ require (
require ( require (
github.com/ajg/form v1.5.1 // indirect github.com/ajg/form v1.5.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect
@ -44,7 +45,6 @@ require (
github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-json v0.10.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 // indirect github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
@ -61,9 +61,10 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect github.com/segmentio/asm v1.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/objx v0.5.2 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
go.uber.org/atomic v1.11.0 // indirect go.uber.org/atomic v1.11.0 // indirect
golang.org/x/exp/shiny v0.0.0-20241108190413-2d47ceb2692f // indirect golang.org/x/exp/shiny v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/image v0.22.0 // indirect golang.org/x/image v0.22.0 // indirect

14
go.sum
View file

@ -11,7 +11,8 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoU
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -73,8 +74,6 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 h1:Dj0L5fhJ9F82ZJyVOmBx6msDp/kfd1t9GRfny/mfJA0= github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438 h1:Dj0L5fhJ9F82ZJyVOmBx6msDp/kfd1t9GRfny/mfJA0=
github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= github.com/jackc/pgerrcode v0.0.0-20240316143900-6e2875d9b438/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
@ -148,14 +147,11 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
@ -167,6 +163,10 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300 h1:XQdibLKagjdevRB6vAjVY4qbSr8rQ610YzTkWcxzxSI= github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300 h1:XQdibLKagjdevRB6vAjVY4qbSr8rQ610YzTkWcxzxSI=
github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300/go.mod h1:FNa/dfN95vAYCNFrIKRrlRo+MBLbwmR9Asa5f2ljmBI= github.com/tcolgate/mp3 v0.0.0-20170426193717-e79c5a46d300/go.mod h1:FNa/dfN95vAYCNFrIKRrlRo+MBLbwmR9Asa5f2ljmBI=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM=
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=

View file

@ -1,38 +1,31 @@
package common package common
import ( import (
"github.com/spf13/cobra" "github.com/urfave/cli/v2"
) )
const ( const (
AppName = "stillbox" AppName = "stillbox"
EnvPrefix = "STILLBOX_" EnvPrefix = "STILLBOX_"
) )
const ( const (
TimeFormat = "Jan 2 15:04:05" TimeFormat = "Jan 2 15:04:05"
) )
type cmdOptions interface { type cmdOptions interface {
Options(*cobra.Command, []string) error Options(*cli.Context) error
Execute() error Execute() error
} }
func RunE(c cmdOptions) func(cmd *cobra.Command, args []string) error { func Action(c cmdOptions) cli.ActionFunc {
return func(cmd *cobra.Command, args []string) error { return func(ctx *cli.Context) error {
err := c.Options(cmd, args) err := c.Options(ctx)
if err != nil { if err != nil {
cmd.SilenceUsage = true
return err return err
} }
err = c.Execute() return c.Execute()
if err != nil {
cmd.SilenceUsage = true
}
return err
} }
} }

View file

@ -8,7 +8,7 @@ import (
"dynatron.me/x/stillbox/pkg/config" "dynatron.me/x/stillbox/pkg/config"
"dynatron.me/x/stillbox/pkg/database" "dynatron.me/x/stillbox/pkg/database"
"github.com/spf13/cobra" "github.com/urfave/cli/v2"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"golang.org/x/term" "golang.org/x/term"
) )
@ -115,59 +115,78 @@ func readPassword(prompt string) (string, error) {
} }
// Command is the users command. // Command is the users command.
func Command(cfg *config.Configuration) []*cobra.Command { func Command(cfg *config.Configuration) *cli.Command {
userCmd := &cobra.Command{ c := &cfg.Config
Use: "users", userCmd := &cli.Command{
Aliases: []string{"u"}, Name: "users",
Short: "administers the server", Aliases: []string{"u"},
PersistentPreRunE: cfg.PreRunE(), Usage: "administers users",
Subcommands: []*cli.Command{
addUserCommand(c),
passwdCommand(c),
},
} }
userCmd.AddCommand(addUserCommand(&cfg.Config), passwdCommand(&cfg.Config))
return []*cobra.Command{userCmd} return userCmd
} }
func addUserCommand(cfg *config.Config) *cobra.Command { func addUserCommand(cfg *config.Config) *cli.Command {
c := &cobra.Command{ c := &cli.Command{
Use: "add", Name: "add",
Short: "adds a user", Description: "adds a user",
RunE: func(cmd *cobra.Command, args []string) error { UsageText: "stillbox users add [-a] [-m email] [username]",
Args: true,
Action: func(ctx *cli.Context) error {
if ctx.Args().Len() != 1 {
return errors.New(ctx.Command.Usage)
}
db, err := database.NewClient(context.Background(), cfg.DB) db, err := database.NewClient(context.Background(), cfg.DB)
if err != nil { if err != nil {
return err return err
} }
username := args[0] username := ctx.Args().Get(0)
isAdmin, err := cmd.Flags().GetBool("admin") isAdmin := ctx.Bool("admin")
if err != nil { email := ctx.String("email")
return err
}
email, err := cmd.Flags().GetString("email")
if err != nil {
return err
}
return AddUser(database.CtxWithDB(context.Background(), db), username, email, isAdmin) return AddUser(database.CtxWithDB(context.Background(), db), username, email, isAdmin)
}, },
Args: cobra.ExactArgs(1), Flags: []cli.Flag{
&cli.BoolFlag{
Name: "admin",
Aliases: []string{"a"},
Value: false,
Usage: "user is an admin",
},
&cli.StringFlag{
Name: "email",
Usage: "email address",
Aliases: []string{"m"},
},
},
} }
c.Flags().BoolP("admin", "a", false, "is admin")
c.Flags().StringP("email", "m", "", "email address")
return c return c
} }
func passwdCommand(cfg *config.Config) *cobra.Command { func passwdCommand(cfg *config.Config) *cli.Command {
c := &cobra.Command{ c := &cli.Command{
Use: "passwd userid", Name: "passwd",
Short: "changes password for a user", Usage: "changes password for a user",
Args: cobra.ExactArgs(1), UsageText: "stillbox users passwd [username]",
RunE: func(cmd *cobra.Command, args []string) error { Args: true,
Action: func(ctx *cli.Context) error {
if ctx.Args().Len() != 1 {
return errors.New(ctx.Command.Usage)
}
db, err := database.NewClient(context.Background(), cfg.DB) db, err := database.NewClient(context.Background(), cfg.DB)
if err != nil { if err != nil {
return err return err
} }
username := args[0] username := ctx.Args().Get(0)
return Passwd(database.CtxWithDB(context.Background(), db), username) return Passwd(database.CtxWithDB(context.Background(), db), username)
}, },
} }

View file

@ -9,20 +9,19 @@ import (
"dynatron.me/x/stillbox/pkg/config" "dynatron.me/x/stillbox/pkg/config"
"dynatron.me/x/stillbox/pkg/server" "dynatron.me/x/stillbox/pkg/server"
"github.com/spf13/cobra" "github.com/urfave/cli/v2"
) )
type ServeOptions struct { type ServeOptions struct {
cfg *config.Configuration cfg *config.Configuration
} }
func Command(cfg *config.Configuration) *cobra.Command { func Command(cfg *config.Configuration) *cli.Command {
opts := makeOptions(cfg) opts := makeOptions(cfg)
serveCmd := &cobra.Command{ serveCmd := &cli.Command{
Use: "serve", Name: "serve",
Short: "starts the" + common.AppName + " server", Usage: "starts the " + common.AppName + " server",
PersistentPreRunE: cfg.PreRunE(), Action: common.Action(opts),
RunE: common.RunE(opts),
} }
return serveCmd return serveCmd
@ -34,7 +33,7 @@ func makeOptions(cfg *config.Configuration) *ServeOptions {
} }
} }
func (o *ServeOptions) Options(_ *cobra.Command, args []string) error { func (o *ServeOptions) Options(_ *cli.Context) error {
return nil return nil
} }

View file

@ -12,7 +12,7 @@ import (
type Configuration struct { type Configuration struct {
Config Config
configPath string `yaml:"-"` configPath *string `yaml:"-"`
} }
type Config struct { type Config struct {

View file

@ -11,34 +11,31 @@ import (
"github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/file" "github.com/knadh/koanf/providers/file"
"github.com/knadh/koanf/v2" "github.com/knadh/koanf/v2"
// "github.com/knadh/koanf/providers/posflag"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/spf13/cobra" "github.com/urfave/cli/v2"
) )
func (c *Configuration) PreRunE() func(*cobra.Command, []string) error { func New(configFile *string) *Configuration {
return func(cmd *cobra.Command, args []string) error { if configFile == nil {
return c.ReadConfig() panic("configFile must not be nil")
} }
return &Configuration{configPath: configFile}
} }
func New(rootCommand *cobra.Command) *Configuration { func (c *Configuration) Before(ctx *cli.Context) error {
c := &Configuration{} return c.ReadConfig()
rootCommand.PersistentFlags().StringVarP(&c.configPath, "config", "c", "config.yaml", "configuration file")
return c
} }
func (c *Configuration) ReadConfig() error { func (c *Configuration) ReadConfig() error {
log.Info().Str("configPath", c.configPath).Msg("read config") log.Info().Str("configPath", *c.configPath).Msg("read config")
return c.read() return c.read()
} }
func (c *Configuration) read() error { func (c *Configuration) read() error {
k := koanf.New(".") k := koanf.New(".")
err := k.Load(file.Provider(c.configPath), yaml.Parser()) err := k.Load(file.Provider(*c.configPath), yaml.Parser())
if err != nil { if err != nil {
return err return err
} }
@ -52,7 +49,7 @@ func (c *Configuration) read() error {
koanf.UnmarshalConf{ koanf.UnmarshalConf{
Tag: "yaml", Tag: "yaml",
DecoderConfig: &mapstructure.DecoderConfig{ DecoderConfig: &mapstructure.DecoderConfig{
Result: &c.Config, Result: &c.Config,
WeaklyTypedInput: true, WeaklyTypedInput: true,
DecodeHook: mapstructure.ComposeDecodeHookFunc( DecodeHook: mapstructure.ComposeDecodeHookFunc(
mapstructure.StringToTimeDurationHookFunc(), mapstructure.StringToTimeDurationHookFunc(),