-
Notifications
You must be signed in to change notification settings - Fork 21
Add Environment Variable Source to Staert #42
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a first quick review.
I did not repeat a message for the repetitive problems.
I do not take a look on algorithmic.
envsource_assign_test.go
Outdated
"testing" | ||
|
||
"github.com/containous/flaeg/parse" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please group imports.
import (
"reflect"
"testing"
"github.com/containous/flaeg/parse"
"github.com/stretchr/testify/assert"
)
envsource_assign_test.go
Outdated
OtherStringValue string | ||
}{}, | ||
[]*envValue{ | ||
&envValue{"FOO", path{"StringValue"}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&envValue
declaration is not needed, same everywhere
envsource.go
Outdated
|
||
values, err := e.analyzeStruct(configVal.Type(), []string{}) | ||
|
||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
values, err := e.analyzeStruct(configVal.Type(), []string{})
if err != nil {
return err
}
envsource.go
Outdated
// Recursively scan the given config structure type information | ||
// and look for defined environment variables. | ||
func (e *envSource) analyzeStruct(configType reflect.Type, currentPath path) ([]*envValue, error) { | ||
res := []*envValue{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var res []*envValue
envsource.go
Outdated
|
||
if err != nil { | ||
return []*envValue{}, err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
values, err := e.analyzeValue(field.Type, currentPath)
if err != nil {
return nil, err
}
envsource_assign_test.go
Outdated
t.Fail() | ||
} | ||
|
||
assert.Exactly(t, testCase.Expectation, testCase.Value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't mix stblib test and testify.
Either you use stblib everywhere or testify, but not the both.
envsource_assign_test.go
Outdated
} | ||
} | ||
|
||
func TestFilterEnvVarWithPrefix(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could move the tests on the top of the file (after type declaration)
envsource_assign_test.go
Outdated
Expectation interface{} | ||
}{ | ||
{ | ||
"BasicStruct", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you explicitly name all fields.
envsource_assign_test.go
Outdated
Config []basicAppConfig | ||
}{}, | ||
[]*envValue{ | ||
&envValue{"Test", path{"Config", "0", "StringValue"}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
&envValue
declaration is not needed, same everywhere
envsource_assign_test.go
Outdated
expectedPtrPtr := getPtrPtrConfig() | ||
|
||
testCases := []struct { | ||
Label string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add the test cases description for each test.
use a field desc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what the Label field should do. "BasicStructPointerPointer", "WithWrongPath". What format do you use for test names/descriptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use desc
to avoid ambiguities of names like name
, label
, ...
The description must be a sentence or partial sentence.
ex: with a wrong path
I love the should ... when ...
format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed the label to provide better context and be more readable. if a test fails it looks like this :
TestAssignValues/should_assign_values_to_config_with_a_map_that_uses_a_parser_for_values (0.00s)
changed field name to desc
Commits 9840c06 and onwards are fixes following the review |
There is a problem, it's complex to explain. The problem is related to the To explain I will give you some example from the Case 1DurationField = 28
[PtrStruct1]
S1Int = 28 config := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 1,
S1String: "S1StringInitConfig",
},
DurationField: parse.Duration(time.Second),
} defaultPointersConfig := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 11,
S1String: "S1StringDefaultPointersConfig",
S1Bool: true,
S1PtrStruct3: &Struct3{
S3Float64: 11.11,
},
},
} Result: {
"PtrStruct1": {
"S1Int": 28,
"S1String": "S1StringDefaultPointersConfig",
"S1Bool": true,
"S1PtrStruct3": null
},
"DurationField":"28s"
} Case 2DurationField = 28
[PtrStruct1]
S1Int = 28
S1String = "S1StringToml" config := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 1,
S1String: "S1StringInitConfig",
},
DurationField: parse.Duration(time.Second),
} defaultPointersConfig := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 11,
S1String: "S1StringDefaultPointersConfig",
S1Bool: true,
S1PtrStruct3: &Struct3{
S3Float64: 11.11,
},
},
} Result: {
"PtrStruct1": {
"S1Int": 28,
"S1String": "S1StringToml",
"S1Bool": true,
"S1PtrStruct3": null
},
"DurationField":"28s"
} Case 3DurationField = 28
[PtrStruct1]
S1Int = 28
S1Bool = false config := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 1,
S1String: "S1StringInitConfig",
},
DurationField: parse.Duration(time.Second),
} defaultPointersConfig := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 11,
S1String: "S1StringDefaultPointersConfig",
S1Bool: true,
S1PtrStruct3: &Struct3{
S3Float64: 11.11,
},
},
} Result: {
"PtrStruct1": {
"S1Int": 28,
"S1String": "S1StringDefaultPointersConfig",
"S1Bool": false,
"S1PtrStruct3": null
},
"DurationField":"28s"
} Case 4DurationField = 28
[PtrStruct1]
S1Int = 28
S1Bool = false config := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 1,
S1String: "S1StringInitConfig",
},
DurationField: parse.Duration(time.Second),
} defaultPointersConfig := &StructPtr{
PtrStruct1: &Struct1{
S1Int: 11,
S1String: "S1StringDefaultPointersConfig",
S1Bool: true,
S1PtrStruct3: &Struct3{
S3Float64: 11.11,
},
},
} Result: {
"PtrStruct1": {
"S1Int": 28,
"S1String": "S1StringDefaultPointersConfig",
"S1Bool": false,
"S1PtrStruct3": null
},
"DurationField":"28s"
} |
Description
This is a first shot at providing an environment variable source to staert (and traefik). I revived #30, extended it, and finished it. I'll add documentation (it's pretty much similar to the initial PR one, so see :
I tested it briefly with traefik, I'll send a PR there too as I get closer to a releasable state.)
I have integrated it in traefik to test, and it manages to parse the entire config tree from traefik. that covers many cases. I'm not certain it manages to SET all values though. so more tests will be needed there.
Quite some work left to do though before calling it done :
DefaultPointerConfig
When it comes to
defaultPointerConfig
, some notes that made me understand it 🥇defaultConfig
--pointerName
, it touches the value, and so, you take the default pointer valuedefaultPointerConfig
value as defaultRelated to traefik/traefik#7