Skip to content

Fix medium-priority review issues in updates, versions, and caching - #13

Merged
cookabc merged 1 commit into
mainfrom
cursor/medium-review-fixes-ec26
Oct 27, 2026
Merged

cookabc merged 1 commit into
mainfrom
cursor/medium-review-fixes-ec26

Conversation

@cookabc

@cookabc cookabc commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Fixes the five medium-priority items left after #12. No new dependencies; PEP 440 lives in this repo. npm test (161 passing), biome check, and npx @vscode/vsce package all succeed.

1. Update All used stale line numbers for safe edits

Issue. Safe updates were turned into WorkspaceEdits inside the registry loop, using line numbers from the parse taken before the network requests. Only risky updates were re-located afterwards, so an insert or delete while versions were loading moved a patch bump onto the wrong line.

Fix. Both safe and risky updates are collected as data. After the confirmation dialog, planRelocatedEdits reparses the current document and matches each dependency by package name and extra, then plans the rewrite from that line. A dependency that disappeared is skipped.

Tests. src/test/unit/batchUpdate.test.ts

  • safe updates land on the post-insert lines, including a comment inserted between two packages
  • a deleted dependency is skipped instead of editing a stale line
  • an unchanged file still rewrites the original lines
  • a risky update is relocated in the same pass
  • two pyproject entries that share a name but differ by extra stay distinct after a shift

2. Debug logging on every CodeLens resolve

Issue. resolveCodeLens called console.error("[UAT-PROBE] ...") on every lens.

Fix. The probe is removed.

Tests. mediumReview.test.ts spies on console.error during resolveCodeLens and asserts the probe string is absent.

3. Extras-only requirements files were rejected

Issue. detectFileType treated any [ ] pair as invalid TOML-like content. A requirements file whose only lines were extras, such as requests[security]>=2.0, was classified invalid and produced no dependencies.

Fix. A requirements*.txt file is valid unless it actually contains pyproject markers ([project], [tool., and so on). The content heuristic also allows an extra between the name and the operator, so the same line is recognized without a requirements file name.

Tests.

  • parser.test.ts: requirements.txt containing only requests[security]>=2.0 is a valid requirements file
  • basic.test.ts: that file parses both extras lines, and deps.txt with only requests[security,socks]>=2.0 is detected and parsed

4. PEP 440 comparison gaps

Issue. 1.0.0rc1.post1 compared greater than 1.0.0 because any post segment was treated as a final post-release. Epochs (1!1.0) were ignored. 1.0rc1+cpu was not a pre-release because the check required the pre tag to be at the end of the string.

Fix. src/core/pep440.ts parses and orders versions with the PEP 440 key (epoch, release, pre, post, dev, local). A pre-release that also has a post or local segment stays a pre-release. == ignores a local version unless the specifier itself has one. ~= and .* require the same epoch. An epoch change is a major/high-risk update. The implementation is local to this extension (about 80 KB packaged, no added dependency).

Tests. versionResolver.test.ts and versionAnalyzer.test.ts

  • 1.0.0rc1.post1 < 1.0.0 and > 1.0.0rc1
  • 1!1.0 > 2.0, and resolve picks the highest epoch
  • 1.0rc1+cpu is a pre-release; 1.0+cpu is not
  • the PEP 440 ordering examples sort strictly
  • spelling aliases (c/rc/pre, 1.0-1/1.0.post1, v1.0.0) compare equal
  • == and .* honor epochs; ==1.2.3 matches 1.2.3+cpu but ==1.2.3+cpu does not match 1.2.3+gpu
  • 1.0.0 → 1!1.0.0 is a high-risk major update

5. Cache identity, closed documents, and hover

Issue. Cache keys were only lowercased, so foo_bar and foo-bar did not share an entry (PEP 503). dependencyCache never dropped closed documents, and the status bar summed every document ever opened. Hover called getLatestCompatible with an empty specifier, so it showed the absolute latest while the CodeLens stayed inside the range.

Fix. Both the persisted cache and the CodeLens version cache use versionCacheKey (lowercase, runs of - _ . collapsed to one -). Closing a document calls forgetDocument, and the status bar only counts documents still in workspace.textDocuments. Reopening a file whose versions are already cached refreshes the total. Hover passes the dependency specifier through the same resolveLatest path as the CodeLens (a bare == pin still suggests the absolute latest; a range does not).

Tests. mediumReview.test.ts

  • Foo_Bar, foo.bar, and foo-bar share one registry fetch in getPackageVersions and in the CodeLens memory cache
  • after two files each have an update, forgetting one drops the status total from 2 to 1; reopening restores it; a document absent from textDocuments is evicted on the next refresh
  • hover on requests>=2.0,<3 reports 2.9.0, not 4.0.0; hover on requests==2.0.0 reports 4.0.0, matching the CodeLens pin rule
Open in Web Open in Cursor 

Plan every Update All edit from the current document so a line inserted
during the registry lookup cannot move a safe bump. Compare versions with
PEP 440, accept extras-only requirements files, normalize cache keys, and
drop closed documents from the status bar.

Co-authored-by: cookabc <chuangcius@gmail.com>
@cookabc
cookabc merged commit c71e8fa into main Oct 27, 2026
1 check passed
@cursor
cursor Bot deleted the cursor/medium-review-fixes-ec26 branch October 27, 2026 07:07
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