Skip to content

Commit 45700cc

Browse files
authored
Merge pull request #12 from owenthereal/flag_refactor
Move config parsing to cmd
2 parents 63e7b0e + 21bf629 commit 45700cc

File tree

6 files changed

+87
-117
lines changed

6 files changed

+87
-117
lines changed

cmd/candy/cmd/root.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ var rootCmd = &cobra.Command{
2020
}
2121

2222
var (
23-
homeDir string
24-
flagRootCfgFile string
23+
homeDir string
24+
flagConfigFile string
2525
)
2626

2727
func init() {
28-
rootCmd.PersistentFlags().StringVar(&flagRootCfgFile, "config", filepath.Join(userHomeDir(), ".candyconfig"), "Config file")
28+
rootCmd.PersistentFlags().StringVar(&flagConfigFile, "config", filepath.Join(userHomeDir(), ".candyconfig"), "Config file")
2929
}
3030

3131
func userHomeDir() string {

cmd/candy/cmd/run.go

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8+
"strings"
89

910
"github.com/owenthereal/candy"
1011
"github.com/owenthereal/candy/server"
1112
"github.com/spf13/cobra"
13+
"github.com/spf13/pflag"
14+
"github.com/spf13/viper"
1215
"go.uber.org/zap"
1316
)
1417

@@ -46,20 +49,8 @@ func runRunE(c *cobra.Command, args []string) error {
4649
}
4750

4851
func startServer(c *cobra.Command, ctx context.Context) error {
49-
var cfg server.Config
50-
if err := candy.LoadConfig(
51-
flagRootCfgFile,
52-
c,
53-
[]string{
54-
"host-root",
55-
"domain",
56-
"http-addr",
57-
"https-addr",
58-
"admin-addr",
59-
"dns-addr",
60-
},
61-
&cfg,
62-
); err != nil {
52+
cfg, err := loadServerConfig(c)
53+
if err != nil {
6354
return err
6455
}
6556

@@ -69,7 +60,51 @@ func startServer(c *cobra.Command, ctx context.Context) error {
6960
return fmt.Errorf("failed to create host directory %s: %w", cfg.HostRoot, err)
7061
}
7162

72-
svr := server.New(cfg)
63+
svr := server.New(*cfg)
7364

7465
return svr.Run(ctx)
7566
}
67+
68+
func loadServerConfig(cmd *cobra.Command) (*server.Config, error) {
69+
var cfg server.Config
70+
71+
if err := unmarshalFlags(flagConfigFile, cmd, &cfg); err != nil {
72+
return nil, err
73+
}
74+
75+
if err := cfg.Validate(); err != nil {
76+
return nil, err
77+
}
78+
79+
return &cfg, nil
80+
}
81+
82+
func unmarshalFlags(cfgFile string, cmd *cobra.Command, opts interface{}) error {
83+
v := viper.New()
84+
85+
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
86+
flagName := flag.Name
87+
if flagName != "config" && flagName != "help" {
88+
if err := v.BindPFlag(flagName, flag); err != nil {
89+
panic(fmt.Errorf("error binding flag '%s': %w", flagName, err).Error())
90+
}
91+
}
92+
})
93+
94+
v.AutomaticEnv()
95+
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
96+
v.SetEnvPrefix("CANDY")
97+
98+
if _, err := os.Stat(cfgFile); err == nil {
99+
v.SetConfigFile(cfgFile)
100+
v.SetConfigType("json")
101+
}
102+
103+
if err := v.ReadInConfig(); err != nil {
104+
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
105+
return fmt.Errorf("error loading config file %s: %w", cfgFile, err)
106+
}
107+
}
108+
109+
return v.Unmarshal(opts)
110+
}

cmd/candy/cmd/setup_darwin.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"strings"
1313

1414
"github.com/owenthereal/candy"
15-
"github.com/owenthereal/candy/server"
1615
"github.com/spf13/cobra"
1716
"go.uber.org/zap"
1817
)
@@ -50,16 +49,8 @@ func setupRunE(c *cobra.Command, args []string) error {
5049
}
5150

5251
func runSetupRunE(c *cobra.Command, args []string) error {
53-
var cfg server.Config
54-
if err := candy.LoadConfig(
55-
flagRootCfgFile,
56-
c,
57-
[]string{
58-
"domain",
59-
"dns-addr",
60-
},
61-
&cfg,
62-
); err != nil {
52+
cfg, err := loadServerConfig(c)
53+
if err != nil {
6354
return err
6455
}
6556

@@ -72,7 +63,7 @@ func runSetupRunE(c *cobra.Command, args []string) error {
7263
return err
7364
}
7465

75-
var logger = candy.Log()
66+
logger := candy.Log()
7667

7768
for _, domain := range cfg.Domain {
7869
file := filepath.Join(resolverDir, "candy-"+domain)

cmd/candy/cmd/setup_linux.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"strings"
1313

1414
"github.com/owenthereal/candy"
15-
"github.com/owenthereal/candy/server"
1615
"github.com/spf13/cobra"
1716
"go.uber.org/zap"
1817
)
@@ -49,16 +48,8 @@ func setupRunE(c *cobra.Command, args []string) error {
4948
}
5049

5150
func runSetupRunE(c *cobra.Command, args []string) error {
52-
var cfg server.Config
53-
if err := candy.LoadConfig(
54-
flagRootCfgFile,
55-
c,
56-
[]string{
57-
"domain",
58-
"dns-addr",
59-
},
60-
&cfg,
61-
); err != nil {
51+
cfg, err := loadServerConfig(c)
52+
if err != nil {
6253
return err
6354
}
6455

config.go

Lines changed: 0 additions & 76 deletions
This file was deleted.

server/server.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package server
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/owenthereal/candy"
78
"github.com/owenthereal/candy/caddy"
@@ -21,6 +22,34 @@ type Config struct {
2122
DnsLocalIp bool `mapstructure:"dns-local-ip"`
2223
}
2324

25+
func (c Config) Validate() error {
26+
if c.HostRoot == "" {
27+
return fmt.Errorf("--host-root is required")
28+
}
29+
30+
if len(c.Domain) == 0 {
31+
return fmt.Errorf("--domain is required")
32+
}
33+
34+
if c.HttpAddr == "" {
35+
return fmt.Errorf("--http-addr is required")
36+
}
37+
38+
if c.HttpsAddr == "" {
39+
return fmt.Errorf("--https-addr is required")
40+
}
41+
42+
if c.AdminAddr == "" {
43+
return fmt.Errorf("--admin-addr is required")
44+
}
45+
46+
if c.DnsAddr == "" {
47+
return fmt.Errorf("--dns-addr is required")
48+
}
49+
50+
return nil
51+
}
52+
2453
func New(cfg Config) *Server {
2554
return &Server{cfg: cfg}
2655
}

0 commit comments

Comments
 (0)