Move to urfave/cli
This commit is contained in:
parent
f1e65aaa68
commit
4bee6840dc
8 changed files with 130 additions and 97 deletions
|
@ -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
7
go.mod
|
@ -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
14
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
Loading…
Reference in a new issue