func TestMain(t *testing.T) { Convey("readConfig", t, func() { readConfig() So(viper.AllKeys(), ShouldContain, "loglevel") }) Convey("setupLogging", t, func() { setupLogging() So(log.DisplayTime(), ShouldBeTrue) So(log.Level(), ShouldEqual, log.DebugLevel) }) }
func (cfg *viperProvider) initValues() { cfg.configValues = make(map[string]interface{}) for _, key := range viper.AllKeys() { configType, present := cfg.configTypes[key] if !present { continue } config := reflect.New(configType).Interface() err := viper.MarshalKey(key, config) if err != nil { cfg.log.Fatalf("Can't parse section %s, got: %v", key, err) } cfg.substituteEnvVars(config) cfg.configValues[key] = config } }
// CheckForDuplicateAliases validates that all commands have unique aliases. func CheckForDuplicateAliases() error { var aliases []string logrus.Infoln("Checking for duplicate aliases...") // It would be preferred to use viper.Sub("aliases") here, but there are some // nil pointer dereferencing issues. for _, setting := range viper.AllKeys() { if strings.HasSuffix(setting, "aliases") { aliases = append(aliases, viper.GetStringSlice(setting)...) } } // Sort the strings to allow us to fail faster in case there is a duplicate. sort.Strings(aliases) for i := 0; i < len(aliases)-1; i++ { if aliases[i] == aliases[i+1] { return fmt.Errorf("Duplicate alias found: %s", aliases[i]) } } return nil }
func main() { app := cli.NewApp() app.Name = "MumbleDJ" app.Usage = "A Mumble bot that plays audio from various media sites." app.Version = DJ.Version app.Flags = []cli.Flag{ cli.StringFlag{ Name: "config, c", Value: os.ExpandEnv("$HOME/.config/mumbledj/config.yaml"), Usage: "location of MumbleDJ configuration file", }, cli.StringFlag{ Name: "server, s", Value: "127.0.0.1", Usage: "address of Mumble server to connect to", }, cli.StringFlag{ Name: "port, o", Value: "64738", Usage: "port of Mumble server to connect to", }, cli.StringFlag{ Name: "username, u", Value: "MumbleDJ", Usage: "username for the bot", }, cli.StringFlag{ Name: "password, p", Value: "", Usage: "password for the Mumble server", }, cli.StringFlag{ Name: "channel, n", Value: "", Usage: "channel the bot enters after connecting to the Mumble server", }, cli.StringFlag{ Name: "cert, e", Value: "", Usage: "path to PEM certificate", }, cli.StringFlag{ Name: "key, k", Value: "", Usage: "path to PEM key", }, cli.StringFlag{ Name: "accesstokens, a", Value: "", Usage: "list of access tokens separated by spaces", }, cli.BoolFlag{ Name: "insecure, i", Usage: "if present, the bot will not check Mumble certs for consistency", }, cli.BoolFlag{ Name: "debug, d", Usage: "if present, all debug messages will be shown", }, } hiddenFlags := make([]cli.Flag, len(viper.AllKeys())) for i, configValue := range viper.AllKeys() { hiddenFlags[i] = cli.StringFlag{ Name: configValue, Hidden: true, } } app.Flags = append(app.Flags, hiddenFlags...) app.Action = func(c *cli.Context) error { if c.Bool("debug") { logrus.SetLevel(logrus.InfoLevel) } for _, configValue := range viper.AllKeys() { if c.GlobalIsSet(configValue) { if strings.Contains(c.String(configValue), ",") { viper.Set(configValue, strings.Split(c.String(configValue), ",")) } else { viper.Set(configValue, c.String(configValue)) } } } viper.SetConfigFile(c.String("config")) if err := viper.ReadInConfig(); err != nil { logrus.WithFields(logrus.Fields{ "file": c.String("config"), "error": err.Error(), }).Warnln("An error occurred while reading the configuration file. Using default configuration...") if _, err := os.Stat(c.String("config")); os.IsNotExist(err) { createConfigWhenNotExists() } } else { if duplicateErr := bot.CheckForDuplicateAliases(); duplicateErr != nil { logrus.WithFields(logrus.Fields{ "issue": duplicateErr.Error(), }).Fatalln("An issue was discoverd in your configuration.") } createNewConfigIfNeeded() viper.WatchConfig() } if c.GlobalIsSet("server") { viper.Set("connection.address", c.String("server")) } if c.GlobalIsSet("port") { viper.Set("connection.port", c.String("port")) } if c.GlobalIsSet("username") { viper.Set("connection.username", c.String("username")) } if c.GlobalIsSet("password") { viper.Set("connection.password", c.String("password")) } if c.GlobalIsSet("channel") { viper.Set("defaults.channel", c.String("channel")) } if c.GlobalIsSet("cert") { viper.Set("connection.cert", c.String("cert")) } if c.GlobalIsSet("key") { viper.Set("connection.key", c.String("key")) } if c.GlobalIsSet("accesstokens") { viper.Set("connection.access_tokens", c.String("accesstokens")) } if c.GlobalIsSet("insecure") { viper.Set("connection.insecure", c.Bool("insecure")) } if err := DJ.Connect(); err != nil { logrus.WithFields(logrus.Fields{ "error": err.Error(), }).Fatalln("An error occurred while connecting to the server.") } if viper.GetString("defaults.channel") != "" { defaultChannel := strings.Split(viper.GetString("defaults.channel"), "/") DJ.Client.Do(func() { DJ.Client.Self.Move(DJ.Client.Channels.Find(defaultChannel...)) }) } DJ.Client.Do(func() { DJ.Client.Self.SetComment(viper.GetString("defaults.comment")) }) <-DJ.KeepAlive return nil } app.Run(os.Args) }