kubectl-diff-watch is a kubectl plugin written in Go that watches Kubernetes resources and displays colored diffs when they change. It uses the Kubernetes dynamic client (client-go) directly — no shell-outs.
.
├── main.go # CLI entry point (cobra), flag parsing
├── pkg/
│ ├── diff/
│ │ ├── diff.go # Differ interface + factory function
│ │ ├── color.go # Colored unified diff (default output)
│ │ ├── dyff.go # dyff structural diff output
│ │ └── simple.go # Plain text unified diff (no color)
│ └── watch/
│ └── watcher.go # Kubernetes watcher using dynamic informers
├── tests/
│ └── integration_test.go # Integration tests using envtest
├── go.mod
├── go.sum
├── .gitignore
└── README.md
- No shell-outs: Everything is done in Go — Kubernetes API access via client-go, diff computation via go-difflib, structural diff via dyff library.
- No cli-runtime/genericclioptions: We only expose
--kubeconfig,--context,--namespaceinstead of the full set of 20+ kubectl flags. Config is built usingclient-go/tools/clientcmddirectly. - Pluggable diff output: The
diff.Differinterface allows adding new output formats easily. Currently:diff(colored unified diff, default) anddyff(structural). Color can be disabled with--no-color. - Clean diffs by default:
managedFields,resourceVersion,generation, andobservedGenerationare stripped before diffing to reduce noise. - Informer-based watch: Uses
dynamicinformerwhich handles reconnection and bookmarks automatically. - RestConfig injection for tests: The
watch.Configstruct accepts a pre-built*rest.Configso tests can use envtest without writing kubeconfig files.
go build -o kubectl-diff-watch .Tests require envtest binaries (kube-apiserver + etcd):
KUBEBUILDER_ASSETS="$(setup-envtest use --print path)" go test -v -timeout 120s ./tests/- Create a new file
pkg/diff/myformat.go - Implement the
diff.Differinterface (Diff(w io.Writer, header string, old, new string) error) - Register it in the
New()factory inpkg/diff/diff.go - Add it to the
--outputflag description inmain.go
KUBECONFIG— handled natively by client-go's loading rulesKUBECONTEXT— falls back when--contextflag is not setKUBENAMESPACE— falls back when--namespaceflag is not set
github.com/spf13/cobra— CLI frameworkgithub.com/pmezard/go-difflib— unified diff computationgithub.com/mgutz/ansi— ANSI color codesgithub.com/homeport/dyff+github.com/gonvenience/ytbx— structural YAML diffk8s.io/client-go— Kubernetes client (dynamic, discovery, informers)k8s.io/apimachinery— Kubernetes API typessigs.k8s.io/yaml— YAML marshalingsigs.k8s.io/controller-runtime— envtest (test dependency only)