summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Flint <[email protected]>2021-01-31 18:29:22 -0800
committerAlex Flint <[email protected]>2021-01-31 18:29:22 -0800
commitaa6cb95149b650d07de76176d652b7280c86db06 (patch)
treeeb5cf751ccfc98a9cdceb401c80afde1b4f406fe
parentb91c03d2c6c9e6429f3947f6b6e83321a56aa0f2 (diff)
skip unexported fields
-rw-r--r--parse.go2
-rw-r--r--parse_test.go9
-rw-r--r--reflect.go8
-rw-r--r--reflect_test.go7
4 files changed, 25 insertions, 1 deletions
diff --git a/parse.go b/parse.go
index 8fdbd9d..0c65397 100644
--- a/parse.go
+++ b/parse.go
@@ -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
}
diff --git a/parse_test.go b/parse_test.go
index ad668a9..a0334c7 100644
--- a/parse_test.go
+++ b/parse_test.go
@@ -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)
+}
diff --git a/reflect.go b/reflect.go
index e113583..f1e8e8d 100644
--- a/reflect.go
+++ b/reflect.go
@@ -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)
+}
diff --git a/reflect_test.go b/reflect_test.go
index 47e68b5..07b459c 100644
--- a/reflect_test.go
+++ b/reflect_test.go
@@ -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})))
+}