-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e3164d7
commit 6d88a43
Showing
14 changed files
with
394 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package option | ||
|
||
import "reflect" | ||
|
||
type FieldInitializedArg struct { | ||
Name string | ||
FullName string | ||
Type reflect.Type | ||
Required bool | ||
Description string | ||
|
||
FlagName string | ||
EnvName string | ||
DefaultValue interface{} | ||
} | ||
|
||
type FieldDefinedArg struct { | ||
Name string | ||
FullName string | ||
Type reflect.Type | ||
Required bool | ||
Description string | ||
|
||
FlagName string | ||
EnvName string | ||
DefaultValue interface{} | ||
|
||
Source ConfigSource | ||
Value interface{} | ||
} | ||
|
||
type FieldDefineErrorArg struct { | ||
Name string | ||
FullName string | ||
Type reflect.Type | ||
Err error | ||
} | ||
|
||
type Options struct { | ||
PriorityOrder []ConfigSource | ||
FlagParsed func() error | ||
Usage func() | ||
OnFieldInitialized []func(FieldInitializedArg) | ||
OnFieldDefined []func(FieldDefinedArg) | ||
OnFieldDefineErr []func(FieldDefineErrorArg) | ||
} | ||
|
||
type ClientOption interface { | ||
Apply(*Options) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package option | ||
|
||
type ConfigSource int | ||
|
||
const ( | ||
FlagVariable ConfigSource = iota | ||
EnvVariable | ||
ExternalSource | ||
DefaultValue | ||
) | ||
|
||
func (s ConfigSource) String() string { | ||
switch s { | ||
case FlagVariable: | ||
return "Flag" | ||
case EnvVariable: | ||
return "Environment" | ||
case ExternalSource: | ||
return "External" | ||
case DefaultValue: | ||
return "Default" | ||
} | ||
return "" | ||
} | ||
|
||
type priorityOrder []ConfigSource | ||
|
||
func (p priorityOrder) Apply(opts *Options) { | ||
opts.PriorityOrder = p | ||
} | ||
|
||
// WithPriorityOrder overrides default priority order, with an order from function argument. | ||
// Default priority order is: Flag, Environment variable, External source, Default value. | ||
func WithPriorityOrder(s ...ConfigSource) ClientOption { | ||
defaultOrder := []ConfigSource{ | ||
FlagVariable, EnvVariable, ExternalSource, DefaultValue, | ||
} | ||
if len(s) == 0 { | ||
return priorityOrder(defaultOrder) | ||
} | ||
po := make(map[ConfigSource]int) | ||
var idx int | ||
for _, p := range s { | ||
if p != FlagVariable && p != EnvVariable && | ||
p != ExternalSource && p != DefaultValue { | ||
continue | ||
} | ||
if _, ok := po[p]; !ok { | ||
po[p] = idx | ||
idx++ | ||
} | ||
} | ||
if len(po) == 0 { | ||
return priorityOrder(defaultOrder) | ||
} | ||
result := make([]ConfigSource, len(po)) | ||
for s, idx := range po { | ||
result[idx] = s | ||
} | ||
return priorityOrder(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package option | ||
|
||
type flagParsedFunc func() error | ||
|
||
func (fP flagParsedFunc) Apply(opts *Options) { | ||
opts.FlagParsed = fP | ||
} | ||
|
||
// WithFlagParsed define this callback when you need handle flags | ||
// This callback will raise after method flag.Parse() | ||
// return not nil error interrupt pasring | ||
func WithFlagParsed(flagParsed func() error) ClientOption { | ||
return flagParsedFunc(flagParsed) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package option | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
) | ||
|
||
type help struct { | ||
fields []FieldInitializedArg | ||
} | ||
|
||
func (h *help) usage() { | ||
fmt.Fprintln(os.Stdout, "Usage:") | ||
fmt.Fprintln(os.Stdout, "") | ||
h.print() | ||
} | ||
|
||
func (h *help) print() { | ||
for _, f := range h.fields { | ||
h.printValue(f) | ||
} | ||
} | ||
|
||
func (h *help) printValue(f FieldInitializedArg) { | ||
// TODO: help should be configurable | ||
fmt.Fprintf(os.Stdout, "%s <%s> %s\n", f.FullName, f.Type.Name(), f.DefaultValue) | ||
fmt.Fprintf(os.Stdout, "\tflag: %s\n", f.FlagName) | ||
fmt.Fprintf(os.Stdout, "\tenvironment variable: %s\n", f.EnvName) | ||
fmt.Fprintf(os.Stdout, "\trequired: %t\n", f.Required) | ||
if f.Description != "" { | ||
fmt.Fprintf(os.Stdout, "\tdescription: \"%s\"\n", f.Description) | ||
} | ||
fmt.Fprintln(os.Stdout) | ||
} | ||
|
||
func (h *help) addField(arg FieldInitializedArg) { | ||
h.fields = append(h.fields, arg) | ||
} | ||
|
||
func (h *help) Apply(opts *Options) { | ||
opts.Usage = h.usage | ||
opts.OnFieldInitialized = append(opts.OnFieldInitialized, h.addField) | ||
} | ||
|
||
func WithFlagUsage() ClientOption { | ||
h := &help{ | ||
fields: make([]FieldInitializedArg, 0), | ||
} | ||
return h | ||
} |
Oops, something went wrong.