package cmd import ( "fmt" "log" "log/slog" "math/rand" "os" "strings" "time" "git.bloy.org/mike/hasshelper/web" "github.com/spf13/cobra" "github.com/spf13/viper" ) var cfgFile string var rootCmd = &cobra.Command{ Use: "hasshelper", Short: "Helper for Home Assistant installations.", Run: rootCmdRun, } func logLevelVar(str string) slog.Level { levelUpper := strings.ToUpper(str) switch levelUpper { case "DEBUG": return slog.LevelDebug case "INFO": return slog.LevelInfo case "WARN": return slog.LevelWarn case "ERROR": return slog.LevelError default: return slog.LevelInfo } } func rootCmdRun(cmd *cobra.Command, args []string) { logLevel := logLevelVar(viper.GetString("loglevel")) logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})) logger.Info("HASSHelper startup", "version", viper.GetString("version")) exitchan := make(chan bool) web.Run(logger, exitchan) <-exitchan // run the main command until one of the goroutines is done } // Execute will kick off cobra's processing of the root command func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } func init() { rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.config/hasshelper/config.toml)") cobra.OnInitialize(initConfig) const dirName = "hasshelper" var userConfigDir, err = os.UserConfigDir() if err == nil { viper.AddConfigPath( fmt.Sprintf("%s%c%s", userConfigDir, os.PathSeparator, dirName)) } else { log.Println("could not locate user config dir:", err) } viper.AddConfigPath(fmt.Sprintf("/etc%c%s", os.PathSeparator, dirName)) viper.SetConfigName("config.toml") viper.SetEnvPrefix("hasshelper") } func initConfig() { viper.Set("version", gitVersion) viper.SetDefault("deployment", "prod") viper.SetDefault("loglevel", "info") viper.AutomaticEnv() if cfgFile != "" { viper.SetConfigFile(cfgFile) } if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { log.Printf("no config file found. Environment only") } else { log.Fatalf("error reading config file: %v\n", err) } } expected_config := []string{ "deployment", "image_dir", "version", "webserver_port", } for _, key := range expected_config { if !viper.IsSet(key) { fmt.Fprintf(os.Stderr, "Missing configuration value: %s\n", key) os.Exit(1) } } rand.Seed(time.Now().UnixNano()) }