Skip to content

Commit dacd357

Browse files
knight42claude
andauthored
feat: handle Kubernetes List objects in local/stdin input (#43)
When piping `kubectl get` output (which wraps resources in a `kind: List` object), `visitLocalObjects` would fail because the List itself has no `managedFields`. Now checks `obj.IsList()` and iterates through items. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4d0c18a commit dacd357

File tree

5 files changed

+663
-3
lines changed

5 files changed

+663
-3
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ to show who last modified the field.
1111
As long as the field `.metadata.manageFields` of the resource is set properly, this command
1212
is able to display the manager of each field.
1313

14+
`kubectl-blame` can work in two ways:
15+
16+
1. **Directly from the cluster** — fetch and blame resources in one step:
17+
```
18+
kubectl blame deployments my-app
19+
```
20+
2. **From piped input** — use `kubectl get` (or any command that outputs YAML/JSON) and pipe the result:
21+
```
22+
kubectl get deployments -o yaml | kubectl blame
23+
```
24+
This also works with Kubernetes List objects (e.g., `kind: List`), so you can pipe the output of `kubectl get` which wraps multiple resources in a List.
25+
1426
[![asciicast](https://asciinema.org/a/375008.svg)](https://asciinema.org/a/375008)
1527

1628
## Installing

cmd/blame.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,21 @@ func (o *Options) visitLocalObjects(visit func(object metav1.Object) error) erro
122122
}
123123
return err
124124
}
125-
err = visit(obj)
126-
if err != nil {
127-
return err
125+
if obj.IsList() {
126+
list, err := obj.ToList()
127+
if err != nil {
128+
return err
129+
}
130+
for i := range list.Items {
131+
if err := visit(&list.Items[i]); err != nil {
132+
return err
133+
}
134+
}
135+
} else {
136+
err = visit(obj)
137+
if err != nil {
138+
return err
139+
}
128140
}
129141
}
130142
return nil

cmd/blame_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ func TestBlameLocalFile(t *testing.T) {
5555
"multi-manager-list-item": {
5656
inputFile: "multi-manager-list-item.yaml",
5757
},
58+
"list": {
59+
inputFile: "list.yaml",
60+
},
5861
}
5962
for name, tc := range testCases {
6063
t.Run(name, func(t *testing.T) {

0 commit comments

Comments
 (0)