package gosimpleconf import ( "bufio" "fmt" "io" "os" "strings" ) type ConfigMap map[string]string func Load(filename string) (ConfigMap, error) { return ReadFile(filename) } func ReadFile(filename string) (ConfigMap, error) { var err error file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() parsedMap, err := parseFile(file) if err != nil { return nil, err } return parsedMap, nil } func WriteFile(filename string, configMap ConfigMap) error { file, err := os.Create(filename) if err != nil { return err } defer file.Close() for k, v := range configMap { fmt.Fprintf(file, "%s = %s\n", k, v) } return nil } func parseFile(config io.Reader) (ConfigMap, error) { var err error parsedMap := make(ConfigMap) scanner := bufio.NewScanner(config) for scanner.Scan() { line := scanner.Text() trimmed := strings.TrimSpace(line) if len(trimmed) == 0 { // ignore empty lines continue } if trimmed[0] == '#' { // ignore comments continue } split := strings.Split(trimmed, "=") if len(split) < 2 { return nil, fmt.Errorf("failed to parse config line: %v", trimmed) } key := trimToken(split[0]) value := strings.Join(split[1:], "=") // Re-add any ='s that were part of the value value = trimToken(value) parsedMap[key] = value } if err = scanner.Err(); err != nil { return nil, err } return parsedMap, nil } func trimToken(value string) string { // Trim off whitespace v := strings.TrimSpace(value) // Trim off any surrounding quotes, everything is a string anyway v = strings.TrimPrefix(v, "\"") v = strings.TrimSuffix(v, "\"") return v }