bump(github.com/ccding/go-config-reader): 8b6c2b50197f20da3b1c5944c274c173634dc056

This commit is contained in:
Brandon Philips
2013-08-18 19:43:20 -07:00
parent 7ec0ee2a19
commit 2662b3c559
2 changed files with 127 additions and 25 deletions

View File

@ -13,23 +13,60 @@
// limitations under the License. // limitations under the License.
// //
// author: Cong Ding <dinggnu@gmail.com> // author: Cong Ding <dinggnu@gmail.com>
//
package config package config
import ( import (
"bufio" "bufio"
"errors" "errors"
"fmt"
"io/ioutil"
"os" "os"
"strings" "strings"
) )
var commentPrefix = []string{"//", "#", ";"} var commentPrefix = []string{"//", "#", ";"}
func Read(filename string) (map[string]string, error) { // Config struct constructs a new configuration handler.
var res = map[string]string{} type Config struct {
in, err := os.Open(filename) filename string
config map[string]map[string]string
}
// NewConfig function cnstructs a new Config struct with filename. You have to
// call Read() function to let it read from the file. Otherwise you will get
// empty string (i.e., "") when you are calling Get() function. Another usage
// is that you call NewConfig() function and then call Add()/Set() function to
// add new key-values to the configuration. Finally you can call Write()
// function to write the new configuration to the file.
func NewConfig(filename string) *Config {
c := new(Config)
c.filename = filename
c.config = make(map[string]map[string]string)
return c
}
// Filename function returns the filename of the configuration.
func (c *Config) Filename() string {
return c.filename
}
// SetFilename function sets the filename of the configuration.
func (c *Config) SetFilename(filename string) {
c.filename = filename
}
// Reset function reset the map in the configuration.
func (c *Config) Reset() {
c.config = make(map[string]map[string]string)
}
// Read function reads configurations from the file defined in
// Config.filename.
func (c *Config) Read() error {
in, err := os.Open(c.filename)
if err != nil { if err != nil {
return res, err return err
} }
defer in.Close() defer in.Close()
scanner := bufio.NewScanner(in) scanner := bufio.NewScanner(in)
@ -40,9 +77,9 @@ func Read(filename string) (map[string]string, error) {
continue continue
} }
if line == "" { if line == "" {
sec := checkSection(scanner.Text()) sec, ok := checkSection(scanner.Text())
if sec != "" { if ok {
section = sec + "." section = sec
continue continue
} }
} }
@ -54,40 +91,103 @@ func Read(filename string) (map[string]string, error) {
line = line[:len(line)-1] line = line[:len(line)-1]
continue continue
} }
key, value, err := checkLine(line) key, value, ok := checkLine(line)
if err != nil { if !ok {
return res, errors.New("WRONG: " + line) return errors.New("WRONG: " + line)
} }
res[section+key] = value c.Set(section, key, value)
line = "" line = ""
} }
return res, nil return nil
} }
func checkSection(line string) string { // Get function returns the value of a key in the configuration. If the key
// does not exist, it returns empty string (i.e., "").
func (c *Config) Get(section string, key string) string {
value, ok := c.config[section][key]
if !ok {
return ""
}
return value
}
// Set function updates the value of a key in the configuration. Function
// Set() is exactly the same as function Add().
func (c *Config) Set(section string, key string, value string) {
_, ok := c.config[section]
if !ok {
c.config[section] = make(map[string]string)
}
c.config[section][key] = value
}
// Add function adds a new key to the configuration. Function Add() is exactly
// the same as function Set().
func (c *Config) Add(section string, key string, value string) {
c.Set(section, key, value)
}
// Del function deletes a key from the configuration.
func (c *Config) Del(section string, key string) {
_, ok := c.config[section]
if ok {
delete(c.config[section], key)
if len(c.config[section]) == 0 {
delete(c.config, section)
}
}
}
// Write function writes the updated configuration back.
func (c *Config) Write() error {
return nil
}
// WriteTo function writes the configuration to a new file. This function
// re-organizes the configuration and deletes all the comments.
func (c *Config) WriteTo(filename string) error {
content := ""
for k, v := range c.config {
format := "%v = %v\n"
if k != "" {
content += fmt.Sprintf("[%v]\n", k)
format = "\t" + format
}
for key, value := range v {
content += fmt.Sprintf(format, key, value)
}
}
return ioutil.WriteFile(filename, []byte(content), 0644)
}
// To check this line is a section or not. If it is not a section, it returns
// "".
func checkSection(line string) (string, bool) {
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
lineLen := len(line) lineLen := len(line)
if lineLen < 2 { if lineLen < 2 {
return "" return "", false
} }
if line[0] == '[' && line[lineLen-1] == ']' { if line[0] == '[' && line[lineLen-1] == ']' {
return line[1 : lineLen-1] return line[1 : lineLen-1], true
} }
return "" return "", false
} }
func checkLine(line string) (string, string, error) { // To check this line is a valid key-value pair or not.
func checkLine(line string) (string, string, bool) {
key := "" key := ""
value := "" value := ""
sp := strings.SplitN(line, "=", 2) sp := strings.SplitN(line, "=", 2)
if len(sp) != 2 { if len(sp) != 2 {
return key, value, errors.New("WRONG: " + line) return key, value, false
} }
key = strings.TrimSpace(sp[0]) key = strings.TrimSpace(sp[0])
value = strings.TrimSpace(sp[1]) value = strings.TrimSpace(sp[1])
return key, value, nil return key, value, true
} }
// To check this line is a whole line comment or not.
func checkComment(line string) bool { func checkComment(line string) bool {
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
for p := range commentPrefix { for p := range commentPrefix {

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
// //
// author: Cong Ding <dinggnu@gmail.com> // author: Cong Ding <dinggnu@gmail.com>
//
package main package main
import ( import (
@ -22,9 +22,11 @@ import (
) )
func main() { func main() {
res, err := config.Read("example.conf") c := config.NewConfig("example.conf")
err := c.Read()
fmt.Println(err) fmt.Println(err)
fmt.Println(res) fmt.Println(c)
fmt.Println(res["test.a"]) fmt.Println(c.Get("test", "a"))
fmt.Println(res["dd"]) fmt.Println(c.Get("", "dd"))
c.WriteTo("example2.conf")
} }