skip unexported fields

This commit is contained in:
Alex Flint 2021-01-31 18:29:22 -08:00
parent b91c03d2c6
commit aa6cb95149
4 changed files with 25 additions and 1 deletions

View File

@ -263,7 +263,7 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) {
walkFields(t, func(field reflect.StructField, t reflect.Type) bool {
// Check for the ignore switch in the tag
tag := field.Tag.Get("arg")
if tag == "-" {
if tag == "-" || !isExported(field.Name) {
return false
}

View File

@ -1213,3 +1213,12 @@ func TestDefaultValuesNotAllowedWithSlice(t *testing.T) {
err := parse("", &args)
assert.EqualError(t, err, ".A: default values are not supported for slice fields")
}
func TestUnexportedFieldsSkipped(t *testing.T) {
var args struct {
unexported struct{}
}
_, err := NewParser(Config{}, &args)
require.NoError(t, err)
}

View File

@ -3,6 +3,8 @@ package arg
import (
"encoding"
"reflect"
"unicode"
"unicode/utf8"
scalar "github.com/alexflint/go-scalar"
)
@ -60,3 +62,9 @@ func isBoolean(t reflect.Type) bool {
return false
}
}
// isExported returns true if the struct field name is exported
func isExported(field string) bool {
r, _ := utf8.DecodeRuneInString(field) // returns RuneError for empty string or invalid UTF8
return unicode.IsLetter(r) && unicode.IsUpper(r)
}

View File

@ -53,3 +53,10 @@ func TestCanParseTextUnmarshaler(t *testing.T) {
assertCanParse(t, reflect.TypeOf(su), true, false, true)
assertCanParse(t, reflect.TypeOf(&su), true, false, true)
}
func TestIsExported(t *testing.T) {
assert.True(t, isExported("Exported"))
assert.False(t, isExported("notExported"))
assert.False(t, isExported(""))
assert.False(t, isExported(string([]byte{255})))
}