Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
de146237
Commit
de146237
authored
Aug 13, 2015
by
Brendan Burns
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a printer that knows how to print user-defined columns
parent
ab738494
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
302 additions
and
35 deletions
+302
-35
custom_column_printer.go
pkg/kubectl/custom_column_printer.go
+107
-0
custom_column_printer_test.go
pkg/kubectl/custom_column_printer_test.go
+93
-0
resource_printer.go
pkg/kubectl/resource_printer.go
+18
-11
resource_printer_test.go
pkg/kubectl/resource_printer_test.go
+10
-1
sorting_printer.go
pkg/kubectl/sorting_printer.go
+20
-12
sorting_printer_test.go
pkg/kubectl/sorting_printer_test.go
+12
-10
jsonpath.go
pkg/util/jsonpath/jsonpath.go
+42
-1
No files found.
pkg/kubectl/custom_column_printer.go
0 → 100644
View file @
de146237
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
kubectl
import
(
"fmt"
"io"
"reflect"
"strings"
"text/tabwriter"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/jsonpath"
)
const
(
columnwidth
=
10
tabwidth
=
4
padding
=
3
padding_character
=
' '
flags
=
0
)
// Column represents a user specified column
type
Column
struct
{
// The header to print above the column, general style is ALL_CAPS
Header
string
// The pointer to the field in the object to print in JSONPath form
// e.g. {.ObjectMeta.Name}, see pkg/util/jsonpath for more details.
FieldSpec
string
}
// CustomColumnPrinter is a printer that knows how to print arbitrary columns
// of data from templates specified in the `Columns` array
type
CustomColumnsPrinter
struct
{
Columns
[]
Column
}
func
(
s
*
CustomColumnsPrinter
)
PrintObj
(
obj
runtime
.
Object
,
out
io
.
Writer
)
error
{
w
:=
tabwriter
.
NewWriter
(
out
,
columnwidth
,
tabwidth
,
padding
,
padding_character
,
flags
)
headers
:=
make
([]
string
,
len
(
s
.
Columns
))
for
ix
:=
range
s
.
Columns
{
headers
[
ix
]
=
s
.
Columns
[
ix
]
.
Header
}
fmt
.
Fprintln
(
w
,
strings
.
Join
(
headers
,
"
\t
"
))
parsers
:=
make
([]
*
jsonpath
.
JSONPath
,
len
(
s
.
Columns
))
for
ix
:=
range
s
.
Columns
{
parsers
[
ix
]
=
jsonpath
.
New
(
fmt
.
Sprintf
(
"column%d"
,
ix
))
if
err
:=
parsers
[
ix
]
.
Parse
(
s
.
Columns
[
ix
]
.
FieldSpec
);
err
!=
nil
{
return
err
}
}
if
runtime
.
IsListType
(
obj
)
{
objs
,
err
:=
runtime
.
ExtractList
(
obj
)
if
err
!=
nil
{
return
err
}
for
ix
:=
range
objs
{
if
err
:=
s
.
printOneObject
(
objs
[
ix
],
parsers
,
w
);
err
!=
nil
{
return
err
}
}
}
else
{
if
err
:=
s
.
printOneObject
(
obj
,
parsers
,
w
);
err
!=
nil
{
return
err
}
}
return
w
.
Flush
()
}
func
(
s
*
CustomColumnsPrinter
)
printOneObject
(
obj
runtime
.
Object
,
parsers
[]
*
jsonpath
.
JSONPath
,
out
io
.
Writer
)
error
{
columns
:=
make
([]
string
,
len
(
parsers
))
for
ix
:=
range
parsers
{
parser
:=
parsers
[
ix
]
values
,
err
:=
parser
.
FindResults
(
reflect
.
ValueOf
(
obj
)
.
Elem
()
.
Interface
())
if
err
!=
nil
{
return
err
}
if
len
(
values
)
==
0
||
len
(
values
[
0
])
==
0
{
fmt
.
Fprintf
(
out
,
"<none>
\t
"
)
}
valueStrings
:=
[]
string
{}
for
arrIx
:=
range
values
{
for
valIx
:=
range
values
[
arrIx
]
{
valueStrings
=
append
(
valueStrings
,
fmt
.
Sprintf
(
"%v"
,
values
[
arrIx
][
valIx
]
.
Interface
()))
}
}
columns
[
ix
]
=
strings
.
Join
(
valueStrings
,
","
)
}
fmt
.
Fprintln
(
out
,
strings
.
Join
(
columns
,
"
\t
"
))
return
nil
}
pkg/kubectl/custom_column_printer_test.go
0 → 100644
View file @
de146237
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
kubectl
import
(
"bytes"
"testing"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
)
func
TestColumnPrint
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
columns
[]
Column
obj
runtime
.
Object
expectedOutput
string
}{
{
columns
:
[]
Column
{
{
Header
:
"NAME"
,
FieldSpec
:
"{.metadata.name}"
,
},
},
obj
:
&
v1
.
Pod
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
"foo"
}},
expectedOutput
:
`NAME
foo
`
,
},
{
columns
:
[]
Column
{
{
Header
:
"NAME"
,
FieldSpec
:
"{.metadata.name}"
,
},
},
obj
:
&
v1
.
PodList
{
Items
:
[]
v1
.
Pod
{
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
"foo"
}},
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
"bar"
}},
},
},
expectedOutput
:
`NAME
foo
bar
`
,
},
{
columns
:
[]
Column
{
{
Header
:
"NAME"
,
FieldSpec
:
"{.metadata.name}"
,
},
{
Header
:
"API_VERSION"
,
FieldSpec
:
"{.apiVersion}"
,
},
},
obj
:
&
v1
.
Pod
{
ObjectMeta
:
v1
.
ObjectMeta
{
Name
:
"foo"
},
TypeMeta
:
v1
.
TypeMeta
{
APIVersion
:
"baz"
}},
expectedOutput
:
`NAME API_VERSION
foo baz
`
,
},
}
for
_
,
test
:=
range
tests
{
printer
:=
&
CustomColumnsPrinter
{
Columns
:
test
.
columns
,
}
buffer
:=
&
bytes
.
Buffer
{}
if
err
:=
printer
.
PrintObj
(
test
.
obj
,
buffer
);
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
if
buffer
.
String
()
!=
test
.
expectedOutput
{
t
.
Errorf
(
"
\n
expected:
\n
'%s'
\n
saw
\n
'%s'
\n
"
,
test
.
expectedOutput
,
buffer
.
String
())
}
}
}
pkg/kubectl/resource_printer.go
View file @
de146237
...
@@ -34,6 +34,7 @@ import (
...
@@ -34,6 +34,7 @@ import (
"github.com/golang/glog"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/expapi"
"k8s.io/kubernetes/pkg/expapi"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/labels"
...
@@ -1335,20 +1336,26 @@ func NewJSONPathPrinter(tmpl string) (*JSONPathPrinter, error) {
...
@@ -1335,20 +1336,26 @@ func NewJSONPathPrinter(tmpl string) (*JSONPathPrinter, error) {
// PrintObj formats the obj with the JSONPath Template.
// PrintObj formats the obj with the JSONPath Template.
func
(
j
*
JSONPathPrinter
)
PrintObj
(
obj
runtime
.
Object
,
w
io
.
Writer
)
error
{
func
(
j
*
JSONPathPrinter
)
PrintObj
(
obj
runtime
.
Object
,
w
io
.
Writer
)
error
{
data
,
err
:=
json
.
Marshal
(
obj
)
var
queryObj
interface
{}
if
err
!=
nil
{
switch
obj
.
(
type
)
{
return
err
case
*
v1
.
List
,
*
api
.
List
:
}
data
,
err
:=
json
.
Marshal
(
obj
)
out
:=
map
[
string
]
interface
{}{}
if
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
data
,
&
out
);
err
!=
nil
{
return
err
return
err
}
queryObj
=
map
[
string
]
interface
{}{}
if
err
:=
json
.
Unmarshal
(
data
,
&
queryObj
);
err
!=
nil
{
return
err
}
default
:
queryObj
=
obj
}
}
if
err
=
j
.
JSONPath
.
Execute
(
w
,
out
);
err
!=
nil
{
if
err
:=
j
.
JSONPath
.
Execute
(
w
,
queryObj
);
err
!=
nil
{
fmt
.
Fprintf
(
w
,
"Error executing template: %v
\n
"
,
err
)
fmt
.
Fprintf
(
w
,
"Error executing template: %v
\n
"
,
err
)
fmt
.
Fprintf
(
w
,
"template was:
\n\t
%v
\n
"
,
j
.
rawTemplate
)
fmt
.
Fprintf
(
w
,
"template was:
\n\t
%v
\n
"
,
j
.
rawTemplate
)
fmt
.
Fprintf
(
w
,
"raw data was:
\n\t
%v
\n
"
,
string
(
data
))
fmt
.
Fprintf
(
w
,
"object given to jsonpath engine was:
\n\t
%#v
\n
"
,
queryObj
)
fmt
.
Fprintf
(
w
,
"object given to template engine was:
\n\t
%+v
\n
"
,
out
)
return
fmt
.
Errorf
(
"error executing jsonpath '%v': '%v'
\n
----data----
\n
%+v
\n
"
,
j
.
rawTemplate
,
err
,
obj
)
return
fmt
.
Errorf
(
"error executing jsonpath '%v': '%v'
\n
----data----
\n
%+v
\n
"
,
j
.
rawTemplate
,
err
,
out
)
}
}
return
nil
return
nil
}
}
pkg/kubectl/resource_printer_test.go
View file @
de146237
...
@@ -102,6 +102,13 @@ func TestPrinter(t *testing.T) {
...
@@ -102,6 +102,13 @@ func TestPrinter(t *testing.T) {
//test inputs
//test inputs
simpleTest
:=
&
TestPrintType
{
"foo"
}
simpleTest
:=
&
TestPrintType
{
"foo"
}
podTest
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
}}
podTest
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
}}
podListTest
:=
&
api
.
PodList
{
Items
:
[]
api
.
Pod
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"foo"
}},
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"bar"
}},
},
}
emptyListTest
:=
&
api
.
PodList
{}
testapi
,
err
:=
api
.
Scheme
.
ConvertToVersion
(
podTest
,
testapi
.
Version
())
testapi
,
err
:=
api
.
Scheme
.
ConvertToVersion
(
podTest
,
testapi
.
Version
())
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
...
@@ -119,6 +126,8 @@ func TestPrinter(t *testing.T) {
...
@@ -119,6 +126,8 @@ func TestPrinter(t *testing.T) {
{
"test template"
,
"template"
,
"{{if .id}}{{.id}}{{end}}{{if .metadata.name}}{{.metadata.name}}{{end}}"
,
{
"test template"
,
"template"
,
"{{if .id}}{{.id}}{{end}}{{if .metadata.name}}{{.metadata.name}}{{end}}"
,
podTest
,
"foo"
},
podTest
,
"foo"
},
{
"test jsonpath"
,
"jsonpath"
,
"{.metadata.name}"
,
podTest
,
"foo"
},
{
"test jsonpath"
,
"jsonpath"
,
"{.metadata.name}"
,
podTest
,
"foo"
},
{
"test jsonpath list"
,
"jsonpath"
,
"{.items[*].metadata.name}"
,
podListTest
,
"foo bar"
},
{
"test jsonpath empty list"
,
"jsonpath"
,
"{.items[*].metadata.name}"
,
emptyListTest
,
""
},
{
"test name"
,
"name"
,
""
,
podTest
,
"/foo
\n
"
},
{
"test name"
,
"name"
,
""
,
podTest
,
"/foo
\n
"
},
{
"emits versioned objects"
,
"template"
,
"{{.kind}}"
,
testapi
,
"Pod"
},
{
"emits versioned objects"
,
"template"
,
"{{.kind}}"
,
testapi
,
"Pod"
},
}
}
...
@@ -132,7 +141,7 @@ func TestPrinter(t *testing.T) {
...
@@ -132,7 +141,7 @@ func TestPrinter(t *testing.T) {
t
.
Errorf
(
"unexpected error: %#v"
,
err
)
t
.
Errorf
(
"unexpected error: %#v"
,
err
)
}
}
if
buf
.
String
()
!=
test
.
Expect
{
if
buf
.
String
()
!=
test
.
Expect
{
t
.
Errorf
(
"in %s, expect %q, got %q"
,
test
.
Name
,
test
.
Expect
,
buf
.
String
()
,
buf
.
String
()
)
t
.
Errorf
(
"in %s, expect %q, got %q"
,
test
.
Name
,
test
.
Expect
,
buf
.
String
())
}
}
}
}
...
...
pkg/kubectl/sorting_printer.go
View file @
de146237
...
@@ -87,6 +87,23 @@ func (r *RuntimeSort) Swap(i, j int) {
...
@@ -87,6 +87,23 @@ func (r *RuntimeSort) Swap(i, j int) {
r
.
objs
[
i
],
r
.
objs
[
j
]
=
r
.
objs
[
j
],
r
.
objs
[
i
]
r
.
objs
[
i
],
r
.
objs
[
j
]
=
r
.
objs
[
j
],
r
.
objs
[
i
]
}
}
func
isLess
(
i
,
j
reflect
.
Value
)
(
bool
,
error
)
{
switch
i
.
Kind
()
{
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
return
i
.
Int
()
<
j
.
Int
(),
nil
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
:
return
i
.
Uint
()
<
j
.
Uint
(),
nil
case
reflect
.
Float32
,
reflect
.
Float64
:
return
i
.
Float
()
<
j
.
Float
(),
nil
case
reflect
.
String
:
return
i
.
String
()
<
j
.
String
(),
nil
case
reflect
.
Ptr
:
return
isLess
(
i
.
Elem
(),
j
.
Elem
())
default
:
return
false
,
fmt
.
Errorf
(
"unsortable type: %v"
,
i
.
Kind
())
}
}
func
(
r
*
RuntimeSort
)
Less
(
i
,
j
int
)
bool
{
func
(
r
*
RuntimeSort
)
Less
(
i
,
j
int
)
bool
{
iObj
:=
r
.
objs
[
i
]
iObj
:=
r
.
objs
[
i
]
jObj
:=
r
.
objs
[
j
]
jObj
:=
r
.
objs
[
j
]
...
@@ -106,18 +123,9 @@ func (r *RuntimeSort) Less(i, j int) bool {
...
@@ -106,18 +123,9 @@ func (r *RuntimeSort) Less(i, j int) bool {
iField
:=
iValues
[
0
][
0
]
iField
:=
iValues
[
0
][
0
]
jField
:=
jValues
[
0
][
0
]
jField
:=
jValues
[
0
][
0
]
switch
iField
.
Kind
()
{
less
,
err
:=
isLess
(
iField
,
jField
)
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
if
err
!=
nil
{
return
iField
.
Int
()
<
jField
.
Int
()
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
:
return
iField
.
Uint
()
<
jField
.
Uint
()
case
reflect
.
Float32
,
reflect
.
Float64
:
return
iField
.
Float
()
<
jField
.
Float
()
case
reflect
.
String
:
return
iField
.
String
()
<
jField
.
String
()
default
:
glog
.
Fatalf
(
"Field %s in %v is an unsortable type: %s"
,
r
.
field
,
iObj
,
iField
.
Kind
()
.
String
())
glog
.
Fatalf
(
"Field %s in %v is an unsortable type: %s"
,
r
.
field
,
iObj
,
iField
.
Kind
()
.
String
())
}
}
// default to preserving order
return
less
return
i
<
j
}
}
pkg/kubectl/sorting_printer_test.go
View file @
de146237
...
@@ -20,11 +20,13 @@ import (
...
@@ -20,11 +20,13 @@ import (
"reflect"
"reflect"
"testing"
"testing"
"k8s.io/kubernetes/pkg/api
"
api
"k8s.io/kubernetes/pkg/api/v1
"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
)
)
func
TestSortingPrinter
(
t
*
testing
.
T
)
{
func
TestSortingPrinter
(
t
*
testing
.
T
)
{
intPtr
:=
func
(
val
int
)
*
int
{
return
&
val
}
tests
:=
[]
struct
{
tests
:=
[]
struct
{
obj
runtime
.
Object
obj
runtime
.
Object
sort
runtime
.
Object
sort
runtime
.
Object
...
@@ -71,7 +73,7 @@ func TestSortingPrinter(t *testing.T) {
...
@@ -71,7 +73,7 @@ func TestSortingPrinter(t *testing.T) {
},
},
},
},
},
},
field
:
"{.
ObjectMeta.N
ame}"
,
field
:
"{.
metadata.n
ame}"
,
},
},
{
{
name
:
"reverse-order"
,
name
:
"reverse-order"
,
...
@@ -113,7 +115,7 @@ func TestSortingPrinter(t *testing.T) {
...
@@ -113,7 +115,7 @@ func TestSortingPrinter(t *testing.T) {
},
},
},
},
},
},
field
:
"{.
ObjectMeta.N
ame}"
,
field
:
"{.
metadata.n
ame}"
,
},
},
{
{
name
:
"random-order-numbers"
,
name
:
"random-order-numbers"
,
...
@@ -121,17 +123,17 @@ func TestSortingPrinter(t *testing.T) {
...
@@ -121,17 +123,17 @@ func TestSortingPrinter(t *testing.T) {
Items
:
[]
api
.
ReplicationController
{
Items
:
[]
api
.
ReplicationController
{
{
{
Spec
:
api
.
ReplicationControllerSpec
{
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
5
,
Replicas
:
intPtr
(
5
)
,
},
},
},
},
{
{
Spec
:
api
.
ReplicationControllerSpec
{
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
1
,
Replicas
:
intPtr
(
1
)
,
},
},
},
},
{
{
Spec
:
api
.
ReplicationControllerSpec
{
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
9
,
Replicas
:
intPtr
(
9
)
,
},
},
},
},
},
},
...
@@ -140,22 +142,22 @@ func TestSortingPrinter(t *testing.T) {
...
@@ -140,22 +142,22 @@ func TestSortingPrinter(t *testing.T) {
Items
:
[]
api
.
ReplicationController
{
Items
:
[]
api
.
ReplicationController
{
{
{
Spec
:
api
.
ReplicationControllerSpec
{
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
1
,
Replicas
:
intPtr
(
1
)
,
},
},
},
},
{
{
Spec
:
api
.
ReplicationControllerSpec
{
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
5
,
Replicas
:
intPtr
(
5
)
,
},
},
},
},
{
{
Spec
:
api
.
ReplicationControllerSpec
{
Spec
:
api
.
ReplicationControllerSpec
{
Replicas
:
9
,
Replicas
:
intPtr
(
9
)
,
},
},
},
},
},
},
},
},
field
:
"{.
Spec.R
eplicas}"
,
field
:
"{.
spec.r
eplicas}"
,
},
},
}
}
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
...
...
pkg/util/jsonpath/jsonpath.go
View file @
de146237
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"fmt"
"fmt"
"io"
"io"
"reflect"
"reflect"
"strings"
"k8s.io/kubernetes/third_party/golang/template"
"k8s.io/kubernetes/third_party/golang/template"
)
)
...
@@ -258,9 +259,46 @@ func (j *JSONPath) evalUnion(input []reflect.Value, node *UnionNode) ([]reflect.
...
@@ -258,9 +259,46 @@ func (j *JSONPath) evalUnion(input []reflect.Value, node *UnionNode) ([]reflect.
return
result
,
nil
return
result
,
nil
}
}
func
(
j
*
JSONPath
)
findFieldInValue
(
value
*
reflect
.
Value
,
node
*
FieldNode
)
(
reflect
.
Value
,
error
)
{
t
:=
value
.
Type
()
var
inlineValue
*
reflect
.
Value
for
ix
:=
0
;
ix
<
t
.
NumField
();
ix
++
{
f
:=
t
.
Field
(
ix
)
jsonTag
:=
f
.
Tag
.
Get
(
"json"
)
parts
:=
strings
.
Split
(
jsonTag
,
","
)
if
len
(
parts
)
==
0
{
continue
}
if
parts
[
0
]
==
node
.
Value
{
return
value
.
Field
(
ix
),
nil
}
if
len
(
parts
[
0
])
==
0
{
val
:=
value
.
Field
(
ix
)
inlineValue
=
&
val
}
}
if
inlineValue
!=
nil
{
if
inlineValue
.
Kind
()
==
reflect
.
Struct
{
// handle 'inline'
match
,
err
:=
j
.
findFieldInValue
(
inlineValue
,
node
)
if
err
!=
nil
{
return
reflect
.
Value
{},
err
}
if
match
.
IsValid
()
{
return
match
,
nil
}
}
}
return
value
.
FieldByName
(
node
.
Value
),
nil
}
// evalField evaluates filed of struct or key of map.
// evalField evaluates filed of struct or key of map.
func
(
j
*
JSONPath
)
evalField
(
input
[]
reflect
.
Value
,
node
*
FieldNode
)
([]
reflect
.
Value
,
error
)
{
func
(
j
*
JSONPath
)
evalField
(
input
[]
reflect
.
Value
,
node
*
FieldNode
)
([]
reflect
.
Value
,
error
)
{
results
:=
[]
reflect
.
Value
{}
results
:=
[]
reflect
.
Value
{}
// If there's no input, there's no output
if
len
(
input
)
==
0
{
return
results
,
nil
}
for
_
,
value
:=
range
input
{
for
_
,
value
:=
range
input
{
var
result
reflect
.
Value
var
result
reflect
.
Value
value
,
isNil
:=
template
.
Indirect
(
value
)
value
,
isNil
:=
template
.
Indirect
(
value
)
...
@@ -269,7 +307,10 @@ func (j *JSONPath) evalField(input []reflect.Value, node *FieldNode) ([]reflect.
...
@@ -269,7 +307,10 @@ func (j *JSONPath) evalField(input []reflect.Value, node *FieldNode) ([]reflect.
}
}
if
value
.
Kind
()
==
reflect
.
Struct
{
if
value
.
Kind
()
==
reflect
.
Struct
{
result
=
value
.
FieldByName
(
node
.
Value
)
var
err
error
if
result
,
err
=
j
.
findFieldInValue
(
&
value
,
node
);
err
!=
nil
{
return
nil
,
err
}
}
else
if
value
.
Kind
()
==
reflect
.
Map
{
}
else
if
value
.
Kind
()
==
reflect
.
Map
{
result
=
value
.
MapIndex
(
reflect
.
ValueOf
(
node
.
Value
))
result
=
value
.
MapIndex
(
reflect
.
ValueOf
(
node
.
Value
))
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment