Repository navigation
Scope the project-mode Deno crawl to the JSR packages deno.lock records (#1216) - #1217
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Move find_by_purls' per-purl cache lookup into one locate() and the version-dependent deno.lock section lookup (v2 npm.packages, v3 packages.<section>, v4/v5 top-level) out of VEX discovery into deno_crawler::lock_section, so the project crawl can reuse both. No behavior change. Assisted-by: Claude Code:claude-opus-5-5
In project mode, crawl_all walked the whole JSR cache, so scan, agent apply and VEX saw every JSR package any project on the machine had cached. A project with a deno.lock now gets only the packages its lock's jsr section records, each looked up in the cache; a lock with no jsr section records none. --global, --global-prefix and projects without a usable deno.lock still walk the cache. On a 3,000-package cache with 140 locked packages the crawl drops from 48 ms to 7.5 ms (debug build). Fixes #1216. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit a3e5f30. Configure here.
|
[burn-down] Ready for review at Generated by Claude Code |
Final review briefWhat it does. In project mode, the Deno/JSR crawl now looks up only the JSR packages Risk: low. The set only narrows when a real Look here
Verified
Changes I made: none. Open questions (not blocking): in a Deno workspace member whose Auto-merge (squash) is armed, so approving sends this straight to the merge queue. Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1216
Summary
In project mode,
DenoCrawler::crawl_allwalked the whole$DENO_DIR/npm/jsr.iocache as soon ascwdhad a Deno marker.scan, agent apply and VEX therefore saw every JSR package any project on the machine had cached. A project with adeno.locknow gets only the JSR packages its lock records, each looked up in the cache.--global,--global-prefixand projects without a usabledeno.lockstill walk the cache.Why
This is the Deno child of tracking issue #595 (register E05, living document doc/06 "Cache crawls are not project-scoped"). It follows the NuGet (#1183), cargo (#1205) and Go (#1209) children.
lock_sectionreader fordeno.lock's version-dependent layout, shared by the crawl and VEX discovery (deno_npm_keys), and one JSRlocatelookup shared byfind_by_purlsand the crawl.What changed
crawlers/deno_crawler.rs:locate(cache, purl)does the lookupfind_by_purlsalready did (purl grammar, the traversal guard and theis_dircheck). It is now shared byfind_by_purlsand the scoped crawl.jsr_lock_scope(cwd)reads<cwd>/deno.lockFIFO-safely withread_regular_to_string. It returns thepkg:jsr/purl of eachjsrkey. It returnsNonewhen there is no lock, the lock is not JSON, or it has noversionfield, and the crawl then walks the cache.lock_section(lock, "npm" | "jsr")reads a section from any lock version: top-level in v4/v5,packages.<s>in v3 and<s>.packagesin v2.crawl_alluses the lock scope in project mode and keeps the walk otherwise.vex/discover/deno.rs:deno_npm_keysnow callslock_section, and its private copy of the layout logic is deleted.Size
Behavior
These are the only changes:
deno.lockwith aversion: cached JSR packages that the lock doesn't record are no longer crawled.jsrsection, such as an npm-only project, crawls no JSR packages.scan --prunetherefore treats manifest entries for unlocked cached JSR packages as uninstalled.is_safe_jsr_componentguard.deno.json-only projects, malformed locks,find_by_purls, and the VEX npm-section read.Test evidence
New tests, red on main → green here:
crawl_all_local_lock_scopes_to_locked_jsr_packages(v5, v4 and v3 locks)crawl_all_local_lock_without_jsr_reports_nothingcrawl_all_local_lock_skips_uncached_and_unsafe_entriesTo get the red result I forced the scope off, which reproduces main's walk: these 3 FAILED and the other crawl tests passed.
New tests, green on both (they pin the fallbacks):
crawl_all_walks_without_a_usable_lock_or_in_global_modecrawl_all_local_without_lock_walks_the_cacheShared-reader test:
lock_section_reads_every_lock_versioncovers both callers' sections (npm and jsr) across v2 to v5. The existingdeno_npm_keys_cover_every_lock_versionstays green.cargo clippy --workspace --all-features -- -D warnings: clean.cargo test -p socket-patch-core --lib: 5852 passed. The 4 failures are the known root-sandbox ones (copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_…,pypi_requirements::wire_failure_…).crawler_deno_e2e: 13 passed.CLI suites:
e2e_vex_lockfile: 343 passedscan: 118 passedin_process_alternate_installers: 26 passedin_process_get_hosted_ecosystems: 10 passedrepair: 124 passed. The 2 failures (repair_exits_zero_and_stays_quiet_when_lock_file_unremovable,repair_cleanup_failure_is_reported_in_json_and_silent_modes) also fail on main in this sandbox because it runs as root. They pass in CI.Timing (debug test build, 20-run mean): a 3,000-package JSR cache with 140 locked packages took 48.1 ms to walk and 7.5 ms with the lock-scoped lookup.
Risk
Low to medium. The candidate set shrinks only when a real
deno.lockis present. No CLI suite depended on the whole-cache Deno crawl in a locked project, since the VEX fixtures lock the JSR packages they stage.lock_sectionstays in the crawler for now becauseformats/mod.rsis changed by open PRs; it can move to aformats::denomodel later.🤖 Generated with Claude Code
https://claude.ai/code/session_01T1eqQrD34pmJbFhR6LkLx1
Note
Medium Risk
Changes which packages appear in scan/VEX for locked Deno projects (smaller candidate set) and parses untrusted
deno.lockpaths, though existing fail-closed path guards are preserved.Overview
Project-mode Deno/JSR discovery no longer enumerates the entire
$DENO_DIR/npm/jsr.iocache when the workspace has a validdeno.lock.DenoCrawler::crawl_allnow reads the lock’sjsrkeys (lock versions 2–5 via a sharedlock_sectionhelper), turns them intopkg:jsr/…PURLs, and resolves each with targeted cache lookups instead of walking the tree. Cached JSR packages from other projects are excluded; npm-only locks yield no JSR packages.--global,--global-prefix, missing/unreadable locks, and JSON without Deno’sversionfield still perform a full cache walk. JSR path resolution is centralized inlocate(used by both the scoped crawl andfind_by_purls), with the same traversal guards for lock-derived coordinates.VEX Deno discovery reuses
lock_sectionfor npm lock keys, removing duplicated lock layout parsing.Reviewed by Cursor Bugbot for commit a3e5f30. Configure here.
Generated by Claude Code