Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/actions/setup-go-5…
Browse files Browse the repository at this point in the history
….0.2
  • Loading branch information
BROngineer authored Oct 10, 2024
2 parents 3e0a953 + 41638dd commit 66a3ba6
Show file tree
Hide file tree
Showing 50 changed files with 1,452 additions and 1,562 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mod-tidy:

.PHONY: test
test:
go test -race -coverprofile=coverage.out -covermode=atomic -coverpkg=./...
go test ./... -race -coverprofile=coverage.out -covermode=atomic -coverpkg=./...

LOCAL_BIN ?= $(shell pwd)/bin
$(LOCAL_BIN):
Expand Down
8 changes: 8 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
target: auto
threshold: 10%
ignore:
- "examples/**/*"
19 changes: 13 additions & 6 deletions env/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ type replacement struct {
}

type VarNameConstructor struct {
prefix string
capitalize bool
replacement replacement
prefix string
capitalize bool
varNameReplacement replacement
}

func Constructor(charOld, charNew string, opts ...Option) *VarNameConstructor {
c := &VarNameConstructor{replacement: replacement{old: charOld, new: charNew}}
func Constructor(opts ...Option) *VarNameConstructor {
c := &VarNameConstructor{}
for _, opt := range opts {
opt.apply(c)
}
if c.varNameReplacement == (replacement{}) {
c.varNameReplacement = replacement{old: "", new: ""}
}
return c
}

Expand All @@ -32,8 +35,12 @@ func (c *VarNameConstructor) setCapitalize() {
c.capitalize = true
}

func (c *VarNameConstructor) setReplacement(oldChar, newChar string) {
c.varNameReplacement = replacement{old: oldChar, new: newChar}
}

func (c *VarNameConstructor) VarFromFlagName(name string) string {
varName := strings.ReplaceAll(name, c.replacement.old, c.replacement.new)
varName := strings.ReplaceAll(name, c.varNameReplacement.old, c.varNameReplacement.new)
if c.prefix != "" {
varName = fmt.Sprintf("%s_%s", c.prefix, varName)
}
Expand Down
62 changes: 25 additions & 37 deletions env/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,52 @@ import (
)

type testCase struct {
name string
flagName string
replaceOld string
replaceNew string
options []Option
expected string
name string
flagName string
options []Option
expected string
}

func TestVarNameConstructor_VarFromFlagName(t *testing.T) {
t.Parallel()

tests := []testCase{
{
name: "var name as is",
flagName: "sample-flag",
replaceOld: "",
replaceNew: "",
options: []Option{},
expected: "sample-flag",
name: "var name as is",
flagName: "sample-flag",
options: []Option{},
expected: "sample-flag",
},
{
name: "var name capitalized",
flagName: "sample-flag",
replaceOld: "",
replaceNew: "",
options: []Option{Capitalized()},
expected: "SAMPLE-FLAG",
name: "var name capitalized",
flagName: "sample-flag",
options: []Option{Capitalized()},
expected: "SAMPLE-FLAG",
},
{
name: "var name with replacement",
flagName: "sample-flag",
replaceOld: "-",
replaceNew: "_",
options: []Option{Capitalized()},
expected: "SAMPLE_FLAG",
name: "var name with replacement",
flagName: "sample-flag",
options: []Option{Capitalized(), VarNameReplace("-", "_")},
expected: "SAMPLE_FLAG",
},
{
name: "var name with prefix",
flagName: "sample-flag",
replaceOld: "",
replaceNew: "",
options: []Option{Prefix("test")},
expected: "test_sample-flag",
name: "var name with prefix",
flagName: "sample-flag",
options: []Option{Prefix("test")},
expected: "test_sample-flag",
},
{
name: "var name with combined options",
flagName: "sample-flag",
replaceOld: "-",
replaceNew: "_",
options: []Option{Prefix("test"), Capitalized()},
expected: "TEST_SAMPLE_FLAG",
name: "var name with combined options",
flagName: "sample-flag",
options: []Option{Prefix("test"), Capitalized(), VarNameReplace("-", "_")},
expected: "TEST_SAMPLE_FLAG",
},
}
for _, tc := range tests {
tt := tc
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
c := Constructor(tt.replaceOld, tt.replaceNew, tt.options...)
c := Constructor(tt.options...)
actual := c.VarFromFlagName(tt.flagName)
assert.Equal(t, tt.expected, actual)
})
Expand Down
14 changes: 14 additions & 0 deletions env/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package env
type config interface {
setPrefix(string)
setCapitalize()
setReplacement(string, string)
}

type Option interface {
Expand All @@ -28,3 +29,16 @@ func (o capitalized) apply(c config) {
func Capitalized() Option {
return capitalized{}
}

type varNameReplacement struct {
old string
new string
}

func (o varNameReplacement) apply(c config) {
c.setReplacement(o.old, o.new)
}

func VarNameReplace(oldChar, newChar string) Option {
return varNameReplacement{oldChar, newChar}
}
69 changes: 69 additions & 0 deletions examples/bindenv/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package main

import (
"fmt"
"os"
"time"

"github.com/brongineer/helium/env"
"github.com/brongineer/helium/flag"
"github.com/brongineer/helium/flagset"
)

type params struct {
bindAddress string
bindPort uint32
logLevel string
developmentMode bool
timeout time.Duration
peers []string
}

func setEnv() {
_ = os.Setenv("BIND_ENV_EXAMPLE_BIND_ADDRESS", "1.2.3.4")
_ = os.Setenv("BIND_ENV_EXAMPLE_BIND_PORT", "65535")
}

func unsetEnv() {
_ = os.Unsetenv("BIND_ENV_EXAMPLE_BIND_ADDRESS")
_ = os.Unsetenv("BIND_ENV_EXAMPLE_BIND_PORT")
}

func parse(args []string) (params, error) {
fs := flagset.New(env.Prefix("BIND_ENV_EXAMPLE"), env.Capitalized(), env.VarNameReplace("-", "_")).
BindFlag(flag.String("bind-address", flag.Description("bind listen address"), flag.DefaultValue("localhost"))).
BindFlag(flag.Uint32("bind-port", flag.Description("bind listen port"), flag.DefaultValue(uint32(80)))).
BindFlag(flag.String("log-level", flag.Description("logging level"), flag.DefaultValue("info"))).
BindFlag(flag.Bool("development-mode", flag.Shorthand("d"), flag.DefaultValue(false))).
BindFlag(flag.Duration("timeout", flag.Description("context timeout"), flag.Shorthand("t"), flag.DefaultValue(time.Minute))).
BindFlag(flag.StringSlice("peers", flag.Description("remote peers"), flag.DefaultValue([]string{}))).
Build()

if err := fs.Parse(args); err != nil {
return params{}, err
}

if err := fs.BindEnvVars(); err != nil {
return params{}, err
}

return params{
bindAddress: flagset.GetString(fs, "bind-address"),
bindPort: flagset.GetUint32(fs, "bind-port"),
logLevel: flagset.GetString(fs, "log-level"),
developmentMode: flagset.GetBool(fs, "development-mode"),
timeout: flagset.GetDuration(fs, "timeout"),
peers: flagset.GetStringSlice(fs, "peers"),
}, nil
}

func main() {
setEnv()
defer unsetEnv()
opts, err := parse(os.Args)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error: %v", err)
os.Exit(1)
}
fmt.Println("Parsed params:", opts)
}
29 changes: 15 additions & 14 deletions examples/common/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"os"
"time"

"github.com/brongineer/helium"
"github.com/brongineer/helium/flag"
"github.com/brongineer/helium/flagset"
)

type params struct {
Expand All @@ -19,25 +19,26 @@ type params struct {
}

func parse(args []string) (params, error) {
fs := helium.NewFlagSet()
fs.String("bind-address", flag.Description("bind listen address"), flag.DefaultValue("localhost"))
fs.Uint32("bind-port", flag.Description("bind listen port"), flag.DefaultValue(uint32(80)))
fs.String("log-level", flag.Description("logging level"), flag.DefaultValue("info"))
fs.Bool("development-mode", flag.Shorthand("d"), flag.DefaultValue(false))
fs.Duration("timeout", flag.Description("context timeout"), flag.Shorthand("t"), flag.DefaultValue(time.Minute))
fs.StringSlice("peers", flag.Description("remote peers"), flag.DefaultValue([]string{}))
fs := flagset.New().
BindFlag(flag.String("bind-address", flag.Description("bind listen address"), flag.DefaultValue("localhost"))).
BindFlag(flag.Uint32("bind-port", flag.Description("bind listen port"), flag.DefaultValue(uint32(80)))).
BindFlag(flag.String("log-level", flag.Description("logging level"), flag.DefaultValue("info"))).
BindFlag(flag.Bool("development-mode", flag.Shorthand("d"), flag.DefaultValue(false))).
BindFlag(flag.Duration("timeout", flag.Description("context timeout"), flag.Shorthand("t"), flag.DefaultValue(time.Minute))).
BindFlag(flag.StringSlice("peers", flag.Description("remote peers"), flag.DefaultValue([]string{}))).
Build()

if err := fs.Parse(args); err != nil {
return params{}, err
}

return params{
bindAddress: fs.GetString("bind-address"),
bindPort: fs.GetUint32("bind-port"),
logLevel: fs.GetString("log-level"),
developmentMode: fs.GetBool("development-mode"),
timeout: fs.GetDuration("timeout"),
peers: fs.GetStringSlice("peers"),
bindAddress: flagset.GetString(fs, "bind-address"),
bindPort: flagset.GetUint32(fs, "bind-port"),
logLevel: flagset.GetString(fs, "log-level"),
developmentMode: flagset.GetBool(fs, "development-mode"),
timeout: flagset.GetDuration(fs, "timeout"),
peers: flagset.GetStringSlice(fs, "peers"),
}, nil
}

Expand Down
13 changes: 7 additions & 6 deletions examples/custom/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"os"
"time"

"github.com/brongineer/helium"
"github.com/brongineer/helium/flag"
"github.com/brongineer/helium/flagset"
"github.com/brongineer/helium/parser"
)

Expand Down Expand Up @@ -57,17 +57,18 @@ func newCustomParser[T any]() *customParser[T] {
}

func parse(args []string) (params, error) {
fs := helium.NewFlagSet()
helium.CustomFlag[srvParams](fs, "server-config", flag.Parser(newCustomParser[srvParams]()))
helium.CustomFlag[logParams](fs, "log-config", flag.Parser(newCustomParser[logParams]()))
fs := flagset.New().
BindFlag(flag.Typed[srvParams]("server-config", flag.Parser(newCustomParser[srvParams]()))).
BindFlag(flag.Typed[logParams]("log-config", flag.Parser(newCustomParser[logParams]()))).
Build()

if err := fs.Parse(args); err != nil {
return params{}, err
}

return params{
serverOpts: helium.GetCustomFlag[srvParams](fs, "server-config"),
loggerOpts: helium.GetCustomFlag[logParams](fs, "log-config"),
serverOpts: flagset.GetTypedFlag[srvParams](fs, "server-config"),
loggerOpts: flagset.GetTypedFlag[logParams](fs, "log-config"),
}, nil
}

Expand Down
8 changes: 4 additions & 4 deletions flag/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

type fbool = flag[bool]

type Bool struct {
type BoolFlag struct {
*fbool
}

Expand All @@ -25,7 +25,7 @@ func (p *boolParser) ParseCmd(input string) (any, error) {
parsed bool
err error
)
if p.IsVisited() {
if p.IsSetFromCmd() {
return nil, errors.ErrFlagVisited
}
switch input {
Expand All @@ -51,11 +51,11 @@ func (p *boolParser) ParseEnv(input string) (any, error) {
return &parsed, nil
}

func NewBool(name string, opts ...Option) *Bool {
func Bool(name string, opts ...Option) *BoolFlag {
f := newFlag[bool](name)
applyForFlag(f, opts...)
if f.Parser() == nil {
f.setParser(defaultBoolParser())
}
return &Bool{f}
return &BoolFlag{f}
}
8 changes: 4 additions & 4 deletions flag/boolslice.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

type boolSlice = flag[[]bool]

type BoolSlice struct {
type BoolSliceFlag struct {
*boolSlice
}

Expand All @@ -35,7 +35,7 @@ func (p *boolSliceParser) ParseCmd(input string) (any, error) {
}
parsed = append(parsed, v)
}
if p.IsVisited() {
if p.IsSetFromCmd() {
stored := DerefOrDie[[]bool](p.CurrentValue())
parsed = append(stored, parsed...)
}
Expand All @@ -55,11 +55,11 @@ func (p *boolSliceParser) ParseEnv(value string) (any, error) {
return &parsed, nil
}

func NewBoolSlice(name string, opts ...Option) *BoolSlice {
func BoolSlice(name string, opts ...Option) *BoolSliceFlag {
f := newFlag[[]bool](name)
applyForFlag(f, opts...)
if f.Parser() == nil {
f.setParser(defaultBoolSliceParser())
}
return &BoolSlice{f}
return &BoolSliceFlag{f}
}
Loading

0 comments on commit 66a3ba6

Please sign in to comment.