Skip to content

Commit

Permalink
Clear reference values (maps and slices) when first set
Browse files Browse the repository at this point in the history
Fixes #323.
  • Loading branch information
jessevdk committed Mar 21, 2021
1 parent 77d7cb9 commit 1878de2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 17 deletions.
4 changes: 4 additions & 0 deletions ini.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@ func (i *IniParser) matchingGroups(name string) []*Group {
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 {
Expand Down
24 changes: 24 additions & 0 deletions ini_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,30 @@ func TestIniRequired(t *testing.T) {
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 {
Expand Down
16 changes: 11 additions & 5 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ type Option struct {
// 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
}
Expand Down Expand Up @@ -241,12 +242,13 @@ func (option *Option) IsSetDefault() bool {
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
Expand Down Expand Up @@ -281,6 +283,10 @@ func (option *Option) set(value *string) error {
}

func (option *Option) setDefault(value *string) error {
if option.preventDefault {
return nil
}

if err := option.set(value); err != nil {
return err
}
Expand Down
13 changes: 1 addition & 12 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ func (p *Parser) ParseArgs(args []string) ([]string, error) {
}

p.eachOption(func(c *Command, g *Group, option *Option) {
option.isSet = false
option.isSetDefault = false
option.clearReferenceBeforeSet = true
option.updateDefaultLiteral()
})

Expand Down Expand Up @@ -713,13 +712,3 @@ func (p *Parser) printError(err error) error {

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)
}

0 comments on commit 1878de2

Please sign in to comment.