package forgepb // functions to import and export the protobuf // data to and from config files import ( "errors" "os" "path/filepath" "go.wit.com/log" ) // writes out the cluster information it seperate files // to make it humanly possible to hand edit things as needed func (m *Repos) ConfigSave() error { if os.Getenv("FORGE_HOME") == "" { homeDir, _ := os.UserHomeDir() fullpath := filepath.Join(homeDir, ".config/forge") os.Setenv("FORGE_HOME", fullpath) } // try to backup the current cluster config files if err := backupConfig(); err != nil { return err } data, err := m.Marshal() if err != nil { log.Info("proto.Marshal() failed len", len(data), err) return err } log.Info("proto.Marshal() worked len", len(data)) configWrite("forge.pb", data) s := m.FormatTEXT() configWrite("forge.text", []byte(s)) s = m.FormatJSON() configWrite("forge.json", []byte(s)) return nil } func (m *Repos) ConfigLoad() error { if os.Getenv("FORGE_HOME") == "" { homeDir, _ := os.UserHomeDir() fullpath := filepath.Join(homeDir, ".config/forge") os.Setenv("FORGE_HOME", fullpath) } var data []byte var err error if m == nil { return errors.New("It's not safe to run ConfigLoad() on a nil ?") } if data, err = loadFile("forge.pb"); err != nil { // something went wrong loading the file return err } if data != nil { // this means the forge.pb file exists and was read if len(data) == 0 { // todo: error out if the file is empty? // try forge.text & forge.json? } if err = m.Unmarshal(data); err != nil { log.Warn("broken forge.pb config file") return err } log.Info("config load found", len(m.Repos), "repos") return nil } // forge.db doesn't exist. try forge.text // this lets the user hand edit the config if data, err = loadFile("forge.text"); err != nil { // something went wrong loading the file return err } if data != nil { // this means the forge.text file exists and was read if len(data) == 0 { // todo: error out if the file is empty? } if err = m.UnmarshalTEXT(data); err != nil { log.Warn("broken forge.text config file") return err } log.Info("config load found", len(m.Repos), "repos") return nil } // forge.text doesn't exist. try forge.json // this lets the user hand edit the config if data, err = loadFile("forge.json"); err != nil { // something went wrong loading the file return err } if data != nil { // this means the forge.text file exists and was read if len(data) == 0 { // todo: error out if the file is empty? } if err = m.UnmarshalJSON(data); err != nil { log.Warn("broken forge.json config file") return err } log.Info("config load found", len(m.Repos), "repos") return nil } // first time user. make a template config file return nil } func loadFile(filename string) ([]byte, error) { fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename) data, err := os.ReadFile(fullname) if errors.Is(err, os.ErrNotExist) { // if file does not exist, just return nil. this // will cause ConfigLoad() to try the next config file like "forge.text" // because the user might want to edit the .config by hand return nil, nil } if err != nil { // log.Info("open config file :", err) return nil, err } return data, nil } func configWrite(filename string, data []byte) error { fullname := filepath.Join(os.Getenv("FORGE_HOME"), filename) cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE, 0666) defer cfgfile.Close() if err != nil { log.Warn("open config file :", err) return err } cfgfile.Write(data) return nil }