Added label and attribute feature#9
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThis PR refactors Keyring to a struct with a label property, adds a Sendable Attributes type plus sync/async APIs to read item metadata from SecretService, persists label into item creation, adds integration tests for labeling/attributes, and expands DocC examples and tutorials. ChangesKeyring Attributes and Label Feature
Sequence DiagramsequenceDiagram
participant Keyring
participant SecretService
participant Collection
participant Item
Keyring->>SecretService: ensureConnected() / use provided or default service
SecretService->>Collection: defaultCollection() / createIfMissing()
Collection->>Item: searchForItem(label: key)
Item->>Item: read properties ("Label","Created","Modified")
Item->>Keyring: return Attributes(label, created, modified)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@Tests/KeyringAccessTests/KeyringAccessTests.swift`:
- Around line 217-220: The early return after checking
newKeyring[asyncAttributes: key] skips the test cleanup and leaves state behind;
wrap the cleanup call in a defer placed immediately after opening/creating
newKeyring (or replace the early return with recording the issue and allowing
execution to reach the existing deletion code) so that the deletion always runs.
Specifically, adjust the code around newKeyring and the asyncAttributes: key
check so Issue.record("No attributes for the given key") is still executed but
control does not bypass the existing cleanup (use defer or ensure the
delete/cleanup call executes in all paths).
- Around line 223-231: The assertions compare timestamp differences but allow
large negative deltas; update the checks for newAttributes.created vs
creationTime and newAttributes.modified vs editTime to assert absolute deltas
(or assert 0 <= delta && delta <= 1.5) so that timestamps that are older than
expected fail—i.e., compute the delta for
newAttributes.created.timeIntervalSince1970 - creationTime.timeIntervalSince1970
and for newAttributes.modified.timeIntervalSince1970 -
editTime.timeIntervalSince1970 and verify the absolute value is <= 1.5 (or the
delta is between 0 and 1.5).
🪄 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: 9ec4712e-ba3a-494f-9f15-8c1845d2abed
📒 Files selected for processing (4)
Sources/KeyringAccess/Keyring+Attributes.swiftSources/KeyringAccess/Keyring+Set.swiftSources/KeyringAccess/Keyring.swiftTests/KeyringAccessTests/KeyringAccessTests.swift
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@Sources/KeyringAccess/Documentation.docc/Documentation.md`:
- Line 16: The phrase "usecase" in the "Subscript and get/set Support" sentence
is misspelled; update that sentence to use "use case" (two words) instead of
"usecase" so the line reads "...depending on what fits your use case better." to
fix the spelling in Documentation.md.
In
`@Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-Read`:
- Around line 23-26: The example declares two variables named `secret` (from
keyring["user"] and keyring.get(for: "user")) causing a redeclaration error; fix
it by renaming one of them (e.g., rename the result of `keyring.get(for:
"user")` to `secretViaGetter`) or by removing the second `let` and assigning
into the existing `secret` (e.g., `secret = keyring.get(for: "user")`), updating
references accordingly so both `keyring["user"]` and `keyring.get(for: "user")`
are shown without duplicate variable declarations.
In
`@Sources/KeyringAccess/Documentation.docc/Resources/Package/IntroductionPackage-AddedDependency`:
- Around line 14-16: The YourApp executable target is missing a dependency on
the KeyringAccess product, so it cannot import KeyringAccess; update the YourApp
.executableTarget declaration to include a package product dependency on the
KeyringAccess product (i.e., add a .product dependency referencing product name
"KeyringAccess" and the package name used in Package.swift) so the target can
import and use KeyringAccess.
🪄 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: eb11b9aa-9d35-4e4c-9bae-e4f82c7538c2
📒 Files selected for processing (17)
Sources/KeyringAccess/Documentation.docc/Documentation.mdSources/KeyringAccess/Documentation.docc/Resources/Batch/BatchBaseSources/KeyringAccess/Documentation.docc/Resources/Batch/BatchOperationSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-BaseSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-AttributesSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-DeleteSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-KeyringSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-ReadSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-StoreSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-UpdateSources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-initSources/KeyringAccess/Documentation.docc/Resources/Package/IntroductionPackage-AddedDependencySources/KeyringAccess/Documentation.docc/Resources/Package/IntroductionPackage-AddedDependencyAppSources/KeyringAccess/Documentation.docc/Resources/Package/IntroductionPackage-BaseSources/KeyringAccess/Documentation.docc/Table of Contents.tutorialSources/KeyringAccess/Documentation.docc/Tutorials/Quick start.tutorialTests/KeyringAccessTests/KeyringAccessTests.swift
✅ Files skipped from review due to trivial changes (12)
- Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-Delete
- Sources/KeyringAccess/Documentation.docc/Resources/Package/IntroductionPackage-AddedDependencyApp
- Sources/KeyringAccess/Documentation.docc/Resources/Package/IntroductionPackage-Base
- Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-init
- Sources/KeyringAccess/Documentation.docc/Tutorials/Quick start.tutorial
- Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-Attributes
- Sources/KeyringAccess/Documentation.docc/Resources/Batch/BatchBase
- Sources/KeyringAccess/Documentation.docc/Table of Contents.tutorial
- Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-Keyring
- Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base
- Sources/KeyringAccess/Documentation.docc/Resources/Batch/BatchOperation
- Sources/KeyringAccess/Documentation.docc/Resources/CodeExample/Code-Base-Store
🚧 Files skipped from review as they are similar to previous changes (1)
- Tests/KeyringAccessTests/KeyringAccessTests.swift
Overview
This PR adds label and attribute metadata support to the Keyring API, enabling users to set a per-Keyring label on stored secrets and to retrieve key metadata (label, creation date, modification date).
Changes
Core Architecture
public final class Keyring: Sendabletopublic struct Keyring: @unchecked Sendable, adding a storedlabel: String?and a fluentlabel(_:) -> Selfconfigurator. Value semantics with a builder-style setter are a clean, low-friction design.New Public APIs
public struct Attributes: Sendablewith:public let label: Stringpublic let created: Datepublic let modified: Datepublic subscript(attributes key: String) -> Attributes?(noasync shim).public subscript(asyncAttributes key: String) -> Attributes? { get async throws(SecSError) }.public func getAttributes(for key: String) throws(SecSError) -> Attributes?(noasync shim).public func getAttributes(_ key: String, service: SecretService? = nil) async throws(SecSError) -> Attributes?.Implementation details: the async API optionally accepts a
SecretServiceand otherwise creates/uses a default connection; it ensures the service is connected, obtains (or creates) the default collection, finds the item for the key, reads DBus properties (Label,Created,Modified), converts timestamps toDate, and returns anAttributesinstance (ornilwhen not found or on missing properties). The synchronous APIs route to the async-backed implementations via bridging and log errors before returningnilfrom the convenience subscript.Persistence Behavior
Keyring._set(_:for:service:)now persists the configured label to the DBus item label property (replacing a prior TODO). Minor prompt-completion logic adjusted to ignore an unused local binding.Tests
keyring(let→var).testLabelverifies that applying.label(...)to aKeyringinstance results in persisted attributes whoselabelmatches the configured value (including after writing with a re-labeledKeyring).testAttributesverifies attribute persistence and correctness: label,created/modifiedtimestamps (asserting sensible changes within short windows), and cleanup of stored secrets at test end.Documentation
getAttributes.Strengths / Notable Good Work
label(_:)setter is a thoughtful design delivering safer value semantics while preserving ergonomics.Date.Potential Review Notes
@unchecked Sendableis reasonable here, but reviewers should confirm there's no hidden shared-mutable state that requires verified Sendable conformance.nil— consider whether callers need visibility into specific failure modes.