Clear reference values (maps and slices) when first set
Fixes #323.
diff --git a/ini.go b/ini.go
index 2223d7b..60b36c7 100644
--- a/ini.go
+++ b/ini.go
@@ -499,6 +499,10 @@
func (i *IniParser) parse(ini *ini) error {
p := i.parser
+ p.eachOption(func(cmd *Command, group *Group, option *Option) {
+ option.clearReferenceBeforeSet = true
+ })
+
var quotesLookup = make(map[*Option]bool)
for name, section := range ini.Sections {
diff --git a/ini_test.go b/ini_test.go
index 72bc386..72c890c 100644
--- a/ini_test.go
+++ b/ini_test.go
@@ -971,6 +971,30 @@
assertString(t, opts.Required, "cli-value")
}
+func TestIniRequiredSlice_ShouldNotNeedToBeSpecifiedOnCli(t *testing.T) {
+ type options struct {
+ Items []string `long:"item" required:"true"`
+ }
+ var opts options
+ ini := `
+[Application Options]
+item=abc`
+ args := []string{}
+
+ parser := NewParser(&opts, Default)
+ inip := NewIniParser(parser)
+
+ inip.Parse(strings.NewReader(ini))
+
+ _, err := parser.ParseArgs(args)
+
+ if err != nil {
+ t.Fatalf("Unexpected failure: %v", err)
+ }
+
+ assertString(t, opts.Items[0], "abc")
+}
+
func TestWriteFile(t *testing.T) {
file, err := ioutil.TempFile("", "")
if err != nil {
diff --git a/option.go b/option.go
index cc441f8..f6d6941 100644
--- a/option.go
+++ b/option.go
@@ -80,10 +80,11 @@
// Determines if the option will be always quoted in the INI output
iniQuote bool
- tag multiTag
- isSet bool
- isSetDefault bool
- preventDefault bool
+ tag multiTag
+ isSet bool
+ isSetDefault bool
+ preventDefault bool
+ clearReferenceBeforeSet bool
defaultLiteral string
}
@@ -241,12 +242,13 @@
func (option *Option) set(value *string) error {
kind := option.value.Type().Kind()
- if (kind == reflect.Map || kind == reflect.Slice) && !option.isSet {
+ if (kind == reflect.Map || kind == reflect.Slice) && option.clearReferenceBeforeSet {
option.empty()
}
option.isSet = true
option.preventDefault = true
+ option.clearReferenceBeforeSet = false
if len(option.Choices) != 0 {
found := false
@@ -281,6 +283,10 @@
}
func (option *Option) setDefault(value *string) error {
+ if option.preventDefault {
+ return nil
+ }
+
if err := option.set(value); err != nil {
return err
}
diff --git a/parser.go b/parser.go
index 1ebce81..3fc3f7b 100644
--- a/parser.go
+++ b/parser.go
@@ -208,8 +208,7 @@
}
p.eachOption(func(c *Command, g *Group, option *Option) {
- option.isSet = false
- option.isSetDefault = false
+ option.clearReferenceBeforeSet = true
option.updateDefaultLiteral()
})
@@ -713,13 +712,3 @@
return err
}
-
-func (p *Parser) clearIsSet() {
- p.eachCommand(func(c *Command) {
- c.eachGroup(func(g *Group) {
- for _, option := range g.options {
- option.isSet = false
- }
- })
- }, true)
-}