Skip to content
This repository has been archived by the owner on Apr 27, 2022. It is now read-only.

Fix default values for pointers (print) #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions flaeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,11 @@ func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Va
case reflect.Ptr:
if !defaultPointersValue.IsNil() {
if len(key) != 0 {
//turn ptr fields to nil
defaultPointersNilValue, err := setPointersNil(defaultPointersValue)
if err != nil {
return err
if !defaultValue.IsNil() {
defaultValmap[name] = reflect.ValueOf(true)
} else {
defaultValmap[name] = reflect.ValueOf(false)
}
defaultValmap[name] = defaultPointersNilValue
// fmt.Printf("%s: got default value %+v\n", name, defaultPointersNilValue)
}
if !defaultValue.IsNil() {
if err := getDefaultValue(defaultValue.Elem(), defaultPointersValue.Elem(), defaultValmap, name); err != nil {
Expand All @@ -252,8 +250,11 @@ func getDefaultValue(defaultValue reflect.Value, defaultPointersValue reflect.Va
} else {
instValue := reflect.New(defaultPointersValue.Type().Elem())
if len(key) != 0 {
defaultValmap[name] = instValue
// fmt.Printf("%s: got default value %+v\n", name, instValue)
if !defaultValue.IsNil() {
defaultValmap[name] = reflect.ValueOf(true)
} else {
defaultValmap[name] = reflect.ValueOf(false)
}
}
if !defaultValue.IsNil() {
if err := getDefaultValue(defaultValue.Elem(), instValue.Elem(), defaultValmap, name); err != nil {
Expand Down Expand Up @@ -296,14 +297,14 @@ func setPointersNil(objValue reflect.Value) (reflect.Value, error) {
}

//FillStructRecursive initialize a value of any taged Struct given by reference
func fillStructRecursive(objValue reflect.Value, defaultPointerValmap map[string]reflect.Value, valmap map[string]Parser, key string) error {
func fillStructRecursive(objValue reflect.Value, defaultPointersValue reflect.Value, defaultValmap map[string]reflect.Value, valmap map[string]Parser, key string) error {
name := key
switch objValue.Kind() {
case reflect.Struct:

for i := 0; i < objValue.Type().NumField(); i++ {
if objValue.Type().Field(i).Anonymous {
if err := fillStructRecursive(objValue.Field(i), defaultPointerValmap, valmap, name); err != nil {
if err := fillStructRecursive(objValue.Field(i), defaultPointersValue.Field(i), defaultValmap, valmap, name); err != nil {
return err
}
} else if len(objValue.Type().Field(i).Tag.Get("description")) > 0 {
Expand All @@ -327,15 +328,15 @@ func fillStructRecursive(objValue reflect.Value, defaultPointerValmap map[string
}
}
}
if err := fillStructRecursive(objValue.Field(i), defaultPointerValmap, valmap, name); err != nil {
if err := fillStructRecursive(objValue.Field(i), defaultPointersValue.Field(i), defaultValmap, valmap, name); err != nil {
return err
}
}
}

case reflect.Ptr:
if len(key) == 0 && !objValue.IsNil() {
if err := fillStructRecursive(objValue.Elem(), defaultPointerValmap, valmap, name); err != nil {
if err := fillStructRecursive(objValue.Elem(), defaultPointersValue.Elem(), defaultValmap, valmap, name); err != nil {
return err
}
return nil
Expand All @@ -357,17 +358,20 @@ func fillStructRecursive(objValue reflect.Value, defaultPointerValmap map[string
}

if needDefault {
if defVal, ok := defaultPointerValmap[name]; ok {
//set default pointer value
// fmt.Printf("%s : set default value %+v\n", name, defVal)
objValue.Set(defVal)
//turn ptr fields to nil
defaultPointersNilValue, err := setPointersNil(defaultPointersValue)
if err != nil {
return fmt.Errorf("Error setting nil pointers to %s: %s", name, err)
}
if defaultPointersNilValue.Kind() == reflect.Bool {
objValue.Set(reflect.New(objValue.Type().Elem()))
} else {
return fmt.Errorf("flag %s default value not provided", name)
objValue.Set(defaultPointersNilValue)
}
}
if !objValue.IsNil() && contains {
if objValue.Type().Elem().Kind() == reflect.Struct {
if err := fillStructRecursive(objValue.Elem(), defaultPointerValmap, valmap, name); err != nil {
if err := fillStructRecursive(objValue.Elem(), defaultPointersValue.Elem(), defaultValmap, valmap, name); err != nil {
return err
}
}
Expand Down Expand Up @@ -458,7 +462,7 @@ func LoadWithCommand(cmd *Command, cmdArgs []string, customParsers map[reflect.T
return PrintErrorWithCommand(errParseArgs, tagsmap, defaultValmap, parsers, cmd, subCommand)
}

if err := fillStructRecursive(reflect.ValueOf(cmd.Config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(cmd.Config), reflect.ValueOf(cmd.DefaultPointersConfig), defaultValmap, valmap, ""); err != nil {
return err
}

Expand Down Expand Up @@ -545,13 +549,14 @@ func printFlagsDescriptionsDefaultValues(flagmap map[string]reflect.StructField,
if defVal, ok := defaultValmap[flag]; ok {
if defVal.Kind() != reflect.Ptr {
// Set defaultValue on parsers
parsers[field.Type].SetValue(defaultValmap[flag].Interface())
}

if defVal := parsers[field.Type].String(); len(defVal) > 0 {
defaultValues = append(defaultValues, fmt.Sprintf("(default \"%s\")", defVal))
parsers[field.Type].SetValue(defVal.Interface())
if defValStr := parsers[field.Type].String(); len(defValStr) > 0 {
defaultValues = append(defaultValues, fmt.Sprintf("(default \"%s\")", defValStr))
} else {
defaultValues = append(defaultValues, "")
}
} else {
defaultValues = append(defaultValues, "")
defaultValues = append(defaultValues, fmt.Sprintf("(default \"%s\")", defVal))
}
}

Expand All @@ -565,6 +570,7 @@ func printFlagsDescriptionsDefaultValues(flagmap map[string]reflect.StructField,
}
}
}

//add help flag
shortFlagsWithDash = append(shortFlagsWithDash, "-h,")
flagsWithDashs = append(flagsWithDashs, "--help")
Expand Down
51 changes: 25 additions & 26 deletions flaeg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,21 +724,19 @@ func TestGetDefaultValueInitConfigAllDefault(t *testing.T) {
t.Fatalf("Error %s", err.Error())
}
//CHECK
checkDefaultStr := "DefaultOwnerNamePointer"
checkDefaultDob, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
checkDob, _ := time.Parse(time.RFC3339, "1993-09-12T07:32:00Z")
checkValue := map[string]reflect.Value{
"loglevel": reflect.ValueOf("DEBUG"),
"timeout": reflect.ValueOf(Duration(time.Second)),
"db": reflect.ValueOf(&DatabaseInfo{ServerInfo: ServerInfo{Watch: true, IP: "192.168.1.2", Load: 32, Load64: 64}, ConnectionMax: 3200000000, ConnectionMax64: 6400000000000000000}),
"db": reflect.ValueOf(false),
"db.watch": reflect.ValueOf(true),
"db.ip": reflect.ValueOf("192.168.1.2"),
"db.load": reflect.ValueOf(32),
"db.load64": reflect.ValueOf(int64(64)),
"db.comax": reflect.ValueOf(uint(3200000000)),
"db.connectionmax64": reflect.ValueOf(uint64(6400000000000000000)),
"owner": reflect.ValueOf(&OwnerInfo{Name: nil, DateOfBirth: checkDefaultDob, Rate: 0.111, Servers: []ServerInfo{ServerInfo{Watch: false, IP: "192.168.1.2", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.3", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.4", Load: 0, Load64: 0}}}),
"owner.name": reflect.ValueOf(&checkDefaultStr),
"owner": reflect.ValueOf(true),
"owner.name": reflect.ValueOf(true),
"owner.dob": reflect.ValueOf(checkDob),
"owner.rate": reflect.ValueOf(float64(0.999)),
"owner.servers": reflect.ValueOf(*new([]ServerInfo)),
Expand Down Expand Up @@ -770,15 +768,15 @@ func TestGetDefaultValueNoConfigNoDefault(t *testing.T) {
checkValue := map[string]reflect.Value{
"loglevel": reflect.ValueOf(""),
"timeout": reflect.ValueOf(Duration(0)),
"db": reflect.ValueOf(&DatabaseInfo{}),
"db": reflect.ValueOf(false),
"db.watch": reflect.ValueOf(false),
"db.ip": reflect.ValueOf(""),
"db.load": reflect.ValueOf(0),
"db.load64": reflect.ValueOf(int64(0)),
"db.comax": reflect.ValueOf(uint(0)),
"db.connectionmax64": reflect.ValueOf(uint64(0)),
"owner": reflect.ValueOf(&OwnerInfo{}),
"owner.name": reflect.ValueOf(new(string)),
"owner": reflect.ValueOf(false),
"owner.name": reflect.ValueOf(false),
"owner.dob": reflect.ValueOf(time.Time{}),
"owner.rate": reflect.ValueOf(float64(0)),
"owner.servers": reflect.ValueOf(*new([]ServerInfo)),
Expand Down Expand Up @@ -812,15 +810,15 @@ func TestGetDefaultValueInitConfigNoDefault(t *testing.T) {
checkValue := map[string]reflect.Value{
"loglevel": reflect.ValueOf(""),
"timeout": reflect.ValueOf(Duration(time.Millisecond)),
"db": reflect.ValueOf(&DatabaseInfo{}),
"db": reflect.ValueOf(false),
"db.watch": reflect.ValueOf(false),
"db.ip": reflect.ValueOf(""),
"db.load": reflect.ValueOf(0),
"db.load64": reflect.ValueOf(int64(0)),
"db.comax": reflect.ValueOf(uint(0)),
"db.connectionmax64": reflect.ValueOf(uint64(0)),
"owner": reflect.ValueOf(&OwnerInfo{}),
"owner.name": reflect.ValueOf(new(string)),
"owner": reflect.ValueOf(false),
"owner.name": reflect.ValueOf(false),
"owner.dob": reflect.ValueOf(time.Time{}),
"owner.rate": reflect.ValueOf(float64(0)),
"owner.servers": reflect.ValueOf(*new([]ServerInfo)),
Expand All @@ -845,20 +843,19 @@ func TestGetDefaultNoConfigAllDefault(t *testing.T) {
if err := getDefaultValue(reflect.ValueOf(config), reflect.ValueOf(defPointerConfig), defaultValmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}
checkStr := "DefaultOwnerNamePointer"
checkDob, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
checkValue := map[string]reflect.Value{
"loglevel": reflect.ValueOf(""),
"timeout": reflect.ValueOf(Duration(time.Duration(0))),
"db": reflect.ValueOf(&DatabaseInfo{ServerInfo: ServerInfo{Watch: true, IP: "192.168.1.2", Load: 32, Load64: 64}, ConnectionMax: 3200000000, ConnectionMax64: 6400000000000000000}),
"db": reflect.ValueOf(false),
"db.watch": reflect.ValueOf(true),
"db.ip": reflect.ValueOf("192.168.1.2"),
"db.load": reflect.ValueOf(32),
"db.load64": reflect.ValueOf(int64(64)),
"db.comax": reflect.ValueOf(uint(3200000000)),
"db.connectionmax64": reflect.ValueOf(uint64(6400000000000000000)),
"owner": reflect.ValueOf(&OwnerInfo{Name: nil, DateOfBirth: checkDob, Rate: 0.111, Servers: []ServerInfo{ServerInfo{Watch: false, IP: "192.168.1.2", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.3", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.4", Load: 0, Load64: 0}}}),
"owner.name": reflect.ValueOf(&checkStr),
"owner": reflect.ValueOf(false),
"owner.name": reflect.ValueOf(true),
"owner.dob": reflect.ValueOf(checkDob),
"owner.rate": reflect.ValueOf(float64(0.111)),
"owner.servers": reflect.ValueOf([]ServerInfo{ServerInfo{Watch: false, IP: "192.168.1.2", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.3", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.4", Load: 0, Load64: 0}}),
Expand Down Expand Up @@ -925,7 +922,7 @@ func TestFillStructRecursiveNoConfigNoDefaultTrivialValmap(t *testing.T) {
}

//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

Expand Down Expand Up @@ -1015,13 +1012,14 @@ func TestFillStructRecursiveNoConfigNoDefaultAllValmap(t *testing.T) {
}

//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

//CHECK
// fmt.Printf("Got : %+v\n", config)
checkDob, _ := time.Parse(time.RFC3339, "2016-04-20T17:39:00Z")
str := "DefaultOwnerNamePointer"
check := &Configuration{
LogLevel: "INFO",
Timeout: Duration(time.Second),
Expand All @@ -1036,7 +1034,7 @@ func TestFillStructRecursiveNoConfigNoDefaultAllValmap(t *testing.T) {
ConnectionMax64: uint64(264),
},
Owner: &OwnerInfo{
Name: new(string),
Name: &str,
DateOfBirth: checkDob,
Rate: float64(0.222),
Servers: []ServerInfo{ServerInfo{IP: "1.0.0.1"}},
Expand Down Expand Up @@ -1098,7 +1096,7 @@ func TestFillStructRecursiveNoConfigAllDefaultNoValmap(t *testing.T) {
"owner.servers": reflect.ValueOf([]ServerInfo{ServerInfo{Watch: false, IP: "192.168.1.2", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.3", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.4", Load: 0, Load64: 0}}),
}
//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

Expand Down Expand Up @@ -1162,7 +1160,7 @@ func TestFillStructRecursiveInitConfigAllDefaultNoValmap(t *testing.T) {
}

//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

Expand Down Expand Up @@ -1233,7 +1231,7 @@ func TestFillStructRecursiveInitConfigAllDefaultPointerValmap(t *testing.T) {
}

//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

Expand Down Expand Up @@ -1320,7 +1318,7 @@ func TestFillStructRecursiveInitConfigAllDefaultPointerUnderPointerValmap(t *tes
}

//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

Expand Down Expand Up @@ -1401,7 +1399,7 @@ func TestFillStructRecursiveNoConfigAllDefaultSomeValmap(t *testing.T) {
"owner.servers": reflect.ValueOf([]ServerInfo{ServerInfo{Watch: false, IP: "192.168.1.2", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.3", Load: 0, Load64: 0}, ServerInfo{Watch: false, IP: "192.168.1.4", Load: 0, Load64: 0}}),
}
//test
if err := fillStructRecursive(reflect.ValueOf(config), defaultValmap, valmap, ""); err != nil {
if err := fillStructRecursive(reflect.ValueOf(config), reflect.ValueOf(newDefaultPointersConfiguration()), defaultValmap, valmap, ""); err != nil {
t.Errorf("Error %s", err.Error())
}

Expand Down Expand Up @@ -1488,7 +1486,7 @@ func TestLoadWithParsersInitConfigNoDefaultAllFlag(t *testing.T) {
//init config
config := newConfiguration()
//init default pointers
defaultPointers := &Configuration{}
defaultPointers := newDefaultPointersConfiguration()
//init custom parsers
customParsers := map[reflect.Type]Parser{
reflect.TypeOf([]ServerInfo{}): &sliceServerValue{},
Expand Down Expand Up @@ -1519,6 +1517,7 @@ func TestLoadWithParsersInitConfigNoDefaultAllFlag(t *testing.T) {
//CHECK
// fmt.Printf("Got : %+v\n", config)
checkDob, _ := time.Parse(time.RFC3339, "2016-04-20T17:39:00Z")
str := "DefaultOwnerNamePointer"
check := &Configuration{
Name: "initName",
LogLevel: "INFO",
Expand All @@ -1534,7 +1533,7 @@ func TestLoadWithParsersInitConfigNoDefaultAllFlag(t *testing.T) {
ConnectionMax64: uint64(264),
},
Owner: &OwnerInfo{
Name: new(string),
Name: &str,
DateOfBirth: checkDob,
Rate: float64(0.222),
Servers: []ServerInfo{ServerInfo{IP: "1.0.0.1"}},
Expand Down Expand Up @@ -2556,7 +2555,7 @@ func TestGetDefaultValueUnexportedFieldUnderPointer(t *testing.T) {
}
//check
checkValue := map[string]reflect.Value{
"ptrsubconfig": reflect.ValueOf(&SubConfigWithUnexportedField{"ExportedSubFieldDefault", nil}),
"ptrsubconfig": reflect.ValueOf(false),
"ptrsubconfig.exported": reflect.ValueOf("ExportedSubFieldDefault"),
}
if len(checkValue) != len(defaultValmap) {
Expand Down