Skip to content

Commit ea89afd

Browse files
author
Juan Jose Medina
authored
Merge pull request #9 from bitnami/ignore-inline-comments
Support ignoring inline comments in values
2 parents c8f06c4 + e6319c6 commit ea89afd

File tree

3 files changed

+148
-23
lines changed

3 files changed

+148
-23
lines changed

cmd_test.go

Lines changed: 130 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ import (
1212
)
1313

1414
type iniTestValue struct {
15-
section string
16-
key string
17-
value string
18-
isBoolean bool
15+
globalOpts *Options
16+
section string
17+
key string
18+
value string
19+
isBoolean bool
1920
}
2021
type iniSetTest struct {
2122
name string
@@ -68,6 +69,46 @@ var delTests = []iniDelTest{
6869
},
6970
expectedText: `\[general\]\nkey1=val1\n\s*$`,
7071
},
72+
{
73+
name: "Deletes key in file containing semicolon values in regular mode",
74+
values: []iniTestValue{
75+
{
76+
section: "general", key: "key2",
77+
},
78+
},
79+
initialText: "[general]\nkey1=`my ; value`\nkey2=val2",
80+
expectedText: "\\[general\\]\nkey1=`my ; value`\n\\s*$",
81+
},
82+
{
83+
name: "Deletes key in file containing semicolon values in regular mode (2)",
84+
values: []iniTestValue{
85+
{
86+
section: "general", key: "key2",
87+
},
88+
},
89+
initialText: "[general]\nkey1=my ; my comment\nkey2=val2",
90+
expectedText: "\\[general\\]\n; my comment\nkey1=my\n\\s*$",
91+
},
92+
{
93+
name: "Deletes key in file containing semicolon values in ignore-inline-comments mode",
94+
values: []iniTestValue{
95+
{
96+
section: "general", key: "key2", globalOpts: &Options{IgnoreInlineComments: true},
97+
},
98+
},
99+
initialText: "[general]\nkey1=`my ; value`\nkey2=val2",
100+
expectedText: "\\[general\\]\nkey1=my ; value\n\\s*$",
101+
},
102+
{
103+
name: "Deletes key in file containing semicolon values in ignore-inline-comments mode (2)",
104+
values: []iniTestValue{
105+
{
106+
section: "general", key: "key2", globalOpts: &Options{IgnoreInlineComments: true},
107+
},
108+
},
109+
initialText: "[general]\nkey1=my ; my comment\nkey2=val2",
110+
expectedText: "\\[general\\]\nkey1=my ; my comment\n\\s*$",
111+
},
71112
{
72113
name: "Deletes regular value",
73114
initialText: "[general]\nkey1=val1\nkey2=val2\n",
@@ -108,6 +149,36 @@ var getTests = []iniGetTest{
108149
section: "general", key: "mykey", value: "myvalue",
109150
},
110151
},
152+
{
153+
name: "Get value with semicolon in regular mode",
154+
initialText: "[general]\nmykey=`my ; value`\n",
155+
iniTestValue: iniTestValue{
156+
section: "general", key: "mykey", value: "my ; value",
157+
},
158+
},
159+
{
160+
name: "Get value with semicolon in regular mode (2)",
161+
initialText: "[general]\nmykey=my ; this is a comment\n",
162+
iniTestValue: iniTestValue{
163+
section: "general", key: "mykey", value: "my",
164+
},
165+
},
166+
{
167+
name: "Get value with semicolon in ignore-inline-comments mode",
168+
initialText: "[general]\nmykey=`my ; value`\n",
169+
iniTestValue: iniTestValue{
170+
globalOpts: &Options{IgnoreInlineComments: true},
171+
section: "general", key: "mykey", value: "my ; value",
172+
},
173+
},
174+
{
175+
name: "Get value with semicolon in ignore-inline-comments mode (2)",
176+
initialText: "[general]\nmykey=my ; this is a comment\n",
177+
iniTestValue: iniTestValue{
178+
globalOpts: &Options{IgnoreInlineComments: true},
179+
section: "general", key: "mykey", value: "my ; this is a comment",
180+
},
181+
},
111182
{
112183
name: "Get present boolean key",
113184
initialText: "[general]\nmykey\n",
@@ -139,6 +210,25 @@ var setTests = []iniSetTest{
139210
},
140211
expectedText: `mykey=myvalue\n`,
141212
},
213+
{
214+
name: "Sets value with semicolon in regular mode",
215+
values: []iniTestValue{
216+
{
217+
section: "general", key: "mykey", value: "my ; value",
218+
},
219+
},
220+
expectedText: "mykey=`my ; value`\n",
221+
},
222+
{
223+
name: "Sets value with semicolon in ignore-inline-comments mode",
224+
values: []iniTestValue{
225+
{
226+
globalOpts: &Options{IgnoreInlineComments: true},
227+
section: "general", key: "mykey", value: "my ; value",
228+
},
229+
},
230+
expectedText: "mykey=my ; value\n",
231+
},
142232
{
143233
name: "Sets boolean value",
144234
values: []iniTestValue{
@@ -226,22 +316,30 @@ func AssertFileDoesNotContain(t *testing.T, path string, expected interface{}, m
226316
})
227317
}
228318
func TestINIFileSetCmd_Execute(t *testing.T) {
229-
type testFn func(file, section, key, value string, isBoolean bool) error
230-
var testViaCommand = func(file, section, key, value string, isBoolean bool) error {
319+
type testFn func(file, section, key, value string, isBoolean bool, opts *Options) error
320+
var testViaCommand = func(file, section, key, value string, isBoolean bool, opts *Options) error {
231321
cmd := NewINIFileSetCmd()
232322
cmd.Section = section
233323
cmd.Key = key
234324
cmd.Value = value
235325
cmd.Boolean = isBoolean
236326
cmd.Args.File = file
327+
if opts != nil {
328+
globalOpts = opts
329+
} else {
330+
globalOpts = &Options{}
331+
}
237332
return cmd.Execute([]string{})
238333
}
239-
var testViaCli = func(file, section, key, value string, isBoolean bool) error {
334+
var testViaCli = func(file, section, key, value string, isBoolean bool, opts *Options) error {
240335
args := []string{"set", "-k", key, "-s", section, "-v", value}
241336
if isBoolean {
242337
args = append(args, "-b")
243338
}
244339
args = append(args, file)
340+
if opts != nil && opts.IgnoreInlineComments {
341+
args = append([]string{"--ignore-inline-comments"}, args...)
342+
}
245343
res := RunTool(args...)
246344
if !res.Success() {
247345
return fmt.Errorf("%s", res.Stderr())
@@ -268,7 +366,7 @@ func TestINIFileSetCmd_Execute(t *testing.T) {
268366
testTitle := fmt.Sprintf("%s (via %s)", tt.name, id)
269367
t.Run(testTitle, func(t *testing.T) {
270368
for _, v := range tt.values {
271-
err = fn(file, v.section, v.key, v.value, v.isBoolean)
369+
err = fn(file, v.section, v.key, v.value, v.isBoolean, v.globalOpts)
272370
if err != nil {
273371
break
274372
}
@@ -289,21 +387,28 @@ func TestINIFileSetCmd_Execute(t *testing.T) {
289387
}
290388

291389
func TestINIFileGetCmd_Execute(t *testing.T) {
292-
type testFn func(file, section, key string) (string, error)
293-
var testViaCommand = func(file, section, key string) (string, error) {
390+
type testFn func(file, section, key string, opts *Options) (string, error)
391+
var testViaCommand = func(file, section, key string, opts *Options) (string, error) {
294392
b := &bytes.Buffer{}
295393
cmd := NewINIFileGetCmd()
296394
cmd.Section = section
297395
cmd.Key = key
298396
cmd.Args.File = file
299397
cmd.OutWriter = b
300-
398+
if opts != nil {
399+
globalOpts = opts
400+
} else {
401+
globalOpts = &Options{}
402+
}
301403
err := cmd.Execute([]string{})
302404
stdout := b.String()
303405
return stdout, err
304406
}
305-
var testViaCli = func(file, section, key string) (string, error) {
407+
var testViaCli = func(file, section, key string, opts *Options) (string, error) {
306408
args := []string{"get", "-k", key, "-s", section, file}
409+
if opts != nil && opts.IgnoreInlineComments {
410+
args = append([]string{"--ignore-inline-comments"}, args...)
411+
}
307412
res := RunTool(args...)
308413
stdout := res.Stdout()
309414
var err error
@@ -332,7 +437,7 @@ func TestINIFileGetCmd_Execute(t *testing.T) {
332437

333438
t.Run(testTitle, func(t *testing.T) {
334439

335-
stdout, err := fn(file, tt.section, tt.key)
440+
stdout, err := fn(file, tt.section, tt.key, tt.globalOpts)
336441

337442
if tt.expectedErr != nil {
338443
if err == nil {
@@ -350,16 +455,24 @@ func TestINIFileGetCmd_Execute(t *testing.T) {
350455
}
351456

352457
func TestINIFileDelCmd_Execute(t *testing.T) {
353-
type testFn func(file, section, key string) error
354-
var testViaCommand = func(file, section, key string) error {
458+
type testFn func(file, section, key string, opts *Options) error
459+
var testViaCommand = func(file, section, key string, opts *Options) error {
355460
cmd := NewINIFileDelCmd()
356461
cmd.Section = section
357462
cmd.Key = key
358463
cmd.Args.File = file
464+
if opts != nil {
465+
globalOpts = opts
466+
} else {
467+
globalOpts = &Options{}
468+
}
359469
return cmd.Execute([]string{})
360470
}
361-
var testViaCli = func(file, section, key string) error {
471+
var testViaCli = func(file, section, key string, opts *Options) error {
362472
args := []string{"del", "-k", key, "-s", section, file}
473+
if opts != nil && opts.IgnoreInlineComments {
474+
args = append([]string{"--ignore-inline-comments"}, args...)
475+
}
363476
res := RunTool(args...)
364477
if !res.Success() {
365478
return fmt.Errorf("%s", res.Stderr())
@@ -386,7 +499,7 @@ func TestINIFileDelCmd_Execute(t *testing.T) {
386499
t.Run(testTitle, func(t *testing.T) {
387500
for _, v := range tt.values {
388501

389-
err = fn(file, v.section, v.key)
502+
err = fn(file, v.section, v.key, v.globalOpts)
390503
if err != nil {
391504
break
392505
}

ini.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ func init() {
1212
ini.PrettyFormat = false
1313
}
1414

15+
func loadOptions() ini.LoadOptions {
16+
return ini.LoadOptions{
17+
// Support mysql-style "boolean" values - a key wth no value.
18+
AllowBooleanKeys: true,
19+
IgnoreInlineComment: globalOpts.IgnoreInlineComments,
20+
}
21+
}
22+
1523
// iniLoad attempts to load the ini file.
1624
func iniLoad(filename string) (*ini.File, error) {
1725
return ini.LoadSources(
18-
ini.LoadOptions{
19-
// Support mysql-style "boolean" values - a key wth no value.
20-
AllowBooleanKeys: true,
21-
},
26+
loadOptions(),
2227
filename,
2328
)
2429
}
@@ -31,7 +36,7 @@ func iniLoadOrEmpty(filename string) (*ini.File, error) {
3136
return f, nil
3237
}
3338
if os.IsNotExist(err) {
34-
return ini.Empty(), nil
39+
return ini.Empty(loadOptions()), nil
3540
}
3641
return nil, err
3742
}

main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@ import (
77
flags "github.com/jessevdk/go-flags"
88
)
99

10+
// Options defines options supported by all subcommands
11+
type Options struct {
12+
IgnoreInlineComments bool `long:"ignore-inline-comments" description:"Ignore inline comments"`
13+
}
14+
15+
var globalOpts = &Options{}
16+
1017
func main() {
1118
setCmd := NewINIFileSetCmd()
1219
getCmd := NewINIFileGetCmd()
1320
delCmd := NewINIFileDelCmd()
1421

15-
parser := flags.NewParser(nil, flags.HelpFlag|flags.PassDoubleDash)
22+
parser := flags.NewParser(globalOpts, flags.HelpFlag|flags.PassDoubleDash)
1623

1724
parser.AddCommand("set", "INI File Set", "Sets values in a INI file", setCmd)
1825
parser.AddCommand("get", "INI FILE Get", "Gets values from a INI file", getCmd)

0 commit comments

Comments
 (0)