Viper Configuration Solutions - Backup Files Software From Scratch Written in Golang Tutorial #4
In this tutorial series #4, we know how to use the Viper complete configuration solutions for Go. Installed Packages: https://github.com/common-nighthawk/go-figure https://github.com/fsnotify/fsnotify https://github.com/mitchellh/go-homedir https://github.com/spf13/viper If you go with extra mile for buying me a cup of coffee, I appreciate it guys: https://ko-fi.com/maharlikanscode #MaharlikansCode #Viper #Golang #LifeAsSoftwareDeveloper #Maharlikans #FilipinoSoftwareDeveloper #ReadConfigurationFileInGolang Source Codes: main.go package main import ( "gokopy/cmd" ) func main() { cmd.Execute() } root.go package cmd import ( "errors" "fmt" "gokopy/config" "os" "strings" "github.com/common-nighthawk/go-figure" "github.com/fatih/color" "github.com/fsnotify/fsnotify" "github.com/itrepablik/itrlog" "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" ) // AppInfo ... type AppInfo struct { Name, Version string } // ConfigComDir is the collection of the comdir config values type ConfigComDir struct { Ignore []string Log bool } var appCon []AppInfo var conComDir []ConfigComDir var comdirIgnore []string var comdirLog bool = false var cfgFile string var logDTFormat string = config.DefaultDTFormat var rootCmd = &cobra.Command{ Use: config.AppName, Short: config.AppDesc, Long: config.AppDesc, Version: config.AppVersion, // Run: func(cmd *cobra.Command, args []string) { // // Do Stuff Here // fmt.Println("Hello Cobra CLI application") // }, } // Execute ... func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } func init() { // Display the app ASCII logo myFigure := figure.NewFigure(config.AppDisplayName, "", true) myFigure.Print() LoadViperCofig() viper.WatchConfig() // Tell the viper to watch any new changes to the config file. viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("Config file changed:", e.Name) itrlog.Warn("Config file changed:", e.Name) LoadViperCofig() }) } // LoadViperCofig reads the viper 'config.yaml' file func LoadViperCofig() { //******************************************************************************************** // Recall this block of scripts to re-initialize the viper instance and gets the latest values // from any config name value that has changes in real-time. //******************************************************************************************** cobra.OnInitialize(initConfig) viper.SetConfigName("config") // name of config file (without extension) viper.AddConfigPath(".") // optionally look for config in the working directory // Handle errors reading the config file if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found; create the "config.yaml" asap. f, err := os.OpenFile("config.yaml", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { itrlog.Fatalf("error opening file: %v", err) } defer f.Close() } else { // Config file was found but another error was produced itrlog.Fatalf("fatal error config file: %v", err) } } var err error err = viper.UnmarshalKey("app", &appCon) if err != nil { itrlog.Error(err) } for _, a := range appCon { if len(strings.TrimSpace(a.Name)) == 0 || strings.TrimSpace(a.Name) != config.AppName { errMsg := "app name must be " + config.AppName + ", please follow this naming convention to your config.yaml file under 'app'." color.Red(errMsg) itrlog.Fatal(errors.New(errMsg)) } if len(strings.TrimSpace(a.Version)) == 0 || strings.TrimSpace(a.Version) != config.AppVersion { errMsg := "app version must be " + config.AppVersion + ", please follow this naming convention to your config.yaml file under 'app'." color.Red(errMsg) itrlog.Fatal(errors.New(errMsg)) } } // Get the config values for the 'default.command_properties.comdir' keys from the config.yaml file err = viper.UnmarshalKey("default.command_properties.comdir", &conComDir) if err != nil { itrlog.Error(err) } for _, a := range conComDir { comdirIgnore = a.Ignore comdirLog = a.Log } } func initConfig() { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { // Find home directory. home, err := homedir.Dir() if err != nil { color.Red(err.Error()) itrlog.Error(err) os.Exit(1) } // Search config in home directory with name ".gokopy" (without extension). viper.AddConfigPath(home) viper.SetConfigName(".gokopy") } viper.AutomaticEnv() // read in environment variables that match // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { color.Red("Using config file: " + viper.ConfigFileUsed()) } } config.yaml app: name: gokopy version: 1.0.0 default: command_properties: comdir: ignore: [.jpg, .png, folder_name] log: true # true or false, true to enable the log
In this tutorial series #4, we know how to use the Viper complete configuration solutions for Go. Installed Packages: https://github.com/common-nighthawk/go-figure https://github.com/fsnotify/fsnotify https://github.com/mitchellh/go-homedir https://github.com/spf13/viper If you go with extra mile for buying me a cup of coffee, I appreciate it guys: https://ko-fi.com/maharlikanscode #MaharlikansCode #Viper #Golang #LifeAsSoftwareDeveloper #Maharlikans #FilipinoSoftwareDeveloper #ReadConfigurationFileInGolang Source Codes: main.go package main import ( "gokopy/cmd" ) func main() { cmd.Execute() } root.go package cmd import ( "errors" "fmt" "gokopy/config" "os" "strings" "github.com/common-nighthawk/go-figure" "github.com/fatih/color" "github.com/fsnotify/fsnotify" "github.com/itrepablik/itrlog" "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" ) // AppInfo ... type AppInfo struct { Name, Version string } // ConfigComDir is the collection of the comdir config values type ConfigComDir struct { Ignore []string Log bool } var appCon []AppInfo var conComDir []ConfigComDir var comdirIgnore []string var comdirLog bool = false var cfgFile string var logDTFormat string = config.DefaultDTFormat var rootCmd = &cobra.Command{ Use: config.AppName, Short: config.AppDesc, Long: config.AppDesc, Version: config.AppVersion, // Run: func(cmd *cobra.Command, args []string) { // // Do Stuff Here // fmt.Println("Hello Cobra CLI application") // }, } // Execute ... func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } func init() { // Display the app ASCII logo myFigure := figure.NewFigure(config.AppDisplayName, "", true) myFigure.Print() LoadViperCofig() viper.WatchConfig() // Tell the viper to watch any new changes to the config file. viper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("Config file changed:", e.Name) itrlog.Warn("Config file changed:", e.Name) LoadViperCofig() }) } // LoadViperCofig reads the viper 'config.yaml' file func LoadViperCofig() { //******************************************************************************************** // Recall this block of scripts to re-initialize the viper instance and gets the latest values // from any config name value that has changes in real-time. //******************************************************************************************** cobra.OnInitialize(initConfig) viper.SetConfigName("config") // name of config file (without extension) viper.AddConfigPath(".") // optionally look for config in the working directory // Handle errors reading the config file if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found; create the "config.yaml" asap. f, err := os.OpenFile("config.yaml", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { itrlog.Fatalf("error opening file: %v", err) } defer f.Close() } else { // Config file was found but another error was produced itrlog.Fatalf("fatal error config file: %v", err) } } var err error err = viper.UnmarshalKey("app", &appCon) if err != nil { itrlog.Error(err) } for _, a := range appCon { if len(strings.TrimSpace(a.Name)) == 0 || strings.TrimSpace(a.Name) != config.AppName { errMsg := "app name must be " + config.AppName + ", please follow this naming convention to your config.yaml file under 'app'." color.Red(errMsg) itrlog.Fatal(errors.New(errMsg)) } if len(strings.TrimSpace(a.Version)) == 0 || strings.TrimSpace(a.Version) != config.AppVersion { errMsg := "app version must be " + config.AppVersion + ", please follow this naming convention to your config.yaml file under 'app'." color.Red(errMsg) itrlog.Fatal(errors.New(errMsg)) } } // Get the config values for the 'default.command_properties.comdir' keys from the config.yaml file err = viper.UnmarshalKey("default.command_properties.comdir", &conComDir) if err != nil { itrlog.Error(err) } for _, a := range conComDir { comdirIgnore = a.Ignore comdirLog = a.Log } } func initConfig() { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { // Find home directory. home, err := homedir.Dir() if err != nil { color.Red(err.Error()) itrlog.Error(err) os.Exit(1) } // Search config in home directory with name ".gokopy" (without extension). viper.AddConfigPath(home) viper.SetConfigName(".gokopy") } viper.AutomaticEnv() // read in environment variables that match // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { color.Red("Using config file: " + viper.ConfigFileUsed()) } } config.yaml app: name: gokopy version: 1.0.0 default: command_properties: comdir: ignore: [.jpg, .png, folder_name] log: true # true or false, true to enable the log