Last active
April 18, 2021 16:27
-
-
Save marcelohmariano/fb7e4167ae9d611b1f074c70ae5dfdff to your computer and use it in GitHub Desktop.
Viper and Cobra example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net/http" | |
"github.com/spf13/cobra" | |
"github.com/spf13/viper" | |
) | |
type application struct { | |
cmd *cobra.Command | |
err error | |
} | |
func (a *application) AddCmdFlag(name string, value interface{}, usage string) { | |
if a.err != nil { | |
return | |
} | |
if value != nil { | |
viper.SetDefault(name, value) | |
} | |
flags := a.cmd.Flags() | |
switch v := value.(type) { | |
case int: | |
flags.Int(name, v, usage) | |
case string: | |
flags.String(name, v, usage) | |
} | |
a.err = viper.BindPFlag(name, flags.Lookup(name)) | |
} | |
func (a *application) Run() error { | |
if a.err != nil { | |
return a.err | |
} | |
a.err = a.cmd.Execute() | |
return a.err | |
} | |
func startServer(host string, port int) error { | |
address := fmt.Sprintf("%s:%d", host, port) | |
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | |
_, err := w.Write([]byte("Hello!\n")) | |
if err != nil { | |
http.Error(w, "error sending response", 500) | |
} | |
}) | |
log.Printf("Listening on %s:%d\n", host, port) | |
return http.ListenAndServe(address, nil) | |
} | |
func newServerCommand() *cobra.Command { | |
return &cobra.Command{ | |
Use: "server", | |
Short: "A simple HTTP server that reads configs from flags, env vars and a config file", | |
RunE: func(cmd *cobra.Command, args []string) error { | |
host := viper.GetString("host") | |
port := viper.GetInt("port") | |
return startServer(host, port) | |
}, | |
} | |
} | |
func loadConfig() { | |
if err := viper.ReadInConfig(); err != nil { | |
log.Println("not using config file") | |
} | |
} | |
func init() { | |
viper.SetTypeByDefaultValue(true) | |
viper.SetEnvPrefix("server") | |
viper.AutomaticEnv() | |
viper.SetConfigName("config") | |
viper.SetConfigType("yaml") | |
viper.AddConfigPath(".") | |
} | |
func main() { | |
loadConfig() | |
app := &application{cmd: newServerCommand()} | |
app.AddCmdFlag("host", "localhost", "Set the application host") | |
app.AddCmdFlag("port", 8000, "Set the application port") | |
if err := app.Run(); err != nil { | |
log.Fatalln(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This example code shows how to use Viper and Cobra to create an application that gets its configurations from command line, env vars and/or a config file.
The app can be run as follows:
or
or