Skip to content

Fix PNPM Workspace Dependencies Scan and Add New License Discovery System - #7

Merged
JosephMaynard merged 6 commits into
masterfrom
fix/pnpm-workspace-scan
Feb 4, 2026
Merged

JosephMaynard merged 6 commits into
masterfrom
fix/pnpm-workspace-scan

Conversation

@JosephMaynard

@JosephMaynard JosephMaynard commented Feb 4, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Full SPDX license scanning: validation, inference, confidence, exception and deprecation awareness
    • Structured license model with status (match/mismatch/declared-only/etc.) and licenseRisk classification
    • UI/report enhancements: richer license details, filtering, and schema bumped to 1.2
    • New SPDX data generation and build step
  • Chores

    • Package/build script updated to include SPDX generation
    • Improved package resolution to read per-version license text and pnpm store support

@coderabbitai

coderabbitai Bot commented Feb 4, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Introduces comprehensive SPDX license handling: new SPDX generator and license module, type/schema bump to 1.2, build integration, version-aware package resolution and license-text extraction, aggregator license composition (declared/inferred/status/risk), and UI updates to render and filter structured license data.

Changes

Cohort / File(s) Summary
SPDX generator & artifacts
scripts/build-spdx.ts, src/generated/spdx.ts
New build script fetches SPDX license/exception data and emits src/generated/spdx.ts containing Sets for license and exception IDs (including deprecated sets).
License logic module
src/license.ts, src/types.ts, src/report-assets.ts
Adds SPDX parsing/validation, text-based inference, risk classification, and related types (LicenseConfidence, LicenseStatus, DependencyLicenseInfo). Report asset rendering updated to consume the new license shape.
Aggregator & resolution
src/aggregator.ts, src/utils.ts, .dependency-radar/dependency-radar/import-graph.json
Builds licenseInfo from declared/inferred sources, computes status and risk, caches per name@version, enhances package.json resolution (pnpm store support) and returns licenseText. Dependency graph updated to include new modules.
UI and sample data
report-ui/types.ts, report-ui/main.ts, report-ui/sample-data.json, README.md
Schema bumped to 1.2; types and sample data switched from simple license strings to structured license objects; UI uses resolvePrimaryLicense/formatLicenseStatus, displays declared/inferred/exception details and updated filtering. README documents the new license data shape.
Build & package scripts
package.json
Adds build:spdx script and wires it into the build pipeline before existing build steps.
Dependency radar data
dependency-radar.json
Widespread migration of license fields from strings to structured objects (declared/inferred/status), timestamp/branch metadata update.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer (runs build)
  participant Build as build-spdx
  participant FS as src/generated/spdx.ts (generated)
  participant Aggregator as src/aggregator.ts
  participant Utils as src/utils.ts
  participant License as src/license.ts
  participant UI as report-ui/main.ts

  Dev->>Build: run npm run build:spdx
  Build->>FS: fetch SPDX JSON, generate Sets
  FS-->>Aggregator: provide SPDX lookup data (import)
  Aggregator->>Utils: resolvePackageJsonPath(name, paths, version)
  Utils-->>Aggregator: package.json path, licenseFile, licenseText
  Aggregator->>License: validateSpdxExpression(declared), inferLicenseFromText(licenseText)
  License-->>Aggregator: SpdxValidationResult, inference match, normalized IDs
  Aggregator->>Aggregator: buildLicenseInfo (status, licenseIds), pickLicenseRisk
  Aggregator-->>UI: emit aggregated data with structured license object
  UI->>License: format/resolvePrimaryLicense for display
  UI-->>Dev: render report with declared/inferred/status/risk
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Fix: Workspace License Issues #3: Related changes to package resolution and license-reading flow (signatures for resolvePackageJsonPath and readLicenseFromPackageJson and version-aware resolution).

Poem

🐰 Hop, hop — I stitched SPDX bright,

declared and inferred in moonlit sight,
Exceptions noted, statuses sing,
Risk badges rally, bells that ring,
A hopping cheer for license light!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately captures the two main objectives of the changeset: fixing PNPM workspace dependency scanning and implementing a new license discovery system with SPDX validation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/pnpm-workspace-scan

Important

Action Needed: IP Allowlist Update

If your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:

  • ✨ 136.113.208.247/32 (new)
  • 34.170.211.100/32
  • 35.222.179.152/32

Reviews will stop working after February 8, 2026 if the new IP is not added to your allowlist.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.dependency-radar/dependency-radar/import-graph.json (1)

1-81: ⚠️ Potential issue | 🟠 Major

Remove temporary .dependency-radar/ artifacts from the PR.

This looks like generated dependency metadata; please drop it from version control (or keep only when using --keep-temp) and add/update ignore rules if needed.

Based on learnings: Temporary files in .dependency-radar/ may contain dependency metadata; avoid committing them and remove unless debugging with --keep-temp.

🤖 Fix all issues with AI agents
In `@scripts/build-spdx.ts`:
- Around line 29-49: fetchJson currently can hang without a timeout and treats
any status <400 as OK; modify fetchJson to enforce a strict 2xx check and a
request timeout: when calling https.get capture the returned ClientRequest
(e.g., const req = https.get(...)), start a timer (e.g., 10s) that will
destroy/abort the request and reject the Promise with a timeout Error if fired,
and ensure the timer is cleared on successful 'end' and on 'error'; inside the
response handler validate res.statusCode is between 200 and 299 and reject (and
res.resume()) for any other status, and keep the existing 'error' handler but
make sure it also clears the timeout before rejecting.

In `@src/license.ts`:
- Around line 48-117: The guard in validateSpdxExpression currently calls
input.trim() before checking typeof string and also rejects any parentheses;
change the initial invalid.normalized assignment to use the raw trimmed value
only after confirming typeof input === 'string' (i.e., perform the type check
before trimming) and remove the early return for parentheses. Update the
tokenizer/loop that builds tokens/normalizedTokens to treat '(' and ')' as valid
tokens (allow '(' when expectTerm is true and ')' when not expecting a term),
track parentheses nesting to ensure they are balanced, and integrate parentheses
into the normalized output while keeping existing logic for normalizeSpdxId,
normalizeExceptionId, handling 'WITH', and operator validation (AND/OR) so
expressions like "MIT AND (LGPL-2.1-or-later OR BSD-3-Clause)" parse and
validate correctly.
🧹 Nitpick comments (2)
scripts/build-spdx.ts (1)

24-27: Pin SPDX source data for reproducible builds.
Pulling from a moving upstream branch can make builds non-deterministic; consider pinning to a tagged SPDX release/commit or a vetted snapshot with an explicit refresh step.

dependency-radar.json (1)

1-4612: Consider normalizing environment-specific fields if this is a committed fixture.

Fields like generatedAt, branch, and projectDir are machine-specific and will churn; if this file is meant as a stable sample, scrub or relocate it under test fixtures.

Comment thread scripts/build-spdx.ts Outdated
Comment on lines +29 to +49
async function fetchJson<T>(url: string): Promise<T> {
return new Promise((resolve, reject) => {
https
.get(url, (res) => {
if (res.statusCode && res.statusCode >= 400) {
reject(new Error(`Failed to fetch ${url} (${res.statusCode})`));
res.resume();
return;
}
const chunks: Buffer[] = [];
res.on('data', (d) => chunks.push(Buffer.from(d)));
res.on('end', () => {
try {
const raw = Buffer.concat(chunks).toString('utf8');
resolve(JSON.parse(raw) as T);
} catch (err) {
reject(err);
}
});
})
.on('error', (err) => reject(err));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, check if the file exists and read the relevant section
fd -e ts "build-spdx" | head -20

Repository: JosephMaynard/dependency-radar

Length of output: 95


🏁 Script executed:

#!/bin/bash
# Find and read the file
find . -name "build-spdx.ts" -type f 2>/dev/null | head -5

Repository: JosephMaynard/dependency-radar

Length of output: 97


🏁 Script executed:

#!/bin/bash
# Search for the fetchJson function
rg "fetchJson" -t ts -A 25 | head -100

Repository: JosephMaynard/dependency-radar

Length of output: 3115


Add timeout + stricter status code validation in fetchJson.

The current implementation lacks a timeout mechanism, allowing the Promise to hang indefinitely on network stalls. Additionally, treating only status ≥ 400 as failures is too lenient—3xx redirects won't auto-follow and may produce unparseable responses; strict 2xx validation (200-299) is more robust.

🛠️ Suggested hardening
   return new Promise((resolve, reject) => {
-    https
-      .get(url, (res) => {
-        if (res.statusCode && res.statusCode >= 400) {
+    const req = https.get(url, (res) => {
+        if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
           reject(new Error(`Failed to fetch ${url} (${res.statusCode})`));
           res.resume();
           return;
         }
         const chunks: Buffer[] = [];
         res.on('data', (d) => chunks.push(Buffer.from(d)));
         res.on('end', () => {
           try {
             const raw = Buffer.concat(chunks).toString('utf8');
             resolve(JSON.parse(raw) as T);
           } catch (err) {
             reject(err);
           }
         });
-      })
-      .on('error', (err) => reject(err));
+      });
+    req.on('error', (err) => reject(err));
+    req.setTimeout(15_000, () => {
+      req.destroy(new Error(`Timeout fetching ${url}`));
+    });
   });
 }
🤖 Prompt for AI Agents
In `@scripts/build-spdx.ts` around lines 29 - 49, fetchJson currently can hang
without a timeout and treats any status <400 as OK; modify fetchJson to enforce
a strict 2xx check and a request timeout: when calling https.get capture the
returned ClientRequest (e.g., const req = https.get(...)), start a timer (e.g.,
10s) that will destroy/abort the request and reject the Promise with a timeout
Error if fired, and ensure the timer is cleared on successful 'end' and on
'error'; inside the response handler validate res.statusCode is between 200 and
299 and reject (and res.resume()) for any other status, and keep the existing
'error' handler but make sure it also clears the timeout before rejecting.

Comment thread src/license.ts
@JosephMaynard
JosephMaynard merged commit f5e9e70 into master Feb 4, 2026
1 check passed
@JosephMaynard
JosephMaynard deleted the fix/pnpm-workspace-scan branch February 4, 2026 19:09
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