feat(scan): scan selected uv workspace members with dependency graphs - #1565
Merged
Martin Torp (mtorp) merged 8 commits intoSep 28, 2026
Merged
Conversation
Bobo (mamanazizali581-dev)
approved these changes
Sep 28, 2026
Martin Torp (mtorp)
marked this pull request as ready for review
September 28, 2026 10:47
…ng-uv-subdirectories # Conflicts: # CHANGELOG.md
These cases spawn the built CLI like the cmdit tests do, but ran with vitest's 5s default and timed out under parallel load.
Replace --uv-package <project.name> with a boolean --uv-members flag. Each TARGET is a member directory, and uv resolves it from the uv.lock in that directory or its workspace root, so one scan can cover members of several workspaces. Each member's CycloneDX SBOM is written beside its pyproject.toml and removed after the scan. That keeps the existing upload roots and reachability target unchanged, so the scan handler takes a generic generateScanFiles hook and no longer has uv-specific branches. With --reach, analysis runs on the member directory only. The e2e assertions now accept uv 0.12, which omits dependsOn on leaf nodes and adds workspace-root dependency groups to members without their own.
Completes the previous commit, which only picked up the renames and the reachability revert.
The launcher SIGKILLs a signalled scan after a short grace period, and a signal or process.exit() skips finally blocks, so Ctrl-C or a CI cancel left socket-uv-cdx.json in the member directory. A later regular scan would then pick it up as a pre-generated SBOM. Written SBOMs are now also removed synchronously on exit, SIGHUP, SIGINT and SIGTERM. The real-uv e2e tests get a 30s timeout, since each one runs uv twice per member and the handler test sometimes passed 5s.
Benjamin Barslev Nielsen (barslev)
approved these changes
Sep 28, 2026
Martin Torp (mtorp)
deleted the
martin/ask-440-scanning-uv-subdirectories
branch
September 28, 2026 14:30
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A shared
uv.lockcovers the whole workspace, so scanning it directly also pulls in unrelated members. Scanning a member'spyproject.tomlon its own loses the lockfile's pinned versions.This adds a
--uv-membersflag. Each TARGET is a member directory:For each target, the CLI runs
uv export --project <dir>in frozen, offline mode. uv finds theuv.lockin that directory or in its workspace root, so one scan can cover members of several workspaces. The CycloneDX SBOM keeps pinned versions and dependency relationships, including transitive workspace dependencies, all extras, and all dependency groups. Dependencies used only by dependency groups are marked as development dependencies by comparing an export with groups against one without. This needs uv with CycloneDX export support, which uv still treats as a preview feature.Each SBOM is written as
socket-uv-cdx.jsonbeside the member'spyproject.toml, uploaded in place of manifest discovery, and removed after the scan, including on failure, Ctrl-C, or SIGTERM. The CLI stops if that file already exists. Because the file sits where the member's own manifest would, the regular upload roots and the reachability target work unchanged.handleCreateNewScantakes a genericgenerateScanFileshook and has no uv-specific code. With--reach, which takes a single target, Coana analyzes only that member's directory.Invalid targets and export failures stop the scan.
--uv-memberscan't be combined with--auto-manifestor--dynamic-sbom-inference. The README and command help describe the option.Validation:
dependsOnon leaf nodes and adds workspace-root dependency groups to members that don't define their own. The tests accept both.--reachscans against the Socket API with Coana 15.11.3, on a two-member workspace whereappdepends onrequests2.31.0 without calling it andothercallsrequests.get.--uv-members packages/appreported all 3requestsadvisories as unreachable, and--uv-members packages/otherreported all 3 as reachable. A regular scan of the whole workspace gave the same per-member results.The depscan importer drops local workspace nodes without a purl. uv's
uv:workspace:pathvalues stay relative to the workspace root.