Skip to content

Commit

Permalink
[options] Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
andyone committed Oct 20, 2024
1 parent 4cf3628 commit d72e00d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 74 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- `[errors]` Added new package of utilities for working with errors
- `[knf]` Added type `Validators` for `Validator` slice
- `[options]` Code refactoring
- `[errutil]` Package deprecated

### [13.8.1](https://kaos.sh/ek/13.8.1)
Expand Down
57 changes: 15 additions & 42 deletions options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"os"
"strconv"
"strings"

"github.com/essentialkaos/ek/v13/errors"
)

// ////////////////////////////////////////////////////////////////////////////////// //
Expand Down Expand Up @@ -76,9 +78,6 @@ type OptionError struct {
Type int
}

// Errors is a slice with errors
type Errors []error

// ////////////////////////////////////////////////////////////////////////////////// //

type optionName struct {
Expand Down Expand Up @@ -160,12 +159,12 @@ func (o *Options) Add(name string, option *V) error {
}

// AddMap adds map with supported options
func (o *Options) AddMap(optMap Map) Errors {
func (o *Options) AddMap(optMap Map) errors.Errors {
if optMap == nil {
return Errors{ErrNilMap}
return errors.Errors{ErrNilMap}
}

var errs Errors
var errs errors.Errors

for name, opt := range optMap {
err := o.Add(name, opt)
Expand Down Expand Up @@ -392,12 +391,12 @@ func (o *Options) Delete(name string) bool {
}

// Parse parses slice with raw options
func (o *Options) Parse(rawOpts []string, optMap ...Map) (Arguments, Errors) {
func (o *Options) Parse(rawOpts []string, optMap ...Map) (Arguments, errors.Errors) {
if o == nil {
return nil, Errors{ErrNilOptions}
return nil, errors.Errors{ErrNilOptions}
}

var errs Errors
var errs errors.Errors

if len(optMap) != 0 {
for _, m := range optMap {
Expand All @@ -414,32 +413,6 @@ func (o *Options) Parse(rawOpts []string, optMap ...Map) (Arguments, Errors) {

// ////////////////////////////////////////////////////////////////////////////////// //

// String returns string representation of error slice
func (e Errors) String() string {
if e.IsEmpty() {
return ""
}

b := &strings.Builder{}

for i, err := range e {
fmt.Fprintf(b, " - %s", err.Error())

if i != len(e)-1 {
b.WriteRune('\n')
}
}

return b.String()
}

// IsEmpty returns true if errors slice is empty
func (e Errors) IsEmpty() bool {
return len(e) == 0
}

// ////////////////////////////////////////////////////////////////////////////////// //

// Set set option in map
// Note that if the option is already set, it will be replaced
func (m Map) Set(name string, opt *V) error {
Expand Down Expand Up @@ -491,7 +464,7 @@ func Add(name string, opt *V) error {
}

// AddMap adds map with supported options
func AddMap(optMap Map) Errors {
func AddMap(optMap Map) errors.Errors {
if global == nil || !global.initialized {
global = NewOptions()
}
Expand Down Expand Up @@ -575,7 +548,7 @@ func Delete(name string) bool {
}

// Parse parses slice with raw options
func Parse(optMap ...Map) (Arguments, Errors) {
func Parse(optMap ...Map) (Arguments, errors.Errors) {
if global == nil || !global.initialized {
global = NewOptions()
}
Expand Down Expand Up @@ -705,7 +678,7 @@ func (o optionName) String() string {
// without losing code readability
// codebeat:disable[LOC,BLOCK_NESTING,CYCLO]

func (o *Options) parseOptions(rawOpts []string) (Arguments, Errors) {
func (o *Options) parseOptions(rawOpts []string) (Arguments, errors.Errors) {
o.prepare()

if len(rawOpts) == 0 {
Expand All @@ -715,7 +688,7 @@ func (o *Options) parseOptions(rawOpts []string) (Arguments, Errors) {
var optName string
var mixedOpt bool
var arguments Arguments
var errs Errors
var errs errors.Errors

for _, curOpt := range rawOpts {
if optName == "" || mixedOpt {
Expand Down Expand Up @@ -870,8 +843,8 @@ func (o *Options) prepare() {
}
}

func (o *Options) validate() Errors {
var errs Errors
func (o *Options) validate() errors.Errors {
var errs errors.Errors

for n, v := range o.full {
if !isSupportedType(v.Value) {
Expand Down Expand Up @@ -1055,7 +1028,7 @@ func updateIntOption(name string, opt *V, value string) error {
return nil
}

func appendError(errs Errors, err error) Errors {
func appendError(errs errors.Errors, err error) errors.Errors {
if err == nil {
return errs
}
Expand Down
53 changes: 21 additions & 32 deletions options/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ package options
// ////////////////////////////////////////////////////////////////////////////////// //

import (
"fmt"
"strings"
"testing"

. "github.com/essentialkaos/check"

"github.com/essentialkaos/ek/v13/errors"
)

// ////////////////////////////////////////////////////////////////////////////////// //
Expand Down Expand Up @@ -392,50 +393,48 @@ func (s *OptUtilSuite) TestParsing(c *C) {
_, errs := NewOptions().Parse([]string{}, Map{})

c.Assert(errs, HasLen, 0)
c.Assert(errs.IsEmpty(), Equals, true)
c.Assert(errs.String(), Equals, "")

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"--test", "100"}, Map{"t:test": {Type: 10}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" has unsupported type`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" has unsupported type`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{}, Map{"s:string": {}, "s:trace": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "-s" defined 2 or more times`)
c.Assert(errs.Last(), ErrorMatches, `Option "-s" defined 2 or more times`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"-t"}, Map{"s:string": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "-t" is not supported`)
c.Assert(errs.Last(), ErrorMatches, `Option "-t" is not supported`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"-t=100"}, Map{"s:string": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "-t" is not supported`)
c.Assert(errs.Last(), ErrorMatches, `Option "-t" is not supported`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"--test"}, Map{"s:string": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" is not supported`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" is not supported`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"--test=abcd"}, Map{"s:string": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" is not supported`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" is not supported`)

// //////////////////////////////////////////////////////////////////////////////// //

Expand All @@ -449,87 +448,77 @@ func (s *OptUtilSuite) TestParsing(c *C) {
_, errs = NewOptions().Parse([]string{"--asd="}, Map{"t:test": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--asd" has wrong format`)
c.Assert(errs.Last(), ErrorMatches, `Option "--asd" has wrong format`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"-j="}, Map{"t:test": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "-j" has wrong format`)
c.Assert(errs.Last(), ErrorMatches, `Option "-j" has wrong format`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"-t"}, Map{"t:test": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Non-boolean option "--test" is empty`)
c.Assert(errs.Last(), ErrorMatches, `Non-boolean option "--test" is empty`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"--test=!"}, Map{"t:test": {Type: FLOAT}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" has wrong format`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" has wrong format`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"-t=!"}, Map{"t:test": {Type: INT}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" has wrong format`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" has wrong format`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{"--test", "!"}, Map{"t:test": {Type: INT}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" has wrong format`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" has wrong format`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{}, Map{"t:test": nil})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Struct for option "--test" is nil`)
c.Assert(errs.Last(), ErrorMatches, `Struct for option "--test" is nil`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{}, Map{"t:test": {Value: []string{}}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" contains unsupported default value`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" contains unsupported default value`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{}, Map{"t:test": {Conflicts: false}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" contains unsupported list format of conflicting options`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" contains unsupported list format of conflicting options`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{}, Map{"t:test": {Bound: false}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], ErrorMatches, `Option "--test" contains unsupported list format of bound options`)
c.Assert(errs.Last(), ErrorMatches, `Option "--test" contains unsupported list format of bound options`)

// //////////////////////////////////////////////////////////////////////////////// //

_, errs = NewOptions().Parse([]string{}, Map{"": {}})

c.Assert(errs, Not(HasLen), 0)
c.Assert(errs[0], Equals, ErrEmptyName)
}

func (s *OptUtilSuite) TestErrors(c *C) {
errs := Errors{
fmt.Errorf(`Option "--test" has unsupported type`),
fmt.Errorf(`Option "--dump" has unsupported type`),
}

c.Assert(errs.IsEmpty(), Equals, false)
c.Assert(errs.String(), Equals, " - Option \"--test\" has unsupported type\n - Option \"--dump\" has unsupported type")
c.Assert(errs.Last(), Equals, ErrEmptyName)
}

func (s *OptUtilSuite) TestFormat(c *C) {
Expand Down Expand Up @@ -737,7 +726,7 @@ func (s *OptUtilSuite) TestNilOptions(c *C) {
var opts *Options

c.Assert(opts.Add("", &V{}), Equals, ErrNilOptions)
c.Assert(opts.AddMap(Map{"t:": {}}), DeepEquals, Errors{ErrNilOptions})
c.Assert(opts.AddMap(Map{"t:": {}}), DeepEquals, errors.Errors{ErrNilOptions})
c.Assert(opts.GetS("test"), Equals, "")
c.Assert(opts.GetI("test"), Equals, 0)
c.Assert(opts.GetB("test"), Equals, false)
Expand All @@ -748,7 +737,7 @@ func (s *OptUtilSuite) TestNilOptions(c *C) {

_, errs := opts.Parse([]string{}, Map{"t:": {}})

c.Assert(errs, DeepEquals, Errors{ErrNilOptions})
c.Assert(errs, DeepEquals, errors.Errors{ErrNilOptions})
}

func (s *OptUtilSuite) TestNilArguments(c *C) {
Expand Down

0 comments on commit d72e00d

Please sign in to comment.