go vendor
This commit is contained in:
90
vendor/github.com/robfig/config/README.md
generated
vendored
Normal file
90
vendor/github.com/robfig/config/README.md
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
config
|
||||
======
|
||||
|
||||
This package implements a basic configuration file parser language which
|
||||
provides a structure similar to what you would find on Microsoft Windows INI
|
||||
files.
|
||||
|
||||
The configuration file consists of sections, led by a "*[section]*" header and
|
||||
followed by "*name: value*" entries; "*name=value*" is also accepted. Note that
|
||||
leading whitespace is removed from values. The optional values can contain
|
||||
format strings which refer to other values in the same section, or values in a
|
||||
special *DEFAULT* section. Additional defaults can be provided on initialization
|
||||
and retrieval. Comments are indicated by ";" or "#"; a comment may begin
|
||||
anywhere on a line, including on the same line after parameters or section
|
||||
declarations.
|
||||
|
||||
For example:
|
||||
|
||||
[My Section]
|
||||
foodir: %(dir)s/whatever
|
||||
dir=foo
|
||||
|
||||
would resolve the "*%(dir)s*" to the value of "*dir*" (*foo* in this case). All
|
||||
reference expansions are done on demand.
|
||||
|
||||
The functionality and workflow is loosely based on the *configparser* package of
|
||||
the Python Standard Library.
|
||||
|
||||
## Installation
|
||||
|
||||
go get github.com/robfig/config
|
||||
|
||||
## Operating instructions
|
||||
|
||||
Given a sample configuration file:
|
||||
|
||||
[DEFAULT]
|
||||
host: www.example.com
|
||||
protocol: http://
|
||||
base-url: %(protocol)s%(host)s
|
||||
|
||||
[service-1]
|
||||
url: %(base-url)s/some/path
|
||||
delegation: on
|
||||
maxclients: 200 # do not set this higher
|
||||
comments: This is a multi-line
|
||||
entry # And this is a comment
|
||||
|
||||
To read this configuration file, do:
|
||||
|
||||
c, _ := config.ReadDefault("config.cfg")
|
||||
|
||||
c.String("service-1", "url")
|
||||
// result is string "http://www.example.com/some/path"
|
||||
|
||||
c.Int("service-1", "maxclients")
|
||||
// result is int 200
|
||||
|
||||
c.Bool("service-1", "delegation")
|
||||
// result is bool true
|
||||
|
||||
c.String("service-1", "comments")
|
||||
// result is string "This is a multi-line\nentry"
|
||||
|
||||
Note the support for unfolding variables (such as *%(base-url)s*), which are read
|
||||
from the special (reserved) section name *[DEFAULT]*.
|
||||
|
||||
A new configuration file can also be created with:
|
||||
|
||||
c := config.NewDefault()
|
||||
c.AddSection("Section")
|
||||
c.AddOption("Section", "option", "value")
|
||||
c.WriteFile("config.cfg", 0644, "A header for this file")
|
||||
|
||||
This results in the file:
|
||||
|
||||
# A header for this file
|
||||
|
||||
[Section]
|
||||
option: value
|
||||
|
||||
Note that sections, options and values are all case-sensitive.
|
||||
|
||||
## License
|
||||
|
||||
The source files are distributed under the [Mozilla Public License, version 2.0](http://mozilla.org/MPL/2.0/),
|
||||
unless otherwise noted.
|
||||
Please read the [FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html)
|
||||
if you have further questions regarding the license.
|
||||
|
151
vendor/github.com/robfig/config/config.go
generated
vendored
Normal file
151
vendor/github.com/robfig/config/config.go
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// Default section name.
|
||||
DEFAULT_SECTION = "DEFAULT"
|
||||
// Maximum allowed depth when recursively substituing variable names.
|
||||
_DEPTH_VALUES = 200
|
||||
|
||||
DEFAULT_COMMENT = "# "
|
||||
ALTERNATIVE_COMMENT = "; "
|
||||
DEFAULT_SEPARATOR = ":"
|
||||
ALTERNATIVE_SEPARATOR = "="
|
||||
)
|
||||
|
||||
var (
|
||||
// Strings accepted as boolean.
|
||||
boolString = map[string]bool{
|
||||
"t": true,
|
||||
"true": true,
|
||||
"y": true,
|
||||
"yes": true,
|
||||
"on": true,
|
||||
"1": true,
|
||||
"f": false,
|
||||
"false": false,
|
||||
"n": false,
|
||||
"no": false,
|
||||
"off": false,
|
||||
"0": false,
|
||||
}
|
||||
|
||||
varRegExp = regexp.MustCompile(`%\(([a-zA-Z0-9_.\-]+)\)s`) // %(variable)s
|
||||
envVarRegExp = regexp.MustCompile(`\${([a-zA-Z0-9_.\-]+)}`) // ${envvar}
|
||||
)
|
||||
|
||||
// Config is the representation of configuration settings.
|
||||
type Config struct {
|
||||
comment string
|
||||
separator string
|
||||
|
||||
// Sections order
|
||||
lastIdSection int // Last section identifier
|
||||
idSection map[string]int // Section : position
|
||||
|
||||
// The last option identifier used for each section.
|
||||
lastIdOption map[string]int // Section : last identifier
|
||||
|
||||
// Section -> option : value
|
||||
data map[string]map[string]*tValue
|
||||
}
|
||||
|
||||
// tValue holds the input position for a value.
|
||||
type tValue struct {
|
||||
position int // Option order
|
||||
v string // value
|
||||
}
|
||||
|
||||
// New creates an empty configuration representation.
|
||||
// This representation can be filled with AddSection and AddOption and then
|
||||
// saved to a file using WriteFile.
|
||||
//
|
||||
// == Arguments
|
||||
//
|
||||
// comment: has to be `DEFAULT_COMMENT` or `ALTERNATIVE_COMMENT`
|
||||
// separator: has to be `DEFAULT_SEPARATOR` or `ALTERNATIVE_SEPARATOR`
|
||||
// preSpace: indicate if is inserted a space before of the separator
|
||||
// postSpace: indicate if is added a space after of the separator
|
||||
func New(comment, separator string, preSpace, postSpace bool) *Config {
|
||||
if comment != DEFAULT_COMMENT && comment != ALTERNATIVE_COMMENT {
|
||||
panic("comment character not valid")
|
||||
}
|
||||
|
||||
if separator != DEFAULT_SEPARATOR && separator != ALTERNATIVE_SEPARATOR {
|
||||
panic("separator character not valid")
|
||||
}
|
||||
|
||||
// == Get spaces around separator
|
||||
if preSpace {
|
||||
separator = " " + separator
|
||||
}
|
||||
|
||||
if postSpace {
|
||||
separator += " "
|
||||
}
|
||||
//==
|
||||
|
||||
c := new(Config)
|
||||
|
||||
c.comment = comment
|
||||
c.separator = separator
|
||||
c.idSection = make(map[string]int)
|
||||
c.lastIdOption = make(map[string]int)
|
||||
c.data = make(map[string]map[string]*tValue)
|
||||
|
||||
c.AddSection(DEFAULT_SECTION) // Default section always exists.
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// NewDefault creates a configuration representation with values by default.
|
||||
func NewDefault() *Config {
|
||||
return New(DEFAULT_COMMENT, DEFAULT_SEPARATOR, false, true)
|
||||
}
|
||||
|
||||
// Merge merges the given configuration "source" with this one ("target").
|
||||
//
|
||||
// Merging means that any option (under any section) from source that is not in
|
||||
// target will be copied into target. When the target already has an option with
|
||||
// the same name and section then it is overwritten (i.o.w. the source wins).
|
||||
func (target *Config) Merge(source *Config) {
|
||||
if source == nil || source.data == nil || len(source.data) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for section, option := range source.data {
|
||||
for optionName, optionValue := range option {
|
||||
target.AddOption(section, optionName, optionValue.v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// == Utility
|
||||
|
||||
func stripComments(l string) string {
|
||||
// Comments are preceded by space or TAB
|
||||
for _, c := range []string{" ;", "\t;", " #", "\t#"} {
|
||||
if i := strings.Index(l, c); i != -1 {
|
||||
l = l[0:i]
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
27
vendor/github.com/robfig/config/error.go
generated
vendored
Normal file
27
vendor/github.com/robfig/config/error.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
type SectionError string
|
||||
|
||||
func (e SectionError) Error() string {
|
||||
return "section not found: " + string(e)
|
||||
}
|
||||
|
||||
type OptionError string
|
||||
|
||||
func (e OptionError) Error() string {
|
||||
return "option not found: " + string(e)
|
||||
}
|
113
vendor/github.com/robfig/config/option.go
generated
vendored
Normal file
113
vendor/github.com/robfig/config/option.go
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import "errors"
|
||||
|
||||
// AddOption adds a new option and value to the configuration.
|
||||
//
|
||||
// If the section is nil then uses the section by default; if it does not exist,
|
||||
// it is created in advance.
|
||||
//
|
||||
// It returns true if the option and value were inserted, and false if the value
|
||||
// was overwritten.
|
||||
func (c *Config) AddOption(section string, option string, value string) bool {
|
||||
c.AddSection(section) // Make sure section exists
|
||||
|
||||
if section == "" {
|
||||
section = DEFAULT_SECTION
|
||||
}
|
||||
|
||||
_, ok := c.data[section][option]
|
||||
|
||||
c.data[section][option] = &tValue{c.lastIdOption[section], value}
|
||||
c.lastIdOption[section]++
|
||||
|
||||
return !ok
|
||||
}
|
||||
|
||||
// RemoveOption removes a option and value from the configuration.
|
||||
// It returns true if the option and value were removed, and false otherwise,
|
||||
// including if the section did not exist.
|
||||
func (c *Config) RemoveOption(section string, option string) bool {
|
||||
if _, ok := c.data[section]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
_, ok := c.data[section][option]
|
||||
delete(c.data[section], option)
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasOption checks if the configuration has the given option in the section.
|
||||
// It returns false if either the option or section do not exist.
|
||||
func (c *Config) HasOption(section string, option string) bool {
|
||||
if _, ok := c.data[section]; !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
_, okd := c.data[DEFAULT_SECTION][option]
|
||||
_, oknd := c.data[section][option]
|
||||
|
||||
return okd || oknd
|
||||
}
|
||||
|
||||
// Options returns the list of options available in the given section.
|
||||
// It returns an error if the section does not exist and an empty list if the
|
||||
// section is empty. Options within the default section are also included.
|
||||
func (c *Config) Options(section string) (options []string, err error) {
|
||||
if _, ok := c.data[section]; !ok {
|
||||
return nil, errors.New(SectionError(section).Error())
|
||||
}
|
||||
|
||||
// Keep a map of option names we've seen to deduplicate.
|
||||
optionMap := make(map[string]struct{},
|
||||
len(c.data[DEFAULT_SECTION])+len(c.data[section]))
|
||||
for s, _ := range c.data[DEFAULT_SECTION] {
|
||||
optionMap[s] = struct{}{}
|
||||
}
|
||||
for s, _ := range c.data[section] {
|
||||
optionMap[s] = struct{}{}
|
||||
}
|
||||
|
||||
// Get the keys.
|
||||
i := 0
|
||||
options = make([]string, len(optionMap))
|
||||
for k, _ := range optionMap {
|
||||
options[i] = k
|
||||
i++
|
||||
}
|
||||
|
||||
return options, nil
|
||||
}
|
||||
|
||||
// SectionOptions returns only the list of options available in the given section.
|
||||
// Unlike Options, SectionOptions doesn't return options in default section.
|
||||
// It returns an error if the section doesn't exist.
|
||||
func (c *Config) SectionOptions(section string) (options []string, err error) {
|
||||
if _, ok := c.data[section]; !ok {
|
||||
return nil, errors.New(SectionError(section).Error())
|
||||
}
|
||||
|
||||
options = make([]string, len(c.data[section]))
|
||||
i := 0
|
||||
for s, _ := range c.data[section] {
|
||||
options[i] = s
|
||||
i++
|
||||
}
|
||||
|
||||
return options, nil
|
||||
}
|
100
vendor/github.com/robfig/config/read.go
generated
vendored
Normal file
100
vendor/github.com/robfig/config/read.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// _read is the base to read a file and get the configuration representation.
|
||||
// That representation can be queried with GetString, etc.
|
||||
func _read(fname string, c *Config) (*Config, error) {
|
||||
file, err := os.Open(fname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = c.read(bufio.NewReader(file)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = file.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Read reads a configuration file and returns its representation.
|
||||
// All arguments, except `fname`, are related to `New()`
|
||||
func Read(fname string, comment, separator string, preSpace, postSpace bool) (*Config, error) {
|
||||
return _read(fname, New(comment, separator, preSpace, postSpace))
|
||||
}
|
||||
|
||||
// ReadDefault reads a configuration file and returns its representation.
|
||||
// It uses values by default.
|
||||
func ReadDefault(fname string) (*Config, error) {
|
||||
return _read(fname, NewDefault())
|
||||
}
|
||||
|
||||
// * * *
|
||||
|
||||
func (c *Config) read(buf *bufio.Reader) (err error) {
|
||||
var section, option string
|
||||
var scanner = bufio.NewScanner(buf)
|
||||
for scanner.Scan() {
|
||||
l := strings.TrimRightFunc(stripComments(scanner.Text()), unicode.IsSpace)
|
||||
|
||||
// Switch written for readability (not performance)
|
||||
switch {
|
||||
// Empty line and comments
|
||||
case len(l) == 0, l[0] == '#', l[0] == ';':
|
||||
continue
|
||||
|
||||
// New section. The [ must be at the start of the line
|
||||
case l[0] == '[' && l[len(l)-1] == ']':
|
||||
option = "" // reset multi-line value
|
||||
section = strings.TrimSpace(l[1 : len(l)-1])
|
||||
c.AddSection(section)
|
||||
|
||||
// Continuation of multi-line value
|
||||
// starts with whitespace, we're in a section and working on an option
|
||||
case section != "" && option != "" && (l[0] == ' ' || l[0] == '\t'):
|
||||
prev, _ := c.RawString(section, option)
|
||||
value := strings.TrimSpace(l)
|
||||
c.AddOption(section, option, prev+"\n"+value)
|
||||
|
||||
// Other alternatives
|
||||
default:
|
||||
i := strings.IndexAny(l, "=:")
|
||||
|
||||
switch {
|
||||
// Option and value
|
||||
case i > 0 && l[0] != ' ' && l[0] != '\t': // found an =: and it's not a multiline continuation
|
||||
option = strings.TrimSpace(l[0:i])
|
||||
value := strings.TrimSpace(l[i+1:])
|
||||
c.AddOption(section, option, value)
|
||||
|
||||
default:
|
||||
return errors.New("could not parse line: " + l)
|
||||
}
|
||||
}
|
||||
}
|
||||
return scanner.Err()
|
||||
}
|
88
vendor/github.com/robfig/config/section.go
generated
vendored
Normal file
88
vendor/github.com/robfig/config/section.go
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
// AddSection adds a new section to the configuration.
|
||||
//
|
||||
// If the section is nil then uses the section by default which it's already
|
||||
// created.
|
||||
//
|
||||
// It returns true if the new section was inserted, and false if the section
|
||||
// already existed.
|
||||
func (c *Config) AddSection(section string) bool {
|
||||
// DEFAULT_SECTION
|
||||
if section == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, ok := c.data[section]; ok {
|
||||
return false
|
||||
}
|
||||
|
||||
c.data[section] = make(map[string]*tValue)
|
||||
|
||||
// Section order
|
||||
c.idSection[section] = c.lastIdSection
|
||||
c.lastIdSection++
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// RemoveSection removes a section from the configuration.
|
||||
// It returns true if the section was removed, and false if section did not exist.
|
||||
func (c *Config) RemoveSection(section string) bool {
|
||||
_, ok := c.data[section]
|
||||
|
||||
// Default section cannot be removed.
|
||||
if !ok || section == DEFAULT_SECTION {
|
||||
return false
|
||||
}
|
||||
|
||||
for o, _ := range c.data[section] {
|
||||
delete(c.data[section], o) // *value
|
||||
}
|
||||
delete(c.data, section)
|
||||
|
||||
delete(c.lastIdOption, section)
|
||||
delete(c.idSection, section)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// HasSection checks if the configuration has the given section.
|
||||
// (The default section always exists.)
|
||||
func (c *Config) HasSection(section string) bool {
|
||||
_, ok := c.data[section]
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
// Sections returns the list of sections in the configuration.
|
||||
// (The default section always exists).
|
||||
func (c *Config) Sections() (sections []string) {
|
||||
sections = make([]string, len(c.idSection))
|
||||
pos := 0 // Position in sections
|
||||
|
||||
for i := 0; i < c.lastIdSection; i++ {
|
||||
for section, id := range c.idSection {
|
||||
if id == i {
|
||||
sections[pos] = section
|
||||
pos++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sections
|
||||
}
|
155
vendor/github.com/robfig/config/type.go
generated
vendored
Normal file
155
vendor/github.com/robfig/config/type.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Substitutes values, calculated by callback, on matching regex
|
||||
func (c *Config) computeVar(beforeValue *string, regx *regexp.Regexp, headsz, tailsz int, withVar func(*string) string) (*string, error) {
|
||||
var i int
|
||||
computedVal := beforeValue
|
||||
for i = 0; i < _DEPTH_VALUES; i++ { // keep a sane depth
|
||||
|
||||
vr := regx.FindStringSubmatchIndex(*computedVal)
|
||||
if len(vr) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
varname := (*computedVal)[vr[headsz]:vr[headsz+1]]
|
||||
varVal := withVar(&varname)
|
||||
if varVal == "" {
|
||||
return &varVal, errors.New(fmt.Sprintf("Option not found: %s", varname))
|
||||
}
|
||||
|
||||
// substitute by new value and take off leading '%(' and trailing ')s'
|
||||
// %(foo)s => headsz=2, tailsz=2
|
||||
// ${foo} => headsz=2, tailsz=1
|
||||
newVal := (*computedVal)[0:vr[headsz]-headsz] + varVal + (*computedVal)[vr[headsz+1]+tailsz:]
|
||||
computedVal = &newVal
|
||||
}
|
||||
|
||||
if i == _DEPTH_VALUES {
|
||||
retVal := ""
|
||||
return &retVal,
|
||||
fmt.Errorf("Possible cycle while unfolding variables: max depth of %d reached", _DEPTH_VALUES)
|
||||
}
|
||||
|
||||
return computedVal, nil
|
||||
}
|
||||
|
||||
// Bool has the same behaviour as String but converts the response to bool.
|
||||
// See "boolString" for string values converted to bool.
|
||||
func (c *Config) Bool(section string, option string) (value bool, err error) {
|
||||
sv, err := c.String(section, option)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
value, ok := boolString[strings.ToLower(sv)]
|
||||
if !ok {
|
||||
return false, errors.New("could not parse bool value: " + sv)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// Float has the same behaviour as String but converts the response to float.
|
||||
func (c *Config) Float(section string, option string) (value float64, err error) {
|
||||
sv, err := c.String(section, option)
|
||||
if err == nil {
|
||||
value, err = strconv.ParseFloat(sv, 64)
|
||||
}
|
||||
|
||||
return value, err
|
||||
}
|
||||
|
||||
// Int has the same behaviour as String but converts the response to int.
|
||||
func (c *Config) Int(section string, option string) (value int, err error) {
|
||||
sv, err := c.String(section, option)
|
||||
if err == nil {
|
||||
value, err = strconv.Atoi(sv)
|
||||
}
|
||||
|
||||
return value, err
|
||||
}
|
||||
|
||||
// RawString gets the (raw) string value for the given option in the section.
|
||||
// The raw string value is not subjected to unfolding, which was illustrated in
|
||||
// the beginning of this documentation.
|
||||
//
|
||||
// It returns an error if either the section or the option do not exist.
|
||||
func (c *Config) RawString(section string, option string) (value string, err error) {
|
||||
if _, ok := c.data[section]; ok {
|
||||
if tValue, ok := c.data[section][option]; ok {
|
||||
return tValue.v, nil
|
||||
}
|
||||
}
|
||||
return c.RawStringDefault(option)
|
||||
}
|
||||
|
||||
// RawStringDefault gets the (raw) string value for the given option from the
|
||||
// DEFAULT section.
|
||||
//
|
||||
// It returns an error if the option does not exist in the DEFAULT section.
|
||||
func (c *Config) RawStringDefault(option string) (value string, err error) {
|
||||
if tValue, ok := c.data[DEFAULT_SECTION][option]; ok {
|
||||
return tValue.v, nil
|
||||
}
|
||||
return "", OptionError(option)
|
||||
}
|
||||
|
||||
// String gets the string value for the given option in the section.
|
||||
// If the value needs to be unfolded (see e.g. %(host)s example in the beginning
|
||||
// of this documentation), then String does this unfolding automatically, up to
|
||||
// _DEPTH_VALUES number of iterations.
|
||||
//
|
||||
// It returns an error if either the section or the option do not exist, or the
|
||||
// unfolding cycled.
|
||||
func (c *Config) String(section string, option string) (value string, err error) {
|
||||
value, err = c.RawString(section, option)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// % variables
|
||||
computedVal, err := c.computeVar(&value, varRegExp, 2, 2, func(varName *string) string {
|
||||
lowerVar := *varName
|
||||
// search variable in default section as well as current section
|
||||
varVal, _ := c.data[DEFAULT_SECTION][lowerVar]
|
||||
if _, ok := c.data[section][lowerVar]; ok {
|
||||
varVal = c.data[section][lowerVar]
|
||||
}
|
||||
return varVal.v
|
||||
})
|
||||
value = *computedVal
|
||||
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
|
||||
// $ environment variables
|
||||
computedVal, err = c.computeVar(&value, envVarRegExp, 2, 1, func(varName *string) string {
|
||||
return os.Getenv(*varName)
|
||||
})
|
||||
value = *computedVal
|
||||
return value, err
|
||||
}
|
90
vendor/github.com/robfig/config/write.go
generated
vendored
Normal file
90
vendor/github.com/robfig/config/write.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2009 The "config" Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// WriteFile saves the configuration representation to a file.
|
||||
// The desired file permissions must be passed as in os.Open. The header is a
|
||||
// string that is saved as a comment in the first line of the file.
|
||||
func (c *Config) WriteFile(fname string, perm os.FileMode, header string) error {
|
||||
file, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := bufio.NewWriter(file)
|
||||
if err = c.write(buf, header); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.Flush()
|
||||
|
||||
return file.Close()
|
||||
}
|
||||
|
||||
func (c *Config) write(buf *bufio.Writer, header string) (err error) {
|
||||
if header != "" {
|
||||
// Add comment character after of each new line.
|
||||
if i := strings.Index(header, "\n"); i != -1 {
|
||||
header = strings.Replace(header, "\n", "\n"+c.comment, -1)
|
||||
}
|
||||
|
||||
if _, err = buf.WriteString(c.comment + header + "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, orderedSection := range c.Sections() {
|
||||
for section, sectionMap := range c.data {
|
||||
if section == orderedSection {
|
||||
|
||||
// Skip default section if empty.
|
||||
if section == DEFAULT_SECTION && len(sectionMap) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err = buf.WriteString("\n[" + section + "]\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Follow the input order in options.
|
||||
for i := 0; i < c.lastIdOption[section]; i++ {
|
||||
for option, tValue := range sectionMap {
|
||||
|
||||
if tValue.position == i {
|
||||
if _, err = buf.WriteString(fmt.Sprint(
|
||||
option, c.separator, tValue.v, "\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
c.RemoveOption(section, option)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = buf.WriteString("\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user