comparison cmd/gemma/root.go @ 221:696c19abe869

Argh! If one is using its own storage for config like we do the config loaded by viper needs to be injected back into cobra [https://github.com/spf13/cobra/issues/367].
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 24 Jul 2018 18:21:31 +0200
parents 11d1a488b08f
children 63dd5216eee4
comparison
equal deleted inserted replaced
220:11d1a488b08f 221:696c19abe869
12 12
13 "gemma.intevation.de/gemma/auth" 13 "gemma.intevation.de/gemma/auth"
14 "gemma.intevation.de/gemma/config" 14 "gemma.intevation.de/gemma/config"
15 homedir "github.com/mitchellh/go-homedir" 15 homedir "github.com/mitchellh/go-homedir"
16 "github.com/spf13/cobra" 16 "github.com/spf13/cobra"
17 "github.com/spf13/pflag"
17 "github.com/spf13/viper" 18 "github.com/spf13/viper"
18 ) 19 )
19 20
20 var rootCmd = &cobra.Command{ 21 var rootCmd = &cobra.Command{
21 Use: "gemma", 22 Use: "gemma",
22 Short: "gemma is a server for waterway monitoring and management", 23 Short: "gemma is a server for waterway monitoring and management",
23 Run: start, 24 Run: start,
24 } 25 }
25 26
27 // This is not part of the persistent config.
28 var configFile string
29
26 func init() { 30 func init() {
27 cobra.OnInitialize(initConfig) 31 cobra.OnInitialize(initConfig)
28 fl := rootCmd.PersistentFlags 32 fl := rootCmd.PersistentFlags
29 fl().StringVarP(&config.Config.File, "config", "c", "", "config file (default is $HOME/.gemma.toml)") 33 fl().StringVarP(&configFile, "config", "c", "", "config file (default is $HOME/.gemma.toml)")
30 fl().StringVarP(&config.Config.DBHost, "dbhost", "H", "localhost", "host of the database") 34 fl().StringVarP(&config.Config.DBHost, "dbhost", "H", "localhost", "host of the database")
31 fl().UintVarP(&config.Config.DBPort, "dbport", "P", 5432, "port of the database") 35 fl().UintVarP(&config.Config.DBPort, "dbport", "P", 5432, "port of the database")
32 fl().StringVarP(&config.Config.DBName, "dbname", "d", "gemma", "name of the database") 36 fl().StringVarP(&config.Config.DBName, "dbname", "d", "gemma", "name of the database")
33 fl().StringVarP(&config.Config.DBSSLMode, "dbssl", "S", "require", "SSL mode of the database") 37 fl().StringVarP(&config.Config.DBSSLMode, "dbssl", "S", "require", "SSL mode of the database")
34 38
50 viper.BindPFlag("port", fl().Lookup("port")) 54 viper.BindPFlag("port", fl().Lookup("port"))
51 } 55 }
52 56
53 func initConfig() { 57 func initConfig() {
54 // Don't forget to read config either from cfgFile or from home directory! 58 // Don't forget to read config either from cfgFile or from home directory!
55 if config.Config.File != "" { 59 if configFile != "" {
56 // Use config file from the flag. 60 // Use config file from the flag.
57 viper.SetConfigFile(config.Config.File) 61 viper.SetConfigFile(configFile)
58 } else { 62 } else {
59 // Find home directory. 63 // Find home directory.
60 home, err := homedir.Dir() 64 home, err := homedir.Dir()
61 if err != nil { 65 if err != nil {
62 fmt.Println(err) 66 fmt.Println(err)
66 // Search config in home directory with name ".cobra" (without extension). 70 // Search config in home directory with name ".cobra" (without extension).
67 viper.AddConfigPath(home) 71 viper.AddConfigPath(home)
68 viper.SetConfigName(".gemma") 72 viper.SetConfigName(".gemma")
69 } 73 }
70 if err := viper.ReadInConfig(); err != nil { 74 if err := viper.ReadInConfig(); err != nil {
71 if _, ok := err.(viper.ConfigFileNotFoundError); ok { 75 if _, ok := err.(viper.ConfigFileNotFoundError); ok && configFile == "" {
72 // Don't bother if not found. 76 // Don't bother if not found.
73 return 77 return
74 } 78 }
75 log.Fatalf("Can't read config: %v\n", err) 79 log.Fatalf("Can't read config: %v\n", err)
76 } 80 }
77 } 81 }
78 82
83 func injectViper(cmd *cobra.Command) {
84 cmd.Flags().VisitAll(func(f *pflag.Flag) {
85 if !f.Changed {
86 if viper.IsSet(f.Name) {
87 cmd.Flags().Set(f.Name, viper.GetString(f.Name))
88 }
89 }
90 })
91 }
92
79 func start(cmd *cobra.Command, args []string) { 93 func start(cmd *cobra.Command, args []string) {
94
95 // XXX: This hack is needed because we have our
96 // own config storage.
97 injectViper(cmd)
80 98
81 // Install connection pool 99 // Install connection pool
82 cp, err := auth.NewConnectionPool(config.Config.SessionStore) 100 cp, err := auth.NewConnectionPool(config.Config.SessionStore)
83 if err != nil { 101 if err != nil {
84 log.Fatalf("Error with session store: %v\n", err) 102 log.Fatalf("Error with session store: %v\n", err)
87 105
88 p, err := filepath.Abs(config.Config.Web) 106 p, err := filepath.Abs(config.Config.Web)
89 if err != nil { 107 if err != nil {
90 log.Fatalf("error: %v\n", err) 108 log.Fatalf("error: %v\n", err)
91 } 109 }
92 log.Printf("web: %s\n", p)
93 mux := http.NewServeMux() 110 mux := http.NewServeMux()
94 mux.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(p)))) 111 mux.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(p))))
95 mux.HandleFunc("/api/token", token) 112 mux.HandleFunc("/api/token", token)
96 mux.Handle("/api/logout", auth.SessionMiddleware(http.HandlerFunc(token))) 113 mux.Handle("/api/logout", auth.SessionMiddleware(http.HandlerFunc(token)))
97 mux.Handle("/api/renew", auth.SessionMiddleware(http.HandlerFunc(renew))) 114 mux.Handle("/api/renew", auth.SessionMiddleware(http.HandlerFunc(renew)))