Skip to content

PTR-3591 Added modTimeCursor along with encode/decode functions#97

Merged
alice-luno merged 5 commits into
mainfrom
ayang-add-modTimeBlob
May 27, 2026
Merged

PTR-3591 Added modTimeCursor along with encode/decode functions#97
alice-luno merged 5 commits into
mainfrom
ayang-add-modTimeBlob

Conversation

@alice-luno
Copy link
Copy Markdown
Contributor

@alice-luno alice-luno commented May 26, 2026

For External Submissions:

Addresses Issue #98

  • Have you followed the guidelines in our Contributing file?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?
  • If it's a non-trivial change, I've linked a new or existing issue to this PR
  • I have performed a self-review of my code
  • Does your submission pass existing tests?
  • Have you written new tests for your new changes, if applicable?
  • Have you added an explanation of what your changes do and why you'd like us to include them?

Summary by CodeRabbit

  • New Features

    • Added progress tracking for S3 listing operations using timestamp-based cursors with object-key tie-breakers for precise resumption.
  • Tests

    • Added tests covering cursor serialisation/parsing, empty-input handling, error cases and round-trip consistency.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b76ec151-378a-455a-a6e8-f9dc14293413

📥 Commits

Reviewing files that changed from the base of the PR and between 782d300 and 64a0a0b.

📒 Files selected for processing (2)
  • rblob/modTimeBlob.go
  • rblob/modTimeBlob_internal_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • rblob/modTimeBlob.go

📝 Walkthrough

Walkthrough

This PR adds a modtimeCursor in rblob to track S3 listing progress by object modification time. It defines the cursor struct (Key, ModTime), a String() method that serialises as "key|unixNano" (empty key → empty string), and parseModTimeCursor which validates and parses that format into UTC time. Tests cover String() edge cases, parser error cases, and round-trip correctness.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Poem

🐰 I hop the cursor through S3's hay,
By modTime and key I mark the way.
String then parse, round-trip delight,
Tiny paws check format through the night,
A carrot for tests that pass outright. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: introducing modTimeCursor with encode/decode functions, which matches the file additions for modtimeCursor string formatting and parsing.
Description check ✅ Passed The description addresses Issue #98 and confirms that new tests were written, self-review performed, and existing tests pass. It relates to the changeset by indicating this is a non-trivial change with proper testing and issue linkage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 ayang-add-modTimeBlob

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

🧹 Nitpick comments (1)
rblob/modTimeBlob_internal_test.go (1)

37-41: ⚡ Quick win

Add parser round-trip coverage for pipe-containing keys (and empty-key rejection).

You already test String() with file|with|pipes, but not parse/round-trip for that case. Add a round-trip assertion for pipe-containing keys and a parse failure case for |123 to prevent future regressions.

Also applies to: 78-90

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rblob/modTimeBlob_internal_test.go` around lines 37 - 41, Add two test cases
in modTimeBlob_internal_test.go: one asserting round-trip for a pipe-containing
key by creating modtimeCursor{Key: "file|with|pipes", ModTime: time.Unix(0,42)},
calling its String() and then the parser (the function that parses cursor
strings, e.g. ParseModtimeCursor/ParseCursor) and asserting the parsed value
equals the original; and a negative test asserting that parsing the string
"|123" returns an error (i.e. parser rejects empty key). Use the existing
modtimeCursor type and its String() method and the project’s cursor-parse
function name to locate where to add these assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rblob/modTimeBlob.go`:
- Around line 60-67: The cursor parsing currently uses strings.Cut on the first
'|' which mis-parses keys containing '|' and allows an empty key for non-empty
cursors; update the parsing in the modtimeCursor unmarshalling logic (where key,
rest, found := strings.Cut(s, "|") is used) to locate the last separator (e.g.,
strings.LastIndex or LastIndexByte), split into key = s[:idx] and rest =
s[idx+1:], return an error if no separator is found, and additionally reject
cases where key == "" but rest != "" (i.e., non-empty cursor with empty key)
before calling strconv.ParseInt on rest to produce the modtimeCursor.

---

Nitpick comments:
In `@rblob/modTimeBlob_internal_test.go`:
- Around line 37-41: Add two test cases in modTimeBlob_internal_test.go: one
asserting round-trip for a pipe-containing key by creating modtimeCursor{Key:
"file|with|pipes", ModTime: time.Unix(0,42)}, calling its String() and then the
parser (the function that parses cursor strings, e.g.
ParseModtimeCursor/ParseCursor) and asserting the parsed value equals the
original; and a negative test asserting that parsing the string "|123" returns
an error (i.e. parser rejects empty key). Use the existing modtimeCursor type
and its String() method and the project’s cursor-parse function name to locate
where to add these assertions.
🪄 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: 0e960abd-e1e4-4810-829f-f697d95ad655

📥 Commits

Reviewing files that changed from the base of the PR and between 454f1f7 and 0617edc.

📒 Files selected for processing (2)
  • rblob/modTimeBlob.go
  • rblob/modTimeBlob_internal_test.go

Comment thread rblob/modTimeBlob.go Outdated
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.

🧹 Nitpick comments (1)
rblob/modTimeBlob_internal_test.go (1)

51-82: ⚡ Quick win

Consider adding an explicit test case for parsing keys containing pipes.

Whilst TestModtimeCursor_String verifies serialisation of keys with pipes (line 38-41), TestParseModTimeCursor lacks a corresponding parse test. Adding an explicit test case such as parseModTimeCursor("file|with|pipes|42") would strengthen coverage of the LastIndex logic and provide clearer failure messages if the implementation changes.

✅ Suggested test case
t.Run("key containing pipes parses correctly", func(t *testing.T) {
	c, err := parseModTimeCursor("file|with|pipes|42")
	jtest.RequireNil(t, err)
	require.Equal(t, "file|with|pipes", c.Key)
	require.Equal(t, time.Unix(0, 42).UTC(), c.ModTime)
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rblob/modTimeBlob_internal_test.go` around lines 51 - 82, Add a test within
TestParseModTimeCursor that verifies parseModTimeCursor correctly handles keys
containing pipe characters: call parseModTimeCursor("file|with|pipes|42"),
assert no error, assert c.Key == "file|with|pipes" and c.ModTime == time.Unix(0,
42).UTC(); this mirrors the serialization check in TestModtimeCursor_String and
ensures the LastIndex split logic in parseModTimeCursor handles multiple pipes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@rblob/modTimeBlob_internal_test.go`:
- Around line 51-82: Add a test within TestParseModTimeCursor that verifies
parseModTimeCursor correctly handles keys containing pipe characters: call
parseModTimeCursor("file|with|pipes|42"), assert no error, assert c.Key ==
"file|with|pipes" and c.ModTime == time.Unix(0, 42).UTC(); this mirrors the
serialization check in TestModtimeCursor_String and ensures the LastIndex split
logic in parseModTimeCursor handles multiple pipes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7c6b0dfb-c414-40ee-aaed-66836ed300a1

📥 Commits

Reviewing files that changed from the base of the PR and between 0617edc and 39f5173.

📒 Files selected for processing (2)
  • rblob/modTimeBlob.go
  • rblob/modTimeBlob_internal_test.go

Comment thread rblob/modTimeBlob_internal_test.go
@onkuh onkuh requested review from ScaleneZA, donovan-luno and onkuh May 26, 2026 14:46
Copy link
Copy Markdown

@RieshBissessur RieshBissessur left a comment

Choose a reason for hiding this comment

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

LGTM, minor comments

Comment thread rblob/modTimeBlob.go Outdated
Comment thread rblob/modTimeBlob.go Outdated
Comment thread rblob/modTimeBlob_internal_test.go Outdated
@sonarqubecloud
Copy link
Copy Markdown

@alice-luno alice-luno merged commit 6547e00 into main May 27, 2026
5 checks passed
@alice-luno alice-luno deleted the ayang-add-modTimeBlob branch May 27, 2026 08:09
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.

3 participants