package main import ( "bufio" "errors" "log" "os" "strconv" "strings" ) // Configuration holds a configuration for the service. type Configuration struct { ListenAddress string IndentedOutput bool Processes []string } // LoadConfiguration loads configuration from a file. func LoadConfiguration(path string) (conf *Configuration, err error) { conf = &Configuration{} file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() s := bufio.NewScanner(file) s.Split(bufio.ScanLines) for s.Scan() { kv := strings.Split(s.Text(), " = ") switch kv[0] { case "listen_address": conf.ListenAddress = kv[1] case "indented_output": v, err := strconv.ParseBool(kv[1]) if err != nil { log.Printf("[WARN] could not parse \"indented_output\", valid values are true or false. Defaulted to false.\n") } conf.IndentedOutput = v case "processes": if kv[1] != "" { conf.Processes = append(conf.Processes, strings.Split(kv[1], " ")...) } else { log.Printf("[WARN] \"processes\" list is empty.\n") } } } return conf, nil } // StoreConfiguration writes configuration into a file. func (conf *Configuration) StoreConfiguration(path string) (err error) { var config strings.Builder config.WriteString("listen_address = ") config.WriteString(conf.ListenAddress) config.WriteByte('\n') config.WriteString("indented_output = ") config.WriteString(strconv.FormatBool(conf.IndentedOutput)) config.WriteByte('\n') config.WriteString("processes = ") config.WriteString(strings.Join(conf.Processes, " ")) if err := os.WriteFile(path, []byte(config.String()), 0644); err != nil { return err } return nil } // AddProcess appends a new given process into a configuration file. func (conf *Configuration) AddProcess(process string, configPath string) error { for _, v := range conf.Processes { if v == process { return errors.New("process is already on list") } } conf.Processes = append(conf.Processes, process) return nil } // RemoveProcess removes a given process from a configuration file. func (conf *Configuration) RemoveProcess(process string, configPath string) error { for k, v := range conf.Processes { if v == process { newlist := make([]string, len(conf.Processes)-1) newlist = append(conf.Processes[:k], conf.Processes[k+1:]...) conf.Processes = newlist return nil } } return errors.New("process is not on list") }