fix(parser): add support for multiple overlapping global options
This commit is contained in:
2 files changed
+235
-30
No files matched your search
+21
-30
@@ -52,13 +52,13 @@ func MakeArguments() *Arguments {
|
||||
}
|
||||
}
|
||||
|
||||
func (parser *Arguments) CopyGlobal() (cp *Arguments) {
|
||||
cp = MakeArguments()
|
||||
func (parser *Arguments) CopyGlobal() *Arguments {
|
||||
cp := MakeArguments()
|
||||
for k, v := range parser.Globals {
|
||||
cp.Globals[k] = v
|
||||
}
|
||||
|
||||
return
|
||||
return cp
|
||||
}
|
||||
|
||||
func (parser *Arguments) Copy() (cp *Arguments) {
|
||||
@@ -143,51 +143,46 @@ func (parser *Arguments) NeedRoot(runtime *Runtime) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (parser *Arguments) addOP(op string) (err error) {
|
||||
func (parser *Arguments) addOP(op string) error {
|
||||
if parser.Op != "" {
|
||||
err = errors.New(gotext.Get("only one operation may be used at a time"))
|
||||
return
|
||||
return errors.New(gotext.Get("only one operation may be used at a time"))
|
||||
}
|
||||
|
||||
parser.Op = op
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (parser *Arguments) addParam(option, arg string) (err error) {
|
||||
func (parser *Arguments) addParam(option, arg string) error {
|
||||
if !isArg(option) {
|
||||
return errors.New(gotext.Get("invalid option '%s'", option))
|
||||
}
|
||||
|
||||
if isOp(option) {
|
||||
err = parser.addOP(option)
|
||||
return
|
||||
return parser.addOP(option)
|
||||
}
|
||||
|
||||
switch {
|
||||
case isGlobal(option):
|
||||
if isGlobal(option) {
|
||||
if parser.Globals[option] == nil {
|
||||
parser.Globals[option] = &Option{}
|
||||
}
|
||||
parser.Globals[option].Add(arg)
|
||||
default:
|
||||
} else {
|
||||
if parser.Options[option] == nil {
|
||||
parser.Options[option] = &Option{}
|
||||
}
|
||||
parser.Options[option].Add(arg)
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (parser *Arguments) AddArg(options ...string) (err error) {
|
||||
func (parser *Arguments) AddArg(options ...string) error {
|
||||
for _, option := range options {
|
||||
err = parser.addParam(option, "")
|
||||
err := parser.addParam(option, "")
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Multiple args acts as an OR operator
|
||||
@@ -210,14 +205,12 @@ func (parser *Arguments) GetArg(options ...string) (arg string, double, exists b
|
||||
for _, option := range options {
|
||||
value, exists := parser.Options[option]
|
||||
if exists {
|
||||
arg = value.First()
|
||||
return arg, len(value.Args) >= 2, len(value.Args) >= 1
|
||||
return value.First(), len(value.Args) >= 2, len(value.Args) >= 1
|
||||
}
|
||||
|
||||
value, exists = parser.Globals[option]
|
||||
if exists {
|
||||
arg = value.First()
|
||||
return arg, len(value.Args) >= 2, len(value.Args) >= 1
|
||||
return value.First(), len(value.Args) >= 2, len(value.Args) >= 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,14 +272,12 @@ func (parser *Arguments) FormatArgs() (args []string) {
|
||||
func (parser *Arguments) FormatGlobals() (args []string) {
|
||||
for option, arg := range parser.Globals {
|
||||
formattedOption := formatArg(option)
|
||||
args = append(args, formattedOption)
|
||||
|
||||
if hasParam(option) {
|
||||
args = append(args, arg.First())
|
||||
}
|
||||
|
||||
if parser.ExistsDouble(option) {
|
||||
for _, value := range arg.Args {
|
||||
args = append(args, formattedOption)
|
||||
if hasParam(option) {
|
||||
args = append(args, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestOption_Add(t *testing.T) {
|
||||
type fields struct {
|
||||
Args []string
|
||||
}
|
||||
type args struct {
|
||||
arg string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want []string
|
||||
}{
|
||||
{name: "simple add", fields: fields{
|
||||
Args: []string{"a", "b"},
|
||||
}, args: args{
|
||||
arg: "c",
|
||||
}, want: []string{"a", "b", "c"}},
|
||||
{name: "null add", fields: fields{
|
||||
Args: nil,
|
||||
}, args: args{
|
||||
arg: "c",
|
||||
}, want: []string{"c"}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := &Option{
|
||||
Args: tt.fields.Args,
|
||||
}
|
||||
o.Add(tt.args.arg)
|
||||
assert.EqualValues(t, tt.want, o.Args)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOption_Set(t *testing.T) {
|
||||
type fields struct {
|
||||
Args []string
|
||||
}
|
||||
type args struct {
|
||||
arg string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
want []string
|
||||
}{
|
||||
{name: "simple set", fields: fields{
|
||||
Args: []string{"a", "b"},
|
||||
}, args: args{
|
||||
arg: "c",
|
||||
}, want: []string{"c"}},
|
||||
{name: "null set", fields: fields{
|
||||
Args: nil,
|
||||
}, args: args{
|
||||
arg: "c",
|
||||
}, want: []string{"c"}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := &Option{
|
||||
Args: tt.fields.Args,
|
||||
}
|
||||
o.Set(tt.args.arg)
|
||||
assert.EqualValues(t, tt.want, o.Args)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOption_First(t *testing.T) {
|
||||
type fields struct {
|
||||
Args []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want string
|
||||
}{
|
||||
{name: "simple first", fields: fields{
|
||||
Args: []string{"a", "b"},
|
||||
}, want: "a"},
|
||||
{name: "null first", fields: fields{
|
||||
Args: nil,
|
||||
}, want: ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
o := &Option{
|
||||
Args: tt.fields.Args,
|
||||
}
|
||||
assert.Equal(t, tt.want, o.First())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeArguments(t *testing.T) {
|
||||
args := MakeArguments()
|
||||
assert.NotNil(t, args)
|
||||
assert.Equal(t, "", args.Op)
|
||||
assert.Empty(t, args.Globals)
|
||||
assert.Empty(t, args.Options)
|
||||
assert.Empty(t, args.Targets)
|
||||
}
|
||||
|
||||
func TestArguments_CopyGlobal(t *testing.T) {
|
||||
type fields struct {
|
||||
Op string
|
||||
Options map[string]*Option
|
||||
Globals map[string]*Option
|
||||
Targets []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want *Arguments
|
||||
}{
|
||||
{name: "simple", fields: fields{
|
||||
Op: "Q",
|
||||
Options: map[string]*Option{"a": {}},
|
||||
Globals: map[string]*Option{"arch": {
|
||||
Args: []string{"x86_x64"},
|
||||
}, "boo": {Args: []string{"a", "b"}},
|
||||
},
|
||||
Targets: []string{"a", "b"},
|
||||
}, want: &Arguments{
|
||||
Op: "",
|
||||
Options: map[string]*Option{},
|
||||
Globals: map[string]*Option{"arch": {
|
||||
Args: []string{"x86_x64"},
|
||||
}, "boo": {Args: []string{"a", "b"}},
|
||||
},
|
||||
Targets: []string{},
|
||||
}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parser := &Arguments{
|
||||
Op: tt.fields.Op,
|
||||
Options: tt.fields.Options,
|
||||
Globals: tt.fields.Globals,
|
||||
Targets: tt.fields.Targets,
|
||||
}
|
||||
got := parser.CopyGlobal()
|
||||
assert.NotEqualValues(t, tt.fields.Options, got.Options)
|
||||
assert.NotEqualValues(t, tt.fields.Targets, got.Targets)
|
||||
assert.NotEqual(t, tt.fields.Op, got.Op)
|
||||
assert.EqualValues(t, tt.fields.Globals, got.Globals)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestArguments_Copy(t *testing.T) {
|
||||
type fields struct {
|
||||
Op string
|
||||
Options map[string]*Option
|
||||
Globals map[string]*Option
|
||||
Targets []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want *Arguments
|
||||
}{
|
||||
{name: "simple", fields: fields{
|
||||
Op: "Q",
|
||||
Options: map[string]*Option{"a": {}},
|
||||
Globals: map[string]*Option{"arch": {
|
||||
Args: []string{"x86_x64"},
|
||||
}, "boo": {Args: []string{"a", "b"}},
|
||||
},
|
||||
Targets: []string{"a", "b"},
|
||||
}, want: &Arguments{
|
||||
Op: "Q",
|
||||
Options: map[string]*Option{"a": {}},
|
||||
Globals: map[string]*Option{"arch": {
|
||||
Args: []string{"x86_x64"},
|
||||
}, "boo": {Args: []string{"a", "b"}},
|
||||
},
|
||||
Targets: []string{"a", "b"},
|
||||
}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
parser := &Arguments{
|
||||
Op: tt.fields.Op,
|
||||
Options: tt.fields.Options,
|
||||
Globals: tt.fields.Globals,
|
||||
Targets: tt.fields.Targets,
|
||||
}
|
||||
got := parser.Copy()
|
||||
assert.Equal(t, parser, got)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestArguments_DelArg(t *testing.T) {
|
||||
args := MakeArguments()
|
||||
args.addParam("arch", "arg")
|
||||
args.addParam("ask", "arg")
|
||||
args.DelArg("arch", "ask")
|
||||
assert.Empty(t, args.Options)
|
||||
assert.Empty(t, args.Globals)
|
||||
}
|
||||
Reference in new issue
Block a user