From 69c3729413e744aa8c952fb44a9228b2600da1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Wed, 12 Aug 2026 19:01:19 +0200 Subject: [PATCH 1/4] feat: omit 'app.kubernetes.io/managed-by' label on three-way-diff --- manifest/util.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/manifest/util.go b/manifest/util.go index 88b818af..34909f3e 100644 --- a/manifest/util.go +++ b/manifest/util.go @@ -35,6 +35,15 @@ func deleteStatusAndTidyMetadata(obj []byte) (map[string]interface{}, error) { delete(metadata, "annotations") } } + + if a := metadata["labels"]; a != nil { + labels := a.(map[string]interface{}) + delete(labels, "app.kubernetes.io/managed-by") + + if len(annotations) == 0 { + delete(labels, "annotations") + } + } return objectMap, nil } From 0993464e6acb999b28469c05d184a3628f3f1b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Wed, 12 Aug 2026 19:03:26 +0200 Subject: [PATCH 2/4] Remove labels if empty in util.go --- manifest/util.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest/util.go b/manifest/util.go index 34909f3e..d5e612de 100644 --- a/manifest/util.go +++ b/manifest/util.go @@ -40,8 +40,8 @@ func deleteStatusAndTidyMetadata(obj []byte) (map[string]interface{}, error) { labels := a.(map[string]interface{}) delete(labels, "app.kubernetes.io/managed-by") - if len(annotations) == 0 { - delete(labels, "annotations") + if len(labels) == 0 { + delete(metadata, "labels") } } From bb7c05e8101d9a0a106df5c694f5e97eb1fa8dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Wed, 12 Aug 2026 20:26:07 +0200 Subject: [PATCH 3/4] Update util.go --- manifest/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest/util.go b/manifest/util.go index d5e612de..95663e50 100644 --- a/manifest/util.go +++ b/manifest/util.go @@ -35,7 +35,7 @@ func deleteStatusAndTidyMetadata(obj []byte) (map[string]interface{}, error) { delete(metadata, "annotations") } } - + if a := metadata["labels"]; a != nil { labels := a.(map[string]interface{}) delete(labels, "app.kubernetes.io/managed-by") From 0be130c3f400fc5765c310439b0375123fc22978 Mon Sep 17 00:00:00 2001 From: yxxhero Date: Thu, 13 Aug 2026 07:26:04 +0800 Subject: [PATCH 4/4] refactor: avoid nested if for annotations/labels tidy Address review feedback to not use 'if in if'. Extract a deleteFromMap helper that uses a comma-ok type assertion (early return) and a final empty-check, so the two conditionals are sequential rather than nested. Apply it to both the existing annotations tidy and the new labels tidy (omitting app.kubernetes.io/managed-by) for consistency. Also add test coverage for label omission and the empty-label cleanup path. Signed-off-by: yxxhero --- manifest/util.go | 39 ++++++++++++++++++++++----------------- manifest/util_test.go | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/manifest/util.go b/manifest/util.go index 95663e50..96a1368a 100644 --- a/manifest/util.go +++ b/manifest/util.go @@ -25,25 +25,30 @@ func deleteStatusAndTidyMetadata(obj []byte) (map[string]interface{}, error) { // See the below for the goal of this metadata tidy logic. // https://github.com/databus23/helm-diff/issues/326#issuecomment-1008253274 - if a := metadata["annotations"]; a != nil { - annotations := a.(map[string]interface{}) - delete(annotations, "meta.helm.sh/release-name") - delete(annotations, "meta.helm.sh/release-namespace") - delete(annotations, "deployment.kubernetes.io/revision") - - if len(annotations) == 0 { - delete(metadata, "annotations") - } - } + pruneNestedMap(metadata, "annotations", + "meta.helm.sh/release-name", + "meta.helm.sh/release-namespace", + "deployment.kubernetes.io/revision", + ) + pruneNestedMap(metadata, "labels", "app.kubernetes.io/managed-by") - if a := metadata["labels"]; a != nil { - labels := a.(map[string]interface{}) - delete(labels, "app.kubernetes.io/managed-by") + return objectMap, nil +} - if len(labels) == 0 { - delete(metadata, "labels") - } +// pruneNestedMap removes the given fields from the nested map found at key in +// target. If the nested map ends up empty afterwards, key itself is removed +// from target. +func pruneNestedMap(target map[string]interface{}, key string, fields ...string) { + sub, ok := target[key].(map[string]interface{}) + if !ok { + return } - return objectMap, nil + for _, field := range fields { + delete(sub, field) + } + + if len(sub) == 0 { + delete(target, key) + } } diff --git a/manifest/util_test.go b/manifest/util_test.go index 0f86223a..6e344366 100644 --- a/manifest/util_test.go +++ b/manifest/util_test.go @@ -28,12 +28,16 @@ func Test_deleteStatusAndTidyMetadata(t *testing.T) { "metadata": { "annotations": { "deployment.kubernetes.io/revision": "1", - "meta.helm.sh/release-name": "test-release", - "meta.helm.sh/release-namespace": "test-ns", - "other-annot": "value" + "meta.helm.sh/release-name": "test-release", + "meta.helm.sh/release-namespace": "test-ns", + "other-annot": "value" }, "creationTimestamp": "2025-03-03T10:07:50Z", "generation": 1, + "labels": { + "app": "nginx", + "app.kubernetes.io/managed-by": "Helm" + }, "name": "nginx-deployment", "namespace": "test-ns", "resourceVersion": "33648", @@ -64,6 +68,9 @@ func Test_deleteStatusAndTidyMetadata(t *testing.T) { "annotations": map[string]interface{}{ "other-annot": "value", }, + "labels": map[string]interface{}{ + "app": "nginx", + }, "name": "nginx-deployment", "namespace": "test-ns", }, @@ -83,6 +90,27 @@ func Test_deleteStatusAndTidyMetadata(t *testing.T) { }, wantErr: false, }, + { + name: "empty labels are removed", + obj: []byte(` +{ + "kind": "ConfigMap", + "metadata": { + "labels": { + "app.kubernetes.io/managed-by": "Helm" + }, + "name": "example" + } +} +`), + want: map[string]interface{}{ + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": "example", + }, + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {