Files
Timofei Larkin ffd10e99f1 [platform] Add alphabetical sorting to registry resource lists (#1764)
## What this PR does

Adds deterministic alphabetical sorting to all registry resource lists:
- TenantNamespace (sorted by name)
- TenantSecret (sorted by namespace/name)
- TenantModule (sorted by namespace/name)
- Application (sorted by namespace/name)

Introduces a new `pkg/registry/sorting` package with generic helper
functions
to avoid code duplication.

Also fixes pre-existing linter errors:
- Unused `helmReleaseGVR` variables
- Non-constant format strings in `klog.Errorf` calls
- Redundant embedded field selectors

### Release note

```release-note
[platform] Registry resource lists are now returned in alphabetical order
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a reusable alphabetical sorting utility and applied consistent
sorting across list endpoints.

* **Bug Fixes**
* Ensured ResourceVersion/UID are sourced correctly for accurate
list/table responses.
* Simplified and improved error logging and table ResourceVersion
handling.
  * Made schema defaulting behavior more consistent.

* **Tests**
* Added unit tests validating alphabetical sorting for multiple resource
types.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-09 14:53:58 +01:00

48 lines
1.1 KiB
Go

// SPDX-License-Identifier: Apache-2.0
// Package sorting provides generic sorting utilities for registry resources.
package sorting
import (
"slices"
"strings"
)
// NameGetter is an interface for objects that have a Name.
type NameGetter interface {
GetName() string
}
// NamespaceGetter is an interface for objects that have both Name and Namespace.
type NamespaceGetter interface {
NameGetter
GetNamespace() string
}
// ByName sorts a slice of objects by their Name in alphabetical order.
// Use this for cluster-scoped resources.
func ByName[T any, PT interface {
*T
NameGetter
}](items []T) {
slices.SortFunc(items, func(a, b T) int {
pa, pb := PT(&a), PT(&b)
return strings.Compare(pa.GetName(), pb.GetName())
})
}
// ByNamespacedName sorts a slice of objects by Namespace/Name in alphabetical order.
// Use this for namespace-scoped resources.
func ByNamespacedName[T any, PT interface {
*T
NamespaceGetter
}](items []T) {
slices.SortFunc(items, func(a, b T) int {
pa, pb := PT(&a), PT(&b)
if res := strings.Compare(pa.GetNamespace(), pb.GetNamespace()); res != 0 {
return res
}
return strings.Compare(pa.GetName(), pb.GetName())
})
}