Skip to content

chore: Replace sort package with slices and cmp packages - #986

Open
dongjiang1989 wants to merge 1 commit into
prometheus:mainfrom
dongjiang1989:sort-slices
Open

chore: Replace sort package with slices and cmp packages#986
dongjiang1989 wants to merge 1 commit into
prometheus:mainfrom
dongjiang1989:sort-slices

Conversation

@dongjiang1989

Copy link
Copy Markdown
Member

Replace all usage of Go's sort package with the modern slices and cmp packages (Go 1.21+) for more concise and readable sorting code.

Changes

  • Remove sort.Interface methods (Len/Less/Swap) from LabelNames, LabelValues, LabelPairs, Fingerprints, Alerts, Samples, Vector, and Matrix types.
  • Add Compare methods on *Sample, *SampleStream, *Alert, and *LabelPair for use with slices.SortFunc, eliminating duplicated comparator code at call sites.
  • Replace sort.Sort calls with slices.SortFunc (using the new Compare methods or cmp.Compare for simple ordered types), and sort.Strings with slices.Sort.
  • Add a depguard rule in .golangci.yml to forbid the sort package and prevent future regressions.
  • Fix pre-existing gofumpt formatting issues in config and route packages (uncovered by make lint).

Note

The original Alerts.Less was not a proper strict weak ordering (it used StartsBefore || EndsBefore || FPLess). The new (*Alert).Compare implements a correct hierarchical comparison (StartsAt → EndsAt → Fingerprint). TestSortAlerts expected values were updated accordingly.

Verification

  • go build ./...
  • go vet ./...
  • make lint
  • go test ./model/... ./expfmt/...

Replace all usage of Go's sort package with the modern slices and cmp
packages (Go 1.21+) for more concise and readable sorting code.

- Remove sort.Interface methods (Len/Less/Swap) from LabelNames,
  LabelValues, LabelPairs, Fingerprints, Alerts, Samples, Vector, and
  Matrix types.
- Add Compare methods on *Sample, *SampleStream, *Alert, and *LabelPair
  for use with slices.SortFunc.
- Replace sort.Sort calls with slices.SortFunc using the new Compare
  methods, and sort.Strings with slices.Sort.
- Add depguard rule in .golangci.yml to forbid the sort package and
  prevent future regressions.
- Fix pre-existing gofumpt formatting issues in config and route
  packages.

Signed-off-by: dongjiang1989 <dongjiang1989@126.com>
@dongjiang1989 dongjiang1989 changed the title Replace sort package with slices and cmp packages chore: Replace sort package with slices and cmp packages Sep 7, 2026
@bwplotka
bwplotka requested a lite review from Copilot September 8, 2026 14:56
@bwplotka

bwplotka commented Sep 8, 2026

Copy link
Copy Markdown
Member

NOTE: This is a breaking change for downstream - we should do it ideally only when we have to

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The sorting refactor is consistent and test updates align with the new comparison logic, with only minor doc-comment nits remaining.

Pull request overview

This PR modernizes sorting across the codebase by replacing sort usage with Go 1.21+ slices/cmp, and centralizing comparison logic into Compare methods on key model types.

Changes:

  • Replaced sort.Sort / sort.Strings usage with slices.SortFunc / slices.Sort across model and expfmt code.
  • Introduced Compare methods on *Sample, *SampleStream, *Alert, and *LabelPair to reuse consistent ordering logic.
  • Added a depguard rule to forbid importing sort, preventing reintroduction.
File summaries
File Description
route/route_test.go Formatting-only adjustments to method chaining (gofumpt style).
model/value.go Adds Compare methods and migrates matrix sorting to slices.SortFunc.
model/value_test.go Updates vector sorting test to use slices.SortFunc with (*Sample).Compare.
model/metric.go Replaces sort.Strings with slices.Sort for label string ordering.
model/labelset.go Replaces label-name sorting with slices.SortFunc + cmp.Compare.
model/labels.go Removes sort.Interface impls and adds (*LabelPair).Compare.
model/labels_test.go Migrates label sorting tests to slices.SortFunc.
model/fingerprinting.go Removes sort.Interface impl from Fingerprints (now sorted via slices elsewhere).
model/fingerprinting_test.go Migrates fingerprint sorting test to slices.SortFunc + cmp.Compare.
model/alert.go Replaces Alerts.Less with a strict, hierarchical (*Alert).Compare.
model/alert_test.go Updates alert sorting test to use slices.SortFunc and new expected order.
expfmt/decode_test.go Updates sample sorting in decoder tests to use (*model.Sample).Compare.
config/tls_config_test.go Formatting-only cast simplification for TLSVersion.
config/http_config.go Formatting-only cast simplification and gofumpt-style trailing commas in varargs calls.
.golangci.yml Adds depguard deny rule for sort imports.
Review details
  • Files reviewed: 15/15 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread model/alert.go
Comment on lines +113 to +114
// Compare implements the cmp.Comparator interface for Alert pointers.
// It compares by StartsAt, then EndsAt, then Fingerprint.
Comment thread model/labels.go
Comment on lines +180 to +181
// Compare implements the cmp.Comparator interface for LabelPair pointers.
// It compares by Name, then by Value.
Comment thread model/value.go
Comment on lines +138 to +139
// Compare implements the cmp.Comparator interface for Sample pointers.
// It compares first the metrics, then the timestamp.
Comment thread model/value.go
Histograms []SampleHistogramPair `json:"histograms"`
}

// Compare implements the cmp.Comparator interface for SampleStream pointers.

@bboreham bboreham left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Bartek - it's quite a breaking change to make all these types no longer implement sort.Interface. Suggest to leave them in, maybe with a comment that they are for backwards-compatibility only. You could have Less call the new Compare.

Can you explain a bit more about the change to Alert ordering? This will be another breaking change; we'd need a strong justification.

Fix pre-existing gofumpt formatting issues in config and route packages (uncovered by make lint).

Do this in a separate PR. It's extra work to review changes for multiple different reasons at the same time.

Also, it might be neater to use cmp.Or in the Compare methods.

Comment thread config/http_config.go
"TLS12": (TLSVersion)(tls.VersionTLS12),
"TLS11": (TLSVersion)(tls.VersionTLS11),
"TLS10": (TLSVersion)(tls.VersionTLS10),
"TLS13": TLSVersion(tls.VersionTLS13),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not covered by the PR title.

Comment thread config/http_config.go
Comment on lines +642 to +643
conntrack.DialWithName(name),
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spurious change

@dongjiang1989

Copy link
Copy Markdown
Member Author

Thanks for the review @bwplotka @bboreham.

Understood. I'll restore Len/Less/Swap methods as a compatibility layer, delegating to the new Compare().

I will make these changes in the next push:

  1. Fix doc comments and remove the wrong cmp.Comparator reference.
  2. Restore sort.Interface methods (Len/Less/Swap) as a compatibility layer, delegating to Compare().
  3. Rewrite multi-level comparisons using cmp.Or.
  4. Strip unrelated gofumpt formatting changes to a separate PR, clean up spurious diffs.
  5. The old Alert sort had invalid ordering. The new ordering fixes this bug, which is a behavioral change. I will add a changelog note for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants