mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-28 04:10:44 -04:00
Co-authored-by: Jordan Reimer <zofskeez@gmail.com>
This commit is contained in:
parent
6469a5a312
commit
547255b0d4
2 changed files with 469 additions and 0 deletions
271
ui/DEP_OVERRIDE_REPORT.md
Normal file
271
ui/DEP_OVERRIDE_REPORT.md
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
# 🛡️ PNPM Override Audit Report
|
||||
|
||||
Generated on: 2026-03-19, 10:45:45 a.m.
|
||||
|
||||
## `@babel/runtime`
|
||||
**Target Override:** `7.27.0`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 7.27.0.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `ember-cli-babel@7.26.11` | `7.12.18` |
|
||||
| `ember-cli-babel@8.2.0` | `7.12.18` |
|
||||
|
||||
---
|
||||
## `@embroider/macros`
|
||||
**Target Override:** `1.15.0`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 1.15.0 without the override.
|
||||
|
||||
---
|
||||
## `@messageformat/runtime`
|
||||
**Target Override:** `3.0.2`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 3.0.2 without the override.
|
||||
|
||||
---
|
||||
## `ajv@6.12.6`
|
||||
**Target Override:** `6.14.0`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 6.14.0 without the override.
|
||||
|
||||
---
|
||||
## `ajv@8.17.1`
|
||||
**Target Override:** `8.18.0`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 8.18.0 without the override.
|
||||
|
||||
---
|
||||
## `ansi-html`
|
||||
**Target Override:** `0.0.8`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 0.0.8.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `broccoli-middleware@2.1.1` | `0.0.7` |
|
||||
| `broccoli@3.5.2` | `0.0.7` |
|
||||
|
||||
---
|
||||
## `async`
|
||||
**Target Override:** `2.6.4`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 2.6.4.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `fireworm@0.7.2` | `0.2.10` |
|
||||
|
||||
---
|
||||
## `braces`
|
||||
**Target Override:** `3.0.3`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 3.0.3.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `micromatch@3.1.10` | `2.3.2` |
|
||||
|
||||
---
|
||||
## `eslint-utils`
|
||||
**Target Override:** `1.4.3`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 1.4.3 without the override.
|
||||
|
||||
---
|
||||
## `express`
|
||||
**Target Override:** `4.22.1`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 4.22.1 without the override.
|
||||
|
||||
---
|
||||
## `https-proxy-agent`
|
||||
**Target Override:** `2.2.4`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 2.2.4 without the override.
|
||||
|
||||
---
|
||||
## `ini`
|
||||
**Target Override:** `1.3.8`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 1.3.8 without the override.
|
||||
|
||||
---
|
||||
## `json5`
|
||||
**Target Override:** `1.0.2`
|
||||
|
||||
❓ **UNKNOWN (Error)**
|
||||
|
||||
> The script encountered an error resolving this package:
|
||||
> `Command failed: pnpm list "json5" --recursive --depth Infinity --json`
|
||||
|
||||
---
|
||||
## `kind-of`
|
||||
**Target Override:** `6.0.3`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 6.0.3.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `has-values@1.0.0` | `4.0.0` |
|
||||
| `is-number@3.0.0` | `3.2.2` |
|
||||
| `object-copy@0.1.0` | `3.2.2` |
|
||||
| `snapdragon-util@3.0.1` | `3.2.2` |
|
||||
| `to-object-path@0.3.0` | `3.2.2` |
|
||||
|
||||
---
|
||||
## `markdown-it`
|
||||
**Target Override:** `14.1.1`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 14.1.1.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `ember-cli@5.8.1` | `13.0.2` |
|
||||
| `markdown-it-terminal@0.4.0` | `13.0.2` |
|
||||
|
||||
---
|
||||
## `micromatch`
|
||||
**Target Override:** `4.0.8`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 4.0.8.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `anymatch@2.0.0` | `3.1.10` |
|
||||
| `findup-sync@2.0.0` | `3.1.10` |
|
||||
| `sane@4.1.0` | `3.1.10` |
|
||||
|
||||
---
|
||||
## `minimatch@<3.1.3`
|
||||
**Target Override:** `3.1.5`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 3.1.5 without the override.
|
||||
|
||||
---
|
||||
## `minimatch@>=5.0.0 <5.1.7`
|
||||
**Target Override:** `5.1.9`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 5.1.9 without the override.
|
||||
|
||||
---
|
||||
## `minimatch@>=7.0.0 <7.4.7`
|
||||
**Target Override:** `7.4.9`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 7.4.9 without the override.
|
||||
|
||||
---
|
||||
## `minimatch@>=8.0.0 <8.0.5`
|
||||
**Target Override:** `8.0.7`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 8.0.7 without the override.
|
||||
|
||||
---
|
||||
## `minimatch@>=9.0.0 <9.0.6`
|
||||
**Target Override:** `9.0.9`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 9.0.9 without the override.
|
||||
|
||||
---
|
||||
## `prismjs`
|
||||
**Target Override:** `1.30.0`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 1.30.0 without the override.
|
||||
|
||||
---
|
||||
## `qs`
|
||||
**Target Override:** `6.14.1`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 6.14.1.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `body-parser@1.20.3` | `6.13.0` |
|
||||
|
||||
---
|
||||
## `rollup`
|
||||
**Target Override:** `2.80.0`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 2.80.0.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `@rollup/plugin-replace@2.3.0` | `1.32.1` |
|
||||
| `broccoli-rollup@4.0.0` | `1.32.1` |
|
||||
|
||||
---
|
||||
## `serialize-javascript`
|
||||
**Target Override:** `3.1.0`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 3.1.0 without the override.
|
||||
|
||||
---
|
||||
## `socket.io`
|
||||
**Target Override:** `4.8.1`
|
||||
|
||||
✅ **SAFE TO REMOVE**
|
||||
|
||||
> All packages naturally resolve to >= 4.8.1 without the override.
|
||||
|
||||
---
|
||||
## `underscore`
|
||||
**Target Override:** `1.13.7`
|
||||
|
||||
⚠️ **REQUIRED**
|
||||
|
||||
> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= 1.13.7.
|
||||
|
||||
| Parent Package | Naturally Resolved Version |
|
||||
| :--- | :--- |
|
||||
| `nomnom@1.8.1` | `1.6.0` |
|
||||
|
||||
---
|
||||
198
ui/scripts/gen-dep-override-report.js
Normal file
198
ui/scripts/gen-dep-override-report.js
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
/* eslint-env node */
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
const ROOT_DIR = path.join(__dirname, '..');
|
||||
const PKG_PATH = path.join(ROOT_DIR, 'package.json');
|
||||
const LOCK_PATH = path.join(ROOT_DIR, 'pnpm-lock.yaml');
|
||||
|
||||
/**
|
||||
* Simple exact-version comparison.
|
||||
* Returns true if the resolved version is older than the target override.
|
||||
*/
|
||||
function isOlder(found, target) {
|
||||
if (!found || !target) return false;
|
||||
const f = found
|
||||
.replace(/[^0-9.]/g, '')
|
||||
.split('.')
|
||||
.map((n) => parseInt(n || 0));
|
||||
const t = target
|
||||
.replace(/[^0-9.]/g, '')
|
||||
.split('.')
|
||||
.map((n) => parseInt(n || 0));
|
||||
for (let i = 0; i < Math.max(f.length, t.length); i++) {
|
||||
if ((f[i] || 0) < (t[i] || 0)) return true;
|
||||
if ((f[i] || 0) > (t[i] || 0)) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function writeReport(report, error) {
|
||||
const outPath = path.join(ROOT_DIR, 'DEP_OVERRIDE_REPORT.md');
|
||||
fs.writeFileSync(outPath, report);
|
||||
const message =
|
||||
error || '✅ Dependency override audit complete! Project has been restored to its original state.';
|
||||
console.log(message);
|
||||
console.log('📄 See DEP_OVERRIDE_REPORT.md for details.');
|
||||
}
|
||||
|
||||
function genOverrideReport() {
|
||||
console.log('🚀 Starting Dependency Override Audit. Backing up package.json...');
|
||||
|
||||
let report = '# 🛡️ PNPM Override Audit Report\n\n';
|
||||
report += `Generated on: ${new Date().toLocaleString()}\n\n`;
|
||||
|
||||
if (!fs.existsSync(PKG_PATH)) {
|
||||
report += `❌ **Error:** package.json not found at ${PKG_PATH}\n`;
|
||||
writeReport(report, '❌ package.json not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Read and backup the original state
|
||||
const originalPkgStr = fs.readFileSync(PKG_PATH, 'utf8');
|
||||
const originalLockStr = fs.existsSync(LOCK_PATH) ? fs.readFileSync(LOCK_PATH, 'utf8') : null;
|
||||
|
||||
const pkgJson = JSON.parse(originalPkgStr);
|
||||
const overrides = pkgJson.pnpm?.overrides || {};
|
||||
|
||||
if (Object.keys(overrides).length === 0) {
|
||||
report += '✅ **No overrides found in package.json.**\n';
|
||||
writeReport(report);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. Strip overrides and save the modified package.json
|
||||
const tempPkgJson = JSON.parse(originalPkgStr);
|
||||
delete tempPkgJson.pnpm.overrides;
|
||||
fs.writeFileSync(PKG_PATH, JSON.stringify(tempPkgJson, null, 2));
|
||||
|
||||
// 3. Reinstall dependencies to recalculate lockfile AND physically update node_modules
|
||||
console.log('⏳ Relinking node_modules to their natural state (this may take a minute)...');
|
||||
execSync('pnpm install --no-frozen-lockfile --ignore-scripts', {
|
||||
cwd: ROOT_DIR,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
|
||||
// 4. Audit each removed override using pnpm list
|
||||
for (const [overrideName, targetVersion] of Object.entries(overrides)) {
|
||||
console.log(`🔎 Auditing natural resolution for ${overrideName}...`);
|
||||
const culprits = new Map();
|
||||
|
||||
let rawJson;
|
||||
try {
|
||||
rawJson = execSync(`pnpm list "${overrideName}" --recursive --depth Infinity --json`, {
|
||||
cwd: ROOT_DIR,
|
||||
maxBuffer: 1024 * 1024 * 100,
|
||||
}).toString();
|
||||
} catch (e) {
|
||||
console.error(`└──⚠️ Could not fetch tree for ${overrideName}.`);
|
||||
// execSync attaches stdout and stderr to the error object when a command fails
|
||||
const stdout = e.stdout ? e.stdout.toString().trim() : '';
|
||||
const stderr = e.stderr ? e.stderr.toString().trim() : '';
|
||||
|
||||
report += `## \`${overrideName}\`\n**Target Override:** \`${targetVersion}\`\n\n`;
|
||||
|
||||
// If pnpm exited with 1 but output an empty JSON array, it means "Not Found"
|
||||
if (stdout === '[]') {
|
||||
report += `✅ **SAFE TO REMOVE (Orphaned)**\n\n`;
|
||||
report += `> This package does not exist anywhere in the naturally resolved dependency tree. It was likely removed by an upstream dependency update.\n`;
|
||||
} else if (e.code === 'ENOBUFS') {
|
||||
report += `❓ **UNKNOWN (Buffer Overflow)**\n\n`;
|
||||
report += `> The dependency tree is too large for the allocated memory.\n`;
|
||||
} else {
|
||||
const errorMsg = stderr || e.message;
|
||||
report += `❓ **UNKNOWN (Error)**\n\n`;
|
||||
report += `> The script encountered an error resolving this package:\n> \`${errorMsg}\`\n`;
|
||||
}
|
||||
|
||||
report += `\n---\n`;
|
||||
continue; // Immediately jump to the next override in the loop
|
||||
}
|
||||
|
||||
const data = JSON.parse(rawJson);
|
||||
|
||||
const scanTree = (parentName, parentVersion, depsObject) => {
|
||||
if (!depsObject) return;
|
||||
|
||||
for (const [depName, depInfo] of Object.entries(depsObject)) {
|
||||
if (!depInfo) continue;
|
||||
|
||||
if (depName === overrideName && depInfo.version) {
|
||||
const resolvedVersion = depInfo.version;
|
||||
|
||||
if (isOlder(resolvedVersion, targetVersion)) {
|
||||
culprits.set(`${parentName}@${parentVersion}`, resolvedVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// If this dependency has its own dependencies, it becomes the new parent
|
||||
if (depInfo.dependencies) {
|
||||
scanTree(depName, depInfo.version, depInfo.dependencies);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Start the scan from the top-level workspaces/projects
|
||||
data.forEach((project) => {
|
||||
const projectName = project.name || 'Root Project';
|
||||
const projectVersion = project.version || 'unknown';
|
||||
const allDeps = {
|
||||
...project.dependencies,
|
||||
...project.devDependencies,
|
||||
...project.optionalDependencies,
|
||||
};
|
||||
|
||||
scanTree(projectName, projectVersion, allDeps);
|
||||
});
|
||||
|
||||
// Generate markdown segment
|
||||
report += `## \`${overrideName}\`\n**Target Override:** \`${targetVersion}\`\n\n`;
|
||||
if (culprits.size > 0) {
|
||||
report += `⚠️ **REQUIRED**\n\n`;
|
||||
report += `> These packages will continue to receive the overridden version until they are updated to naturally resolve to >= ${targetVersion}.\n\n`;
|
||||
report += `| Parent Package | Naturally Resolved Version |\n| :--- | :--- |\n`;
|
||||
const sortedCulprits = Array.from(culprits.entries()).sort();
|
||||
for (const [parent, resolved] of sortedCulprits) {
|
||||
report += `| \`${parent}\` | \`${resolved}\` |\n`;
|
||||
}
|
||||
} else {
|
||||
report += `✅ **SAFE TO REMOVE**\n\n`;
|
||||
report += `> All packages naturally resolve to >= ${targetVersion} without the override.\n`;
|
||||
}
|
||||
report += `\n---\n`;
|
||||
}
|
||||
} finally {
|
||||
// 5. Restore original package.json, lockfile, and node_modules
|
||||
console.log('🧹 Cleaning up: Restoring package.json, lockfile, and node_modules...');
|
||||
|
||||
// Put the files back
|
||||
fs.writeFileSync(PKG_PATH, originalPkgStr);
|
||||
if (originalLockStr) {
|
||||
fs.writeFileSync(LOCK_PATH, originalLockStr);
|
||||
}
|
||||
|
||||
// Run a full install again to force pnpm to re-apply overrides to node_modules
|
||||
try {
|
||||
execSync('pnpm install --no-frozen-lockfile --ignore-scripts', {
|
||||
cwd: ROOT_DIR,
|
||||
stdio: 'ignore',
|
||||
});
|
||||
} catch (e) {
|
||||
console.error("⚠️ Cleanup failed, you may need to run 'pnpm install' manually.");
|
||||
}
|
||||
|
||||
// Write the report
|
||||
writeReport(report);
|
||||
}
|
||||
}
|
||||
|
||||
genOverrideReport();
|
||||
Loading…
Reference in a new issue