Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lint #14

Closed
wants to merge 1 commit into from
Closed

Lint #14

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 19 additions & 18 deletions all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,23 @@ const (

func testGet(t *testing.T, c *Config, section string, option string,
expected interface{}) {
t.Helper()

ok := false
switch expected.(type) {
switch v := expected.(type) {
case string:
v, _ := c.String(section, option)
if v == expected.(string) {
s, _ := c.String(section, option)
if s == v {
ok = true
}
case int:
v, _ := c.Int(section, option)
if v == expected.(int) {
i, _ := c.Int(section, option)
if i == v {
ok = true
}
case bool:
v, _ := c.Bool(section, option)
if v == expected.(bool) {
b, _ := c.Bool(section, option)
if b == v {
ok = true
}
default:
Expand Down Expand Up @@ -313,7 +315,6 @@ func TestSectionOptions(t *testing.T) {
}

options, err := cr.SectionOptions("First-Section")

if err != nil {
t.Fatalf("SectionOptions failure: %s", err)
}
Expand Down Expand Up @@ -362,13 +363,13 @@ func TestSectionOptions(t *testing.T) {

// TestMerge tests merging 2 configurations.
func TestMerge(t *testing.T) {
target, error := ReadDefault(targetFilename)
if error != nil {
target, err := ReadDefault(targetFilename)
if err != nil {
t.Fatalf("Unable to read target config file '%s'", targetFilename)
}

source, error := ReadDefault(sourceFilename)
if error != nil {
source, err := ReadDefault(sourceFilename)
if err != nil {
t.Fatalf("Unable to read source config file '%s'", sourceFilename)
}

Expand Down Expand Up @@ -407,18 +408,18 @@ func TestLoadContextOneConf(t *testing.T) {
}

ctx.SetSection("X")
result, found := ctx.String("x.three")
result, _ := ctx.String("x.three")
if !strings.EqualFold("conf1-sourcex3", result) {
t.Errorf("Expected '[X] x.three' to be 'conf1-sourcex3' but instead it was '%s'", result)
}

_, found = ctx.String("x.notexists")
_, found := ctx.String("x.notexists")
if found {
t.Error("Config 'x.notexists' shouldn't found")
}

ctx.SetSection("Y")
result, found = ctx.String("y.one")
result, _ = ctx.String("y.one")
if !strings.EqualFold("conf1-sourcey1", result) {
t.Errorf("Expected '[Y] y.one' to be 'conf1-sourcey1' but instead it was '%s'", result)
}
Expand All @@ -437,18 +438,18 @@ func TestLoadContextMultipleConfWithPriority(t *testing.T) {
}

ctx.SetSection("X")
result, found := ctx.String("x.two")
result, _ := ctx.String("x.two")
if !strings.EqualFold("override-conf2-sourcex2", result) {
t.Errorf("Expected '[X] x.two' to be 'override-conf2-sourcex2' but instead it was '%s'", result)
}

_, found = ctx.String("x.notexists")
_, found := ctx.String("x.notexists")
if found {
t.Error("Config 'x.notexists' shouldn't be found")
}

ctx.SetSection("Y")
result, found = ctx.String("y.three")
result, _ = ctx.String("y.three")
if !strings.EqualFold("override-conf2-sourcey3", result) {
t.Errorf("Expected '[Y] y.three' to be 'override-conf2-sourcey3' but instead it was '%s'", result)
}
Expand Down
18 changes: 9 additions & 9 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"strings"
)

// config constants
// config constants.
const (
// Default section name.
DefaultSection = "DEFAULT"
Expand All @@ -34,7 +34,7 @@ const (

var (
// Strings accepted as boolean.
boolString = map[string]bool{
boolString = map[string]bool{ //nolint:gochecknoglobals
"t": true,
"true": true,
"y": true,
Expand Down Expand Up @@ -84,7 +84,7 @@ type tValue struct {
// comment: has to be `DefaultComment` or `AlternativeComment`
// separator: has to be `DefaultSeparator` or `AlternativeSeparator`
// preSpace: indicate if is inserted a space before of the separator
// postSpace: indicate if is added a space after 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 != DefaultComment && comment != AlternativeComment {
panic("comment character not valid")
Expand All @@ -102,7 +102,7 @@ func New(comment, separator string, preSpace, postSpace bool) *Config {
if postSpace {
separator += " "
}
//==
// ==

c := new(Config)

Expand All @@ -122,19 +122,19 @@ func NewDefault() *Config {
return New(DefaultComment, DefaultSeparator, false, true)
}

// Merge merges the given configuration "source" with this one ("target").
// Merge merges the given configuration "source" with this one ("c").
//
// 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) {
// c will be copied into c. When c already has an option with the same name and
// section then it is overwritten (i.o.w. the source wins).
func (c *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)
c.AddOption(section, optionName, optionValue.v)
}
}
}
Expand Down
37 changes: 22 additions & 15 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package config

import (
"errors"
"fmt"
"os"
"path/filepath"
Expand All @@ -30,21 +31,23 @@ type Context struct {
section string // Check this section first, then fall back to DEFAULT
}

// NewContext creates a default section and returns config context
// NewContext creates a default section and returns config context.
func NewContext() *Context {
return &Context{config: NewDefault()}
}

// LoadContext loads the ini config from gives multiple conf paths
// LoadContext loads the ini config from gives multiple conf paths.
func LoadContext(confName string, confPaths []string) (*Context, error) {
ctx := NewContext()
for _, confPath := range confPaths {
path := filepath.Join(confPath, confName)
conf, err := ReadDefault(path)
if err != nil {
if _, isPathErr := err.(*os.PathError); !isPathErr {
return nil, fmt.Errorf("%v: %v", path, err)
perr := &os.PathError{}
if !errors.As(err, &perr) {
return nil, fmt.Errorf("%v: %w", path, err)
}

continue
}
ctx.config.Merge(conf)
Expand All @@ -53,30 +56,32 @@ func LoadContext(confName string, confPaths []string) (*Context, error) {
return ctx, nil
}

// Raw returns raw config instance
// Raw returns raw config instance.
func (c *Context) Raw() *Config {
return c.config
}

// SetSection the section scope of ini config
// For e.g.: dev or prod
// For e.g.: dev or prod.
func (c *Context) SetSection(section string) {
c.section = section
}

// SetOption sets the value for the given key
// SetOption sets the value for the given key.
func (c *Context) SetOption(name, value string) {
c.config.AddOption(c.section, name, value)
}

// Int returns `int` config value and if found returns true
// otherwise false
// otherwise false.
func (c *Context) Int(option string) (result int, found bool) {
result, err := c.config.Int(c.section, option)
if err == nil {
return result, true
}
if _, ok := err.(OptionError); ok {

oerr := OptionError("")
if errors.As(err, &oerr) {
return 0, false
}

Expand All @@ -85,7 +90,7 @@ func (c *Context) Int(option string) (result int, found bool) {
}

// IntDefault returns `int` config value if found otherwise
// returns given default int value
// returns given default int value.
func (c *Context) IntDefault(option string, dfault int) int {
if r, found := c.Int(option); found {
return r
Expand All @@ -94,13 +99,15 @@ func (c *Context) IntDefault(option string, dfault int) int {
}

// Bool returns `bool` config value and if found returns true
// otherwise false
// otherwise false.
func (c *Context) Bool(option string) (result, found bool) {
result, err := c.config.Bool(c.section, option)
if err == nil {
return result, true
}
if _, ok := err.(OptionError); ok {

oerr := OptionError("")
if errors.As(err, &oerr) {
return false, false
}

Expand All @@ -109,7 +116,7 @@ func (c *Context) Bool(option string) (result, found bool) {
}

// BoolDefault returns `bool` config value if found otherwise
// returns given default bool value
// returns given default bool value.
func (c *Context) BoolDefault(option string, dfault bool) bool {
if r, found := c.Bool(option); found {
return r
Expand All @@ -118,7 +125,7 @@ func (c *Context) BoolDefault(option string, dfault bool) bool {
}

// String returns `string` config value and if found returns true
// otherwise false
// otherwise false.
func (c *Context) String(option string) (result string, found bool) {
if r, err := c.config.String(c.section, option); err == nil {
return stripQuotes(r), true
Expand All @@ -127,7 +134,7 @@ func (c *Context) String(option string) (result string, found bool) {
}

// StringDefault returns `string` config value if found otherwise
// returns given default string value
// returns given default string value.
func (c *Context) StringDefault(option, dfault string) string {
if r, found := c.String(option); found {
return r
Expand Down
20 changes: 18 additions & 2 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,32 @@

package config

// SectionError type string
// Error is used for constant errors.
type Error string

// Error implements the error interface.
func (e Error) Error() string {
return string(e)
}

const (
ErrCycle Error = "possible cycle while unfolding variables"
ErrParseBool Error = "could not parse bool value"
ErrParseLine Error = "could not parse line"
)

// SectionError type string.
type SectionError string

// Error implements the error interface.
func (e SectionError) Error() string {
return "section not found: " + string(e)
}

// OptionError type string
// OptionError type string.
type OptionError string

// Error implements the error interface.
func (e OptionError) Error() string {
return "option not found: " + string(e)
}
12 changes: 5 additions & 7 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

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,
Expand Down Expand Up @@ -71,17 +69,17 @@ func (c *Config) HasOption(section string, option string) bool {
func (c *Config) Options(section string) (options []string, err error) {
// If no section passed in then assume we are only looking at the default section
var optionMap map[string]struct{}
onlyDefault := section=="" || section== DefaultSection
onlyDefault := section == "" || section == DefaultSection

if onlyDefault {
if onlyDefault {
optionMap = make(map[string]struct{},
len(c.data[DefaultSection])+len(c.data[section]))
} else if _, ok := c.data[section]; !ok {
return nil, errors.New(SectionError(section).Error())
return nil, SectionError(section)
} else {
// Keep a map of option names we've seen to deduplicate.
optionMap = make(map[string]struct{},
len(c.data[DefaultSection]) + len(c.data[section]))
len(c.data[DefaultSection])+len(c.data[section]))
}

for s := range c.data[DefaultSection] {
Expand Down Expand Up @@ -109,7 +107,7 @@ func (c *Config) Options(section string) (options []string, err error) {
// 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())
return nil, SectionError(section)
}

options = make([]string, len(c.data[section]))
Expand Down
6 changes: 3 additions & 3 deletions read.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func _read(fname string, c *Config) (*Config, error) {
}

// Read reads a configuration file and returns its representation.
// All arguments, except `fname`, are related to `New()`
// 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))
}
Expand All @@ -57,7 +57,7 @@ func ReadDefault(fname string) (*Config, error) {

func (c *Config) read(buf *bufio.Reader) (err error) {
var section, option string
var scanner = bufio.NewScanner(buf)
scanner := bufio.NewScanner(buf)
lineNo := 0
for scanner.Scan() {
l := strings.TrimRightFunc(stripComments(scanner.Text()), unicode.IsSpace)
Expand Down Expand Up @@ -94,7 +94,7 @@ func (c *Config) read(buf *bufio.Reader) (err error) {
c.AddOption(section, option, value)

default:
return fmt.Errorf("could not parse line #%v: %v", lineNo, l)
return fmt.Errorf("%w %d: %v", ErrParseLine, lineNo, l)
}
}
}
Expand Down