Skip to content

fix(archdocs): three bugs in pssg template helper functions#92

Merged
greynewell merged 1 commit intomainfrom
fix-funcs-slice-sort
Apr 9, 2026
Merged

fix(archdocs): three bugs in pssg template helper functions#92
greynewell merged 1 commit intomainfrom
fix-funcs-slice-sort

Conversation

@greynewell
Copy link
Copy Markdown
Contributor

@greynewell greynewell commented Apr 9, 2026

Summary

Three correctness bugs in internal/archdocs/pssg/render/funcs.go:

  1. durationMinutes ignored seconds — the regex captures (\d+)S as matches[3] but it was never read. PT90S returned 0 instead of 1; PT2H30M45S returned 150 instead of the correct truncated 150. Fix: read matches[3] and add seconds/60.

  2. sliceHelper panicked on out-of-bounds startend was clamped to len(v) but start was not, so slice(s, 5, 10) on a 3-element slice produced v[5:3] which panics. Also slice(s, 3, 1) (start > end) would panic. Fix: add clampSliceBounds helper that ensures 0 ≤ start ≤ end ≤ len(v).

  3. sortStrings didn't sort — the function registered as the sort template helper copied the input slice but never called sort.Strings. Any template using {{ sort list }} got an unsorted result. Fix: add sort.Strings(result) after the copy.

Test plan

  • Added TestDurationMinutes, TestSliceHelper, TestSortStrings
  • go test ./internal/archdocs/pssg/render/ passes
  • go build ./... passes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved duration parsing accuracy for ISO 8601 format handling.
    • Enhanced slice boundary handling to prevent out-of-range errors.
    • Ensured deterministic sorting behavior.
  • Tests

    • Added comprehensive unit test coverage for core utility functions.

1. durationMinutes ignored the seconds capture group — PT90S returned 0
   instead of 1; fix reads matches[3] and adds seconds/60.

2. sliceHelper panicked when start exceeded the slice length after end
   was clamped, e.g. slice(s, 5, 10) on a 3-element slice; fix adds a
   clampSliceBounds helper that also guards start > end.

3. sortStrings copied the slice but never called sort.Strings, so the
   template `sort` function always returned an unsorted copy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Walkthrough

This PR improves helper functions in the render package by fixing sortStrings to actually sort results, updating durationMinutes to properly handle ISO 8601 durations with seconds, and refactoring sliceHelper with a shared bounds-clamping utility. Comprehensive unit tests were added to validate these behaviors.

Changes

Cohort / File(s) Summary
Helper Function Improvements
internal/archdocs/pssg/render/funcs.go
Fixed sortStrings to deterministically sort slices. Enhanced durationMinutes to parse ISO 8601 hours/minutes/seconds and include fractional minutes from seconds. Introduced clampSliceBounds helper to centralize bounds-checking logic, replacing repeated per-type clamping in sliceHelper.
Test Coverage
internal/archdocs/pssg/render/funcs_test.go
Added comprehensive unit tests validating durationMinutes (ISO 8601 patterns, edge cases), sliceHelper (normal/inverted bounds, out-of-range handling), and sortStrings (immutability of input, correct ordering).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • jonathanpopham

Poem

🧹 Helpers now stand tall and true,
Sorting strings the way they're due,
Durations parsed in ISO light, ✨
Bounds all clamped and polished tight—
Tests in place, the code shines bright! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the three bugs being fixed in the pssg template helper functions, directly matching the changeset's main objectives.
Description check ✅ Passed The description covers all required sections from the template: What (bug summaries), Why (context with specific examples), and Test plan (with checkboxes showing tests pass).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-funcs-slice-sort

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/archdocs/pssg/render/funcs.go`:
- Around line 243-253: clampSliceBounds can return negative indices if end is
negative because the code sets start = end after only clamping end against
length; update clampSliceBounds to first clamp both start and end into the [0,
length] range (e.g., if start < 0 then start = 0; if start > length then start =
length; same for end) and only then enforce ordering (if start > end then start
= end); apply the same fix to the other similar function(s) in this file that
mirror clampSliceBounds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83f9779c-9c20-4a1e-97c3-f5ac7412c69f

📥 Commits

Reviewing files that changed from the base of the PR and between 343b81f and d20302a.

📒 Files selected for processing (2)
  • internal/archdocs/pssg/render/funcs.go
  • internal/archdocs/pssg/render/funcs_test.go

Comment on lines +243 to +253
func clampSliceBounds(start, end, length int) (int, int) {
if start < 0 {
start = 0
}
if end > length {
end = length
}
if start > end {
start = end
}
return start, end
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

clampSliceBounds can still return negative indices and panic.

On Line 250, start = end can make start negative when end < 0 (e.g., slice(s, -1, -1)), which will panic at slice time.
Please clamp both bounds to [0, length] before ordering.

🐛 Suggested fix
 func clampSliceBounds(start, end, length int) (int, int) {
 	if start < 0 {
 		start = 0
 	}
+	if start > length {
+		start = length
+	}
+	if end < 0 {
+		end = 0
+	}
 	if end > length {
 		end = length
 	}
 	if start > end {
 		start = end
 	}
 	return start, end
 }

Also applies to: 259-266

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/archdocs/pssg/render/funcs.go` around lines 243 - 253,
clampSliceBounds can return negative indices if end is negative because the code
sets start = end after only clamping end against length; update clampSliceBounds
to first clamp both start and end into the [0, length] range (e.g., if start < 0
then start = 0; if start > length then start = length; same for end) and only
then enforce ordering (if start > end then start = end); apply the same fix to
the other similar function(s) in this file that mirror clampSliceBounds.

@greynewell greynewell merged commit cff9d4e into main Apr 9, 2026
7 checks passed
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.

1 participant