Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
github.com/BoRuDar/configuration/v4
is a library for injecting values recursively into structs - a convenient way of setting up a configuration object. Available features:
NewDefaultProvider()
NewEnvProvider()
NewFlagProvider(&cfg)
NewJSONFileProvider("./testdata/input.json")
string
, *string
, []string
, []*string
bool
, *bool
, []bool
, []*bool
int
, int8
, int16
, int32
, int64
+ slices of these types*int
, *int8
, *int16
, *int32
, *int64
+ slices of these typesuint
, uint8
, uint16
, uint32
, uint64
+ slices of these types*uint
, *uint8
, *uint16
, *uint32
, *uint64
+ slices of these typesfloat32
, float64
+ slices of these types*float32
, *float64
+ slices of these typestime.Duration
from strings like 12ms
, 2s
etc.FieldSetter
interfacetags
)flags
, 2.env
, 3.default
or another order)12-factor app
Import path github.com/BoRuDar/configuration/v4
// defining a struct
cfg := struct {
Name string `flag:"name"`
LastName string `default:"defaultLastName"`
Age byte `env:"AGE_ENV" default:"-1"`
BoolPtr *bool `default:"false"`
ObjPtr *struct {
F32 float32 `default:"32"`
StrPtr *string `default:"str_ptr_test"`
HundredMS time.Duration `default:"100ms"`
}
Obj struct {
IntPtr *int16 `default:"123"`
Beta int `file_json:"inside.beta" default:"24"`
StrSlice []string `default:"one;two"`
IntSlice []int64 `default:"3; 4"`
unexported string `xml:"ignored"`
}
}{}
configurator := configuration.New(
&cfg,
// order of execution will be preserved:
configuration.NewFlagProvider(), // 1st
configuration.NewEnvProvider(), // 2nd
configuration.NewJSONFileProvider(fileName), // 3rd
configuration.NewDefaultProvider(), // 4th
)
if err := configurator.InitValues(); err != nil {
log.Fatalf("unexpected error: ", err)
}
If you need only ENV variables and default values you can use a shorter form:
err := configuration.FromEnvAndDefault(&cfg)
You can specify one or more providers. They will be executed in order of definition:
[]Provider{
NewFlagProvider(&cfg), // 1
NewEnvProvider(), // 2
NewDefaultProvider(), // 3
}
If provider set value successfully next ones will not be executed (if flag provider from the sample above found a value env and default providers are skipped).
The value of first successfully executed provider will be set.
If none of providers found value - an application will be terminated.
This behavior can be changed with configurator.OnFailFnOpt
option:
err := configuration.New(
&cfg,
configuration.NewEnvProvider(),
configuration.NewDefaultProvider()).
SetOptions(
configuration.OnFailFnOpt(func(err error) {
log.Println(err)
}),
).InitValues()
You can define a custom provider which should satisfy next interface:
type Provider interface {
Name() string
Init(ptr any) error
Provide(field reflect.StructField, v reflect.Value) error
}
Looks for default
tag and set value from it:
struct {
// ...
Name string `default:"defaultName"`
// ...
}
Looks for env
tag and tries to find an ENV variable with the name from the tag (AGE
in this example):
struct {
// ...
Age byte `env:"AGE"`
// ...
}
Name inside tag env:"<name>"
must be unique for each field. Only UPPER register for ENV vars is accepted:
bad_env_var_name=bad
GOOD_ENV_VAR_NAME=good
Looks for flag
tag and tries to set value from the command line flag -first_name
struct {
// ...
Name string `flag:"first_name|default_value|Description"`
// ...
}
Name inside tag flag:"<name>"
must be unique for each field. default_value
and description
sections are optional
and can be omitted.
NewFlagProvider(&cfg)
expects a pointer to the same object for initialization.
Note: if program is executed with -help
or -h
flag you will see all available flags with description:
Flags:
-first_name "Description (default: default_value)"
And program execution will be terminated.
Requires file_json:"<path_to_json_field>"
tag.
NewJSONFileProvider("./testdata/input.json")
For example, tag file_json:"cache.retention"
will assume that you have this structure of your JSON file:
{
"cache": {
"retention": 1
}
}
You can define how to set fields with any custom types:
type FieldSetter interface {
SetField(field reflect.StructField, val reflect.Value, valStr string) error
}
Example:
type ipTest net.IP
func (it *ipTest) SetField(_ reflect.StructField, val reflect.Value, valStr string) error {
i := ipTest(net.ParseIP(valStr))
if val.Kind() == reflect.Pointer {
val.Set(reflect.ValueOf(&i))
} else {
val.Set(reflect.ValueOf(i))
}
return nil
}
dev
branchFAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.