I am working on a Golang project which needs to dump system configuration to a designated path. Are there any libraries that can generate .cfg file from inside a golang program?
I tried to search for Viper but could not find a suitable example which reads/writes to a .cfg file. It supports JSON, toml and other formats.
CodePudding user response:
It doesn't support the .cfg file format out of the box, but it's possible to create a custom configuration file type by implementing the Marshaler and Unmarshaler interfaces, like:
package main
import (
"fmt"
"io"
"os"
"github.com/spf13/viper"
)
type cfgFile struct {
Config map[string]string
}
func (c *cfgFile) Marshal(w io.Writer) error {
for k, v := range c.Config {
if _, err := fmt.Fprintf(w, "%s = %s\n", k, v); err != nil {
return err
}
}
return nil
}
func (c *cfgFile) Unmarshal(r io.Reader) error {
c.Config = make(map[string]string)
var key, value string
for {
_, err := fmt.Fscanf(r, "%s = %s\n", &key, &value)
if err != nil {
if err == io.EOF {
break
}
return err
}
c.Config[key] = value
}
return nil
}
func main() {
// Create a new Viper instance.
v := viper.New()
// Set the configuration file type to use the custom cfgFile type.
v.SetConfigType("cfg")
// Set the configuration file path.
v.SetConfigFile("config.cfg")
// Set the configuration file type marshaler and unmarshaler.
v.SetConfigMarshaler(&cfgFile{}, viper.MarshalFunc(func(v interface{}, w io.Writer) error {
return v.(*cfgFile).Marshal(w)
}))
v.SetConfigTypeUnmarshaler("cfg", viper.UnmarshalFunc(func(r io.Reader, v interface{}) error {
return v.(*cfgFile).Unmarshal(r)
}))
// Read the configuration file.
if err := v.ReadInConfig(); err != nil {
fmt.Printf("Error reading config file: %s\n", err)
return
}
// Get a value from the configuration.
value := v.GetString("key")
fmt.Println(value)
// Set a value in the configuration.
v.Set("key", "value")
// Write the configuration to the file.
if err := v.WriteConfig(); err != nil {
fmt.Printf("Error writing config file: %s\n", err)
return
}
}