From d0125c22f98ce10718f50067edbcb140c7f49a68 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 16:01:02 -0800 Subject: [PATCH 01/11] add dependabot and tests to GH runners --- .github/dependabot.yml | 10 ++++++++++ .github/workflows/build.yml | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..aa854e5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..eed750e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,36 @@ +name: Test +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + +jobs: + go-test: + name: Go Test + runs-on: ubuntu-latest + steps: + - name: Check out source + uses: actions/checkout@v6 + - name: Read go version + id: go_version + run: | + # Read the variable from the file + GO_VERSION=$(grep '^go ' go.mod | awk '{print $2}') + # Set the variable as an output + echo "GO_VERSION=$GO_VERSION" >> $GITHUB_OUTPUT + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: ${{ steps.go_version.outputs.GO_VERSION }} + + - name: Build + run: | + go get -t ./... + go build . + + - name: Test + run: | + go test . From dbd5d78ec9f90c4de196e2c5f01d2d927a29ecf3 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 16:01:16 -0800 Subject: [PATCH 02/11] add go.mod --- go.mod | 7 +++++++ go.sum | 4 ++++ 2 files changed, 11 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c46aaf1 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module github.com/zmap/zflags + +go 1.24.0 + +require github.com/jessevdk/go-flags v1.6.1 + +require golang.org/x/sys v0.38.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..26c34bd --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= +github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= From 053722b983f123bb9ff5f942fd120f7244548e6b Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 16:02:49 -0800 Subject: [PATCH 03/11] remove travis --- .travis.yml | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9cb28ae..0000000 --- a/.travis.yml +++ /dev/null @@ -1,38 +0,0 @@ -language: go - -go: - - 1.6.x - - 1.7.x - -install: - # go-flags - - go get -d -v ./... - - go build -v ./... - - # linting - - go get github.com/golang/lint - - go install golang.org/x/lint/golint - - # code coverage - - go get golang.org/x/tools/cmd/cover - - go get github.com/onsi/ginkgo/ginkgo - - go get github.com/modocache/gover - - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then go get github.com/mattn/goveralls; fi - -script: - # go-flags - - $(exit $(gofmt -l . | wc -l)) - - go test -v ./... - - # linting - - go tool vet -all=true -v=true . || true - - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/golint ./... - - # code coverage - - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/ginkgo -r -cover - - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/gover - - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=gover.coverprofile -service=travis-ci -repotoken $COVERALLS_TOKEN; fi - -env: - # coveralls.io - secure: "RCYbiB4P0RjQRIoUx/vG/AjP3mmYCbzOmr86DCww1Z88yNcy3hYr3Cq8rpPtYU5v0g7wTpu4adaKIcqRE9xknYGbqj3YWZiCoBP1/n4Z+9sHW3Dsd9D/GRGeHUus0laJUGARjWoCTvoEtOgTdGQDoX7mH+pUUY0FBltNYUdOiiU=" From 54ca86d2afe2773746748dec63ffefd87e6076bb Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 16:02:58 -0800 Subject: [PATCH 04/11] add go vet --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eed750e..90428e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,3 +34,6 @@ jobs: - name: Test run: | go test . + - name: Lint + run: | + go vet . From ec10d81f47694e75a1bff5c997874a9d6a967b83 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 16:05:57 -0800 Subject: [PATCH 05/11] Revert "add go vet" This reverts commit 54ca86d2afe2773746748dec63ffefd87e6076bb. --- .github/workflows/build.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 90428e2..eed750e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,6 +34,3 @@ jobs: - name: Test run: | go test . - - name: Lint - run: | - go vet . From a1f944ba0bf2b2b0ae78fcab4870347277e152b1 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 16:16:19 -0800 Subject: [PATCH 06/11] ensure we don't seg fault in parse --- ini.go | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/ini.go b/ini.go index e7f866b..6e6ba74 100644 --- a/ini.go +++ b/ini.go @@ -115,18 +115,18 @@ func (i *IniParser) ParseFile(filename string) ([]string, []interface{}, error) // // The format of the ini file is as follows: // -// [Option group name] -// option = value +// [Option group name] +// option = value // // Each section in the ini file represents an option group or command in the // flags parser. The default flags parser option group (i.e. when using // flags.Parse) is named 'Application Options'. The ini option name is matched // in the following order: // -// 1. Compared to the ini-name tag on the option struct field (if present) -// 2. Compared to the struct field name -// 3. Compared to the option long name (if present) -// 4. Compared to the option short name (if present) +// 1. Compared to the ini-name tag on the option struct field (if present) +// 2. Compared to the struct field name +// 3. Compared to the option long name (if present) +// 4. Compared to the option short name (if present) // // Sections for nested groups and commands can be addressed using a dot `.' // namespacing notation (i.e [subcommand.Options]). Group section names are @@ -604,15 +604,17 @@ func (i *IniParser) parse(ini *ini) ([]string, []interface{}, error) { if name != "" && name != "Application Options" { c := i.parser.Find(name) - if cmd, ok := c.data.(ZCommander); ok { - if err := cmd.Validate([]string{}); err != nil { //validate - log.Fatal(err) + if c != nil { + if cmd, ok := c.data.(ZCommander); ok { + if err := cmd.Validate([]string{}); err != nil { //validate + log.Fatal(err) + } + modTypes = append(modTypes, name) + returnFlags = append(returnFlags, c.data) + par, _ := c.parent.(*Command) + c.Name = "-" //remove previous command + par.AddCommand(name, c.ShortDescription, c.LongDescription, c.module) //recreate new group with duplicate module } - modTypes = append(modTypes, name) - returnFlags = append(returnFlags, c.data) - par, _ := c.parent.(*Command) - c.Name = "-" //remove previous command - par.AddCommand(name, c.ShortDescription, c.LongDescription, c.module) //recreate new group with duplicate module } } } From 0641ddf5125f9c989c07716344d431f54c9df8e4 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Mon, 24 Nov 2025 17:00:29 -0800 Subject: [PATCH 07/11] fix fallback test --- fallback_test.go | 102 ++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/fallback_test.go b/fallback_test.go index 6295d92..7def495 100644 --- a/fallback_test.go +++ b/fallback_test.go @@ -1,6 +1,7 @@ package flags import ( + "fmt" "os" "reflect" "testing" @@ -11,9 +12,9 @@ import ( // when `env` is absent, it attempts to fall back to `long` (and to `json`) func TestFallback(t *testing.T) { type Options struct { - Int int `long:"int" json:"json-int" default:"1"` - Time time.Duration `json:"time" default:"1m"` - Map map[string]int `json:"map,omitempty" default:"a:1" env-delim:";"` + Int int `long:"int" json:"json-int" default:"1" env:"Int"` + Time time.Duration `json:"time" default:"1m" env:"Time"` + Map map[string]int `json:"map,omitempty" default:"a:1" env:"Map" env-delim:";"` Slice []int `long:"slice" default:"1" default:"2" env:"OVERRIDE_SLICE" env-delim:","` } @@ -27,19 +28,19 @@ func TestFallback(t *testing.T) { msg: "JSON override", args: []string{}, expected: Options{ - Int: 23, - Time: time.Minute * 3, - Map: map[string]int{"key1": 1}, - Slice: []int{3,4,5}, + Int: 23, + Time: time.Minute * 3, + Map: map[string]int{"key1": 1}, + Slice: []int{3, 4, 5}, }, env: map[string]string{ // since both `json` and `long` are present, `long` ("int") wins "json-int": "4", - "int": "23", - "time": "3m", - "map": "key1:1", + "Int": "23", + "Time": "3m", + "Map": "key1:1", // since both `env` and `long` are present, `env` ("OVERRIDE_SLICE") wins - "slice": "3,2,1", + "Slice": "3,2,1", "OVERRIDE_SLICE": "3,4,5", }, }, @@ -63,9 +64,9 @@ func TestFallback(t *testing.T) { Slice: []int{4, 5, 6}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "OVERRIDE_SLICE": "4,5,6", }, }, @@ -75,13 +76,13 @@ func TestFallback(t *testing.T) { expected: Options{ Int: 3, Time: 3 * time.Millisecond, - Map: map[string]int{"c": 3,"d":4}, - Slice: []int{3,1}, + Map: map[string]int{"c": 3, "d": 4}, + Slice: []int{3, 1}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "OVERRIDE_SLICE": "4,5,6", }, }, @@ -95,9 +96,9 @@ func TestFallback(t *testing.T) { Slice: []int{0}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "OVERRIDE_SLICE": "4,5,6", }, }, @@ -111,9 +112,9 @@ func TestFallback(t *testing.T) { Slice: []int{0}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "Slice": "4,5,6", }, }, @@ -126,9 +127,12 @@ func TestFallback(t *testing.T) { var opts Options oldEnv.Restore() for envKey, envValue := range test.env { - os.Setenv(envKey, envValue) + err := os.Setenv(envKey, envValue) + if err != nil { + t.Fatal(fmt.Errorf("error setting env var (%s): %s", envKey, err)) + } } - _, _, _, err := NewParser(&opts, Default | EnvironmentFallback).ParseCommandLine(test.args) + _, _, _, err := NewParser(&opts, Default|EnvironmentFallback).ParseCommandLine(test.args) if err != nil { t.Fatalf("%s:\nUnexpected error: %v", test.msg, err) } @@ -163,17 +167,17 @@ func TestNoFallback(t *testing.T) { msg: "JSON override", args: []string{}, expected: Options{ - Int: 1, - Time: time.Minute * 1, - Map: map[string]int{"a": 1}, - Slice: []int{3,4,5}, + Int: 1, + Time: time.Minute * 1, + Map: map[string]int{"a": 1}, + Slice: []int{3, 4, 5}, }, env: map[string]string{ - "json-int": "4", - "int": "23", - "time": "3m", - "map": "key1:1", - "slice": "3,2,1", + "json-int": "4", + "int": "23", + "time": "3m", + "map": "key1:1", + "slice": "3,2,1", "OVERRIDE_SLICE": "3,4,5", }, }, @@ -197,9 +201,9 @@ func TestNoFallback(t *testing.T) { Slice: []int{4, 5, 6}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "OVERRIDE_SLICE": "4,5,6", }, }, @@ -209,13 +213,13 @@ func TestNoFallback(t *testing.T) { expected: Options{ Int: 3, Time: 3 * time.Millisecond, - Map: map[string]int{"c": 3,"d":4}, - Slice: []int{3,1}, + Map: map[string]int{"c": 3, "d": 4}, + Slice: []int{3, 1}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "OVERRIDE_SLICE": "4,5,6", }, }, @@ -229,9 +233,9 @@ func TestNoFallback(t *testing.T) { Slice: []int{0}, }, env: map[string]string{ - "Int": "2", - "Time": "2m", - "Map": "a:2;b:3", + "Int": "2", + "Time": "2m", + "Map": "a:2;b:3", "OVERRIDE_SLICE": "4,5,6", }, }, @@ -246,7 +250,7 @@ func TestNoFallback(t *testing.T) { for envKey, envValue := range test.env { os.Setenv(envKey, envValue) } - _, _, _, err := NewParser(&opts, Default & (^EnvironmentFallback)).ParseCommandLine(test.args) + _, _, _, err := NewParser(&opts, Default&(^EnvironmentFallback)).ParseCommandLine(test.args) if err != nil { t.Fatalf("%s:\nUnexpected error: %v", test.msg, err) } @@ -259,4 +263,4 @@ func TestNoFallback(t *testing.T) { t.Errorf("%s:\nUnexpected options with arguments %+v\nexpected\n%+v\nbut got\n%+v\n", test.msg, test.args, test.expected, opts) } } -} \ No newline at end of file +} From 607ccbb1ee35578d24893ade4740037385ecf24f Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Tue, 25 Nov 2025 12:08:13 -0800 Subject: [PATCH 08/11] Since we're setting the defaults on ini sections, we shouldn't test that the defaults are cleared when they shouldn't be --- ini_test.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/ini_test.go b/ini_test.go index 7718b9e..e09dfb2 100644 --- a/ini_test.go +++ b/ini_test.go @@ -433,9 +433,6 @@ DefaultArray = 1 DefaultArray = "2" DefaultArray = 3 -; Testdefault map value -; DefaultMap = - ; Test env-default1 value EnvDefault1 = env-def @@ -443,9 +440,6 @@ EnvDefault1 = env-def EnvDefault2 = env-def [Other Options] -; A slice of strings -; StringSlice = - ; A map from string to int int-map = a:2 int-map = b:"3" @@ -464,9 +458,6 @@ DefaultArray = 1 DefaultArray = 2 DefaultArray = 3 -; Testdefault map value -; DefaultMap = - ; Test env-default1 value EnvDefault1 = env-def @@ -474,9 +465,6 @@ EnvDefault1 = env-def EnvDefault2 = env-def [Other Options] -; A slice of strings -; StringSlice = - ; A map from string to int int-map = a:2 int-map = b:3 @@ -529,9 +517,6 @@ DefaultArray = "1" DefaultArray = "2" DefaultArray = "3" -; Testdefault map value -; DefaultMap = - ; Test env-default1 value EnvDefault1 = env-def @@ -539,9 +524,6 @@ EnvDefault1 = env-def EnvDefault2 = env-def [Other Options] -; A slice of strings -; StringSlice = - ; A map from string to int int-map = a:"2" int-map = b:"3" From 9ec38507a83df6ce717c4bf9996dac0b6dbaa7ab Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Tue, 25 Nov 2025 12:30:31 -0800 Subject: [PATCH 09/11] added unit test for listing section multiple times --- ini_test.go | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/ini_test.go b/ini_test.go index e09dfb2..8fb1638 100644 --- a/ini_test.go +++ b/ini_test.go @@ -412,6 +412,76 @@ int-map = b:3 } } +func TestReadIniMultipleSections(t *testing.T) { + var opts helpOptions + + p := NewNamedParser("TestIni", Default) + p.AddGroup("Application Options", "The application options", &opts) + + inip := NewIniParser(p) + + inic := ` +; Show verbose debug information +verbose = true +verbose = true + +DefaultMap = another:"value\n1" +DefaultMap = some:value 2 + +[Application Options] +; A slice of pointers to string +; PtrSlice = + +; Test default value +;;;;;;;;;;Default = "New\nvalue" + +[Application Options] +; Test env-default1 value +EnvDefault1 = New value + +[Other Options] +# A slice of strings +StringSlice = "some\nvalue" +StringSlice = another value + +; A map from string to int +int-map = a:2 +int-map = b:3 + +` + + b := strings.NewReader(inic) + _, _, err := inip.Parse(b) + + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + + assertBoolArray(t, opts.Verbose, []bool{true, true}) + + if v := map[string]string{"another": "value\n1", "some": "value 2"}; !reflect.DeepEqual(opts.DefaultMap, v) { + t.Fatalf("Expected %#v for DefaultMap but got %#v", v, opts.DefaultMap) + } + + assertString(t, opts.Default, "Some\nvalue") + + assertString(t, opts.EnvDefault1, "New value") + + assertStringArray(t, opts.Other.StringSlice, []string{"some\nvalue", "another value"}) + + if v, ok := opts.Other.IntMap["a"]; !ok { + t.Errorf("Expected \"a\" in Other.IntMap") + } else if v != 2 { + t.Errorf("Expected Other.IntMap[\"a\"] = 2, but got %v", v) + } + + if v, ok := opts.Other.IntMap["b"]; !ok { + t.Errorf("Expected \"b\" in Other.IntMap") + } else if v != 3 { + t.Errorf("Expected Other.IntMap[\"b\"] = 3, but got %v", v) + } +} + func TestReadAndWriteIni(t *testing.T) { var tests = []struct { options IniOptions From 5663afe40aa54f5e57eb209abcacd3d57417c2d0 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Tue, 25 Nov 2025 12:35:18 -0800 Subject: [PATCH 10/11] refactored test to re-use evaluation code --- ini_test.go | 119 +++++++++++++++++++--------------------------------- 1 file changed, 44 insertions(+), 75 deletions(-) diff --git a/ini_test.go b/ini_test.go index 8fb1638..ee5c899 100644 --- a/ini_test.go +++ b/ini_test.go @@ -345,13 +345,14 @@ ns1.opt8=true func TestReadIni(t *testing.T) { var opts helpOptions - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - inic := ` + tests := []struct { + name string + ini string + expectedValueOfDefaultOpt string + }{ + { + "Single Application Options section", + ` ; Show verbose debug information verbose = true verbose = true @@ -378,49 +379,10 @@ StringSlice = another value int-map = a:2 int-map = b:3 -` - - b := strings.NewReader(inic) - _, _, err := inip.Parse(b) - - if err != nil { - t.Fatalf("Unexpected error: %s", err) - } - - assertBoolArray(t, opts.Verbose, []bool{true, true}) - - if v := map[string]string{"another": "value\n1", "some": "value 2"}; !reflect.DeepEqual(opts.DefaultMap, v) { - t.Fatalf("Expected %#v for DefaultMap but got %#v", v, opts.DefaultMap) - } - - assertString(t, opts.Default, "New\nvalue") - - assertString(t, opts.EnvDefault1, "New value") - - assertStringArray(t, opts.Other.StringSlice, []string{"some\nvalue", "another value"}) - - if v, ok := opts.Other.IntMap["a"]; !ok { - t.Errorf("Expected \"a\" in Other.IntMap") - } else if v != 2 { - t.Errorf("Expected Other.IntMap[\"a\"] = 2, but got %v", v) - } - - if v, ok := opts.Other.IntMap["b"]; !ok { - t.Errorf("Expected \"b\" in Other.IntMap") - } else if v != 3 { - t.Errorf("Expected Other.IntMap[\"b\"] = 3, but got %v", v) - } -} - -func TestReadIniMultipleSections(t *testing.T) { - var opts helpOptions - - p := NewNamedParser("TestIni", Default) - p.AddGroup("Application Options", "The application options", &opts) - - inip := NewIniParser(p) - - inic := ` +`, "New\nvalue", + }, { + "Multiple Application Options sections", + ` ; Show verbose debug information verbose = true verbose = true @@ -432,9 +394,7 @@ DefaultMap = some:value 2 ; A slice of pointers to string ; PtrSlice = -; Test default value -;;;;;;;;;;Default = "New\nvalue" - + ;Second Application Options Section [Application Options] ; Test env-default1 value EnvDefault1 = New value @@ -448,37 +408,46 @@ StringSlice = another value int-map = a:2 int-map = b:3 -` +`, "Some\nvalue", + }, + } - b := strings.NewReader(inic) - _, _, err := inip.Parse(b) + for _, test := range tests { + p := NewNamedParser("TestIni", Default) + p.AddGroup("Application Options", "The application options", &opts) - if err != nil { - t.Fatalf("Unexpected error: %s", err) - } + inip := NewIniParser(p) - assertBoolArray(t, opts.Verbose, []bool{true, true}) + b := strings.NewReader(test.ini) + _, _, err := inip.Parse(b) - if v := map[string]string{"another": "value\n1", "some": "value 2"}; !reflect.DeepEqual(opts.DefaultMap, v) { - t.Fatalf("Expected %#v for DefaultMap but got %#v", v, opts.DefaultMap) - } + if err != nil { + t.Fatalf("Unexpected error: %s", err) + } + + assertBoolArray(t, opts.Verbose, []bool{true, true}) - assertString(t, opts.Default, "Some\nvalue") + if v := map[string]string{"another": "value\n1", "some": "value 2"}; !reflect.DeepEqual(opts.DefaultMap, v) { + t.Fatalf("Expected %#v for DefaultMap but got %#v", v, opts.DefaultMap) + } - assertString(t, opts.EnvDefault1, "New value") + assertString(t, opts.Default, test.expectedValueOfDefaultOpt) - assertStringArray(t, opts.Other.StringSlice, []string{"some\nvalue", "another value"}) + assertString(t, opts.EnvDefault1, "New value") - if v, ok := opts.Other.IntMap["a"]; !ok { - t.Errorf("Expected \"a\" in Other.IntMap") - } else if v != 2 { - t.Errorf("Expected Other.IntMap[\"a\"] = 2, but got %v", v) - } + assertStringArray(t, opts.Other.StringSlice, []string{"some\nvalue", "another value"}) - if v, ok := opts.Other.IntMap["b"]; !ok { - t.Errorf("Expected \"b\" in Other.IntMap") - } else if v != 3 { - t.Errorf("Expected Other.IntMap[\"b\"] = 3, but got %v", v) + if v, ok := opts.Other.IntMap["a"]; !ok { + t.Errorf("Expected \"a\" in Other.IntMap") + } else if v != 2 { + t.Errorf("Expected Other.IntMap[\"a\"] = 2, but got %v", v) + } + + if v, ok := opts.Other.IntMap["b"]; !ok { + t.Errorf("Expected \"b\" in Other.IntMap") + } else if v != 3 { + t.Errorf("Expected Other.IntMap[\"b\"] = 3, but got %v", v) + } } } From 276479d8f5d357dd10e5e8a0a105a706fdeb5911 Mon Sep 17 00:00:00 2001 From: phillip-stephens Date: Tue, 25 Nov 2025 12:40:29 -0800 Subject: [PATCH 11/11] remove dependency on jesse's go-flags library --- examples/main.go | 3 ++- go.mod | 4 ---- go.sum | 4 ---- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/examples/main.go b/examples/main.go index 632c331..95208fe 100644 --- a/examples/main.go +++ b/examples/main.go @@ -3,10 +3,11 @@ package main import ( "errors" "fmt" - "github.com/jessevdk/go-flags" "os" "strconv" "strings" + + flags "github.com/zmap/zflags" ) type EditorOptions struct { diff --git a/go.mod b/go.mod index c46aaf1..9c3fc64 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,3 @@ module github.com/zmap/zflags go 1.24.0 - -require github.com/jessevdk/go-flags v1.6.1 - -require golang.org/x/sys v0.38.0 // indirect diff --git a/go.sum b/go.sum index 26c34bd..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +0,0 @@ -github.com/jessevdk/go-flags v1.6.1 h1:Cvu5U8UGrLay1rZfv/zP7iLpSHGUZ/Ou68T0iX1bBK4= -github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=