fix(deps): update keepass to 0.12 and migrate provider to new API#494
Conversation
The 0.12 release made the database model encapsulated: `Group.groups`, `Group.entries`, `Database.root`, and `Entry::new`/`Group::new` are now private. Public access goes through `Database::root()` / `root_mut()`, `GroupRef::groups()` / `entries()`, and `GroupMut::add_group()` / `add_entry()`. - Switch entry lookup to id-based traversal that returns `EntryId`, then resolve to `EntryRef`/`EntryMut` via `Database::entry` / `entry_mut`, which sidesteps the lifetime issues that come with recursive `GroupRef` borrows. - Rewrite the write path: navigate or create groups segment-by-segment via `group_mut`/`add_group`, then either update an existing entry's field via `entry_mut` or call `add_entry` on the target group. - Use the new `set_protected` / `set_unprotected` helpers instead of poking the deprecated `fields` map; this preserves the previous "Password is protected, everything else is unprotected" behavior. - Replace the now-removed `Database::new(DatabaseConfig::default())` with the zero-arg `Database::new()`. All 23 KeePass bats tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR upgrades
Confidence Score: 5/5Safe to merge — the rewrite faithfully reproduces the pre-0.12 lookup and write semantics, and the test suite (unit tests + 23/23 bats) confirms end-to-end behaviour is preserved. The migration is mechanically straightforward: every changed code path has a clear counterpart in the old implementation, read and write paths are consistent in their recursive-title-search behaviour, and the borrow-splitting strategy (owned IDs eliminating lifetime conflicts) is clean and correct. No logic changes relative to the old provider, no dropped error cases, no new failure modes. No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "fix(keepass): migrate provider to keepas..." | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request updates the keepass dependency from version 0.10 to 0.12, which involves a significant refactor of the KeePass provider to accommodate the new ID-based API. The changes replace direct group and entry manipulation with lookups using EntryId and GroupId, and introduce new helper methods for recursive searching and path navigation. A critical issue was identified in the group creation logic where a direct string assignment to a mutable reference field would cause a compilation error, requiring a dereference.
| None => { | ||
| let mut group_mut = db.group_mut(current_id).expect("current group exists"); | ||
| let mut new_group = group_mut.add_group(); | ||
| new_group.name = (*name).to_string(); |
There was a problem hiding this comment.
In keepass 0.12, GroupMut is a wrapper where the name field is a &mut String. Assigning a String directly to this field will result in a type mismatch compilation error. You need to dereference the field to update the underlying string value.
| new_group.name = (*name).to_string(); | |
| *new_group.name = (*name).to_string(); |
Summary
Supersedes #469 (Renovate's blind 0.10 → 0.12 bump which doesn't compile). Includes Renovate's
Cargo.toml/Cargo.lockbump plus the matching provider rewrite for the new encapsulated keepass API.What changed in keepass 0.12
Group.groups,Group.entries,Database.root,Entry::new, andGroup::neware nowpub(crate).Database::root()/root_mut(),GroupRef::groups()/entries(),GroupMut::add_group()/add_entry().Database::new()is zero-arg now (wasDatabase::new(DatabaseConfig::default())).Provider migration
EntryId, then resolves toEntryRef/EntryMutviaDatabase::entry/entry_mut. This sidesteps the lifetime issues of recursiveGroupRefborrows.group_mut/add_group, then updates an existing entry or callsadd_entryon the target group.set_protected/set_unprotectedhelpers — same "Password is protected, everything else is unprotected" behavior.No behavior change
The lookup semantics are preserved: path segments before the last name exact-named subgroups to navigate into; the final segment is searched recursively by entry title.
Test plan
cargo build— cleancargo clippy --workspace --all-targets— cleancargo test -p fnox-core keepass --lib— 4 passedKEEPASS_PASSWORD=test mise run test:bats -- test/keepass.bats— 23/23 passed🤖 Generated with Claude Code
Note
Medium Risk
Updates a secrets-storage dependency and rewrites the KeePass provider’s read/write traversal and mutation logic, which could affect entry lookup and database writes. Changes are localized but touch persistent secret data handling.
Overview
Updates the
keepasscrate to0.12(and refreshesCargo.lock, including aquick-xmlbump) and migrates the KeePass provider to the new encapsulated API.The provider now resolves entries via
EntryId/GroupIdandGroupRefaccessors, adds group creation viagroup_mut().add_group(), and writes fields usingset_protected/set_unprotected(keeping Password protected semantics). Database creation is updated to the newDatabase::new()signature, while lookup semantics are preserved by recursively searching for entry titles under the target group.Reviewed by Cursor Bugbot for commit cdaebc4. Bugbot is set up for automated code reviews on this repo. Configure here.