Merge pull request #6 from actions/weekly-sync-branch-16171136386
Some checks failed
Test / test (push) Has been cancelled

Sync Fork with Upstream
This commit is contained in:
Lewis Jones
2025-07-09 14:49:18 +01:00
committed by GitHub
7 changed files with 128 additions and 34 deletions

View File

@@ -86,12 +86,12 @@ describe("ComponentDetection.processComponentsToManifests", () => {
},
isDevelopmentDependency: false,
topLevelReferrers: [], // Empty = direct dependency
locationsFoundAt: ["/package.json"]
locationsFoundAt: ["package.json"]
}
];
const dependencyGraphs: DependencyGraphs = {
"/package.json": {
"package.json": {
graph: { "test-package": null },
explicitlyReferencedComponentIds: ["test-package 1.0.0 - npm"],
developmentDependencies: [],
@@ -102,7 +102,7 @@ describe("ComponentDetection.processComponentsToManifests", () => {
const manifests = ComponentDetection.processComponentsToManifests(componentsFound, dependencyGraphs);
expect(manifests).toHaveLength(1);
expect(manifests[0].name).toBe("/package.json");
expect(manifests[0].name).toBe("package.json");
expect(manifests[0].directDependencies()).toHaveLength(1);
expect(manifests[0].indirectDependencies()).toHaveLength(0);
expect(manifests[0].countDependencies()).toBe(1);
@@ -135,12 +135,12 @@ describe("ComponentDetection.processComponentsToManifests", () => {
}
}
],
locationsFoundAt: ["/package.json"]
locationsFoundAt: ["package.json"]
}
];
const dependencyGraphs: DependencyGraphs = {
"/package.json": {
"package.json": {
graph: { "parent-package": null },
explicitlyReferencedComponentIds: [],
developmentDependencies: [],
@@ -151,7 +151,7 @@ describe("ComponentDetection.processComponentsToManifests", () => {
const manifests = ComponentDetection.processComponentsToManifests(componentsFound, dependencyGraphs);
expect(manifests).toHaveLength(1);
expect(manifests[0].name).toBe("/package.json");
expect(manifests[0].name).toBe("package.json");
expect(manifests[0].directDependencies()).toHaveLength(0);
expect(manifests[0].indirectDependencies()).toHaveLength(1);
expect(manifests[0].countDependencies()).toBe(1);
@@ -184,10 +184,10 @@ describe('normalizeDependencyGraphPaths', () => {
const normalized = ComponentDetection.normalizeDependencyGraphPaths(dependencyGraphs, filePathInput);
// Restore process.cwd
(process as any).cwd = originalCwd;
expect(Object.keys(normalized)).toContain('/a/package.json');
expect(Object.keys(normalized)).toContain('/b/package.json');
expect(normalized['/a/package.json'].graph).toEqual({ 'foo': null });
expect(normalized['/b/package.json'].graph).toEqual({ 'bar': null });
expect(Object.keys(normalized)).toContain('a/package.json');
expect(Object.keys(normalized)).toContain('b/package.json');
expect(normalized['a/package.json'].graph).toEqual({ 'foo': null });
expect(normalized['b/package.json'].graph).toEqual({ 'bar': null });
});
});
@@ -197,13 +197,50 @@ describe('normalizeDependencyGraphPaths with real output.json', () => {
const dependencyGraphs = output.dependencyGraphs;
// Use the same filePath as the action default (".")
const normalized = ComponentDetection.normalizeDependencyGraphPaths(dependencyGraphs, 'test');
// Should contain /package.json and /package-lock.json as keys
expect(Object.keys(normalized)).toContain('/package.json');
expect(Object.keys(normalized)).toContain('/package-lock.json');
// All keys should now be relative to the repo root (cwd) and start with '/'
// Should contain root level manifests without leading slashes
expect(Object.keys(normalized)).toContain('package.json');
expect(Object.keys(normalized)).toContain('package-lock.json');
// Should contain nested manifests with relative paths (no leading slashes)
expect(Object.keys(normalized)).toContain('nested/package.json');
expect(Object.keys(normalized)).toContain('nested/package-lock.json');
// All keys should be relative paths without leading slashes
for (const key of Object.keys(normalized)) {
expect(key.startsWith('/')).toBe(true);
expect(key.startsWith('/')).toBe(false); // No leading slashes
expect(key).not.toMatch(/^\w:\\|^\/\/|^\.{1,2}\//); // Not windows absolute, not network, not relative
}
});
});
test('full action scan creates manifests with correct names and file source locations', async () => {
await ComponentDetection.downloadLatestRelease();
const manifests = await ComponentDetection.scanAndGetManifests('./test');
expect(manifests).toBeDefined();
expect(manifests!.length).toBeGreaterThan(0);
for (const manifest of manifests!) {
expect(manifest.name.startsWith('/')).toBe(false);
}
const expectedManifestNames = [
'package.json',
'package-lock.json',
'nested/package.json',
'nested/package-lock.json',
];
const manifestsByName = manifests!.reduce((acc, manifest) => {
acc[manifest.name] = manifest;
return acc;
}, {} as Record<string, any>);
for (const expectedName of expectedManifestNames) {
const manifest = manifestsByName[expectedName];
expect(manifest).toBeDefined();
expect(manifest.name).toBe(expectedName);
expect(manifest.file?.source_location).toBe(expectedName);
}
}, 15000);

View File

@@ -153,28 +153,31 @@ export default class ComponentDetection {
private static addPackagesToManifests(packages: Array<ComponentDetectionPackage>, manifests: Array<Manifest>, dependencyGraphs: DependencyGraphs): void {
packages.forEach((pkg: ComponentDetectionPackage) => {
pkg.locationsFoundAt.forEach((location: any) => {
if (!manifests.find((manifest: Manifest) => manifest.name == location)) {
const manifest = new Manifest(location, location);
// Use the normalized path (remove leading slash if present)
const normalizedLocation = location.startsWith('/') ? location.substring(1) : location;
if (!manifests.find((manifest: Manifest) => manifest.name == normalizedLocation)) {
const manifest = new Manifest(normalizedLocation, normalizedLocation);
manifests.push(manifest);
}
const depGraphEntry = dependencyGraphs[location];
const depGraphEntry = dependencyGraphs[normalizedLocation];
if (!depGraphEntry) {
core.warning(`No dependency graph entry found for manifest location: ${location}`);
core.warning(`No dependency graph entry found for manifest location: ${normalizedLocation}`);
return; // Skip this location if not found in dependencyGraphs
}
const directDependencies = depGraphEntry.explicitlyReferencedComponentIds;
if (directDependencies.includes(pkg.id)) {
manifests
.find((manifest: Manifest) => manifest.name == location)
.find((manifest: Manifest) => manifest.name == normalizedLocation)
?.addDirectDependency(
pkg,
ComponentDetection.getDependencyScope(pkg)
);
} else {
manifests
.find((manifest: Manifest) => manifest.name == location)
.find((manifest: Manifest) => manifest.name == normalizedLocation)
?.addIndirectDependency(
pkg,
ComponentDetection.getDependencyScope(pkg)
@@ -283,8 +286,6 @@ export default class ComponentDetection {
for (const absPath in dependencyGraphs) {
// Make the path relative to the baseDir
let relPath = path.relative(baseDir, absPath).replace(/\\/g, '/');
// Ensure leading slash to represent repo root
if (!relPath.startsWith('/')) relPath = '/' + relPath;
normalized[relPath] = dependencyGraphs[absPath];
}
return normalized;

17
dist/index.js generated vendored
View File

@@ -36128,23 +36128,25 @@ class ComponentDetection {
packages.forEach((pkg) => {
pkg.locationsFoundAt.forEach((location) => {
var _a, _b;
if (!manifests.find((manifest) => manifest.name == location)) {
const manifest = new dependency_submission_toolkit_1.Manifest(location, location);
// Use the normalized path (remove leading slash if present)
const normalizedLocation = location.startsWith('/') ? location.substring(1) : location;
if (!manifests.find((manifest) => manifest.name == normalizedLocation)) {
const manifest = new dependency_submission_toolkit_1.Manifest(normalizedLocation, normalizedLocation);
manifests.push(manifest);
}
const depGraphEntry = dependencyGraphs[location];
const depGraphEntry = dependencyGraphs[normalizedLocation];
if (!depGraphEntry) {
core.warning(`No dependency graph entry found for manifest location: ${location}`);
core.warning(`No dependency graph entry found for manifest location: ${normalizedLocation}`);
return; // Skip this location if not found in dependencyGraphs
}
const directDependencies = depGraphEntry.explicitlyReferencedComponentIds;
if (directDependencies.includes(pkg.id)) {
(_a = manifests
.find((manifest) => manifest.name == location)) === null || _a === void 0 ? void 0 : _a.addDirectDependency(pkg, ComponentDetection.getDependencyScope(pkg));
.find((manifest) => manifest.name == normalizedLocation)) === null || _a === void 0 ? void 0 : _a.addDirectDependency(pkg, ComponentDetection.getDependencyScope(pkg));
}
else {
(_b = manifests
.find((manifest) => manifest.name == location)) === null || _b === void 0 ? void 0 : _b.addIndirectDependency(pkg, ComponentDetection.getDependencyScope(pkg));
.find((manifest) => manifest.name == normalizedLocation)) === null || _b === void 0 ? void 0 : _b.addIndirectDependency(pkg, ComponentDetection.getDependencyScope(pkg));
}
});
});
@@ -36237,9 +36239,6 @@ class ComponentDetection {
for (const absPath in dependencyGraphs) {
// Make the path relative to the baseDir
let relPath = path_1.default.relative(baseDir, absPath).replace(/\\/g, '/');
// Ensure leading slash to represent repo root
if (!relPath.startsWith('/'))
relPath = '/' + relPath;
normalized[relPath] = dependencyGraphs[absPath];
}
return normalized;

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "component-detection-action",
"version": "0.0.7",
"version": "0.1.0",
"description": "Component detection action",
"main": "dist/index.js",
"type": "module",

45
test/nested/package-lock.json generated Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "nested-test-package",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "nested-test-package",
"version": "1.0.0",
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {
"jest": "^29.0.0"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
"bin": {
"jest": "bin/jest.js"
}
}
},
"dependencies": {
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true
}
}
}

12
test/nested/package.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "nested-test-package",
"version": "1.0.0",
"description": "A nested test package for component detection testing",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {
"jest": "^29.0.0"
}
}