Skip to content

Commit 383a96c

Browse files
committed
fix: restore use of getUserInstructionDeps
1 parent 0969ac7 commit 383a96c

File tree

2 files changed

+187
-468
lines changed

2 files changed

+187
-468
lines changed

lib/response-builder.ts

Lines changed: 47 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@ import * as types from "./types";
1212
import { truncateAdditionalFacts } from "./utils";
1313
import { PLUGIN_VERSION } from "./version";
1414

15-
export {
16-
buildResponse,
17-
annotateWithLayerIds,
18-
expandDockerfilePackages,
19-
excludeBaseImageDeps,
20-
};
15+
export { buildResponse };
2116

2217
async function buildResponse(
2318
depsAnalysis: StaticAnalysis & {
@@ -32,24 +27,30 @@ async function buildResponse(
3227
): Promise<types.PluginResponse> {
3328
const deps = depsAnalysis.depTree.dependencies;
3429

35-
const inputDockerfilePkgs =
36-
dockerfileAnalysis?.dockerfilePackages ??
37-
depsAnalysis.autoDetectedUserInstructions?.dockerfilePackages;
38-
39-
if (inputDockerfilePkgs) {
40-
const expandedDockerfilePkgs = expandDockerfilePackages(
41-
inputDockerfilePkgs,
30+
// Expand dockerfile packages and auto detected user instructions if
31+
// they are provided. These objects are mutated in place, ensuring the
32+
// expanded packages are used in the subsequent steps and fact building.
33+
if (dockerfileAnalysis?.dockerfilePackages) {
34+
getUserInstructionDeps(dockerfileAnalysis.dockerfilePackages, deps);
35+
}
36+
if (depsAnalysis.autoDetectedUserInstructions?.dockerfilePackages) {
37+
getUserInstructionDeps(
38+
depsAnalysis.autoDetectedUserInstructions.dockerfilePackages,
4239
deps,
4340
);
41+
}
42+
43+
const dockerfilePkgs =
44+
dockerfileAnalysis?.dockerfilePackages ??
45+
depsAnalysis.autoDetectedUserInstructions?.dockerfilePackages;
4446

47+
if (dockerfilePkgs) {
4548
const finalDeps = excludeBaseImageDeps(
4649
deps,
47-
expandedDockerfilePkgs,
50+
dockerfilePkgs,
4851
excludeBaseImageVulns,
4952
);
50-
annotateWithLayerIds(finalDeps, expandedDockerfilePkgs);
51-
52-
// Assign the final dependencies to the dependency tree.
53+
annotateLayerIds(finalDeps, dockerfilePkgs);
5354
depsAnalysis.depTree.dependencies = finalDeps;
5455
}
5556

@@ -78,9 +79,6 @@ async function buildResponse(
7879
}
7980

8081
if (dockerfileAnalysis !== undefined) {
81-
// Use legacy expansion function to maintain downstream compatibility.
82-
getUserInstructionDeps(dockerfileAnalysis.dockerfilePackages, deps);
83-
8482
const dockerfileAnalysisFact: facts.DockerfileAnalysisFact = {
8583
type: "dockerfileAnalysis",
8684
data: dockerfileAnalysis,
@@ -218,17 +216,12 @@ async function buildResponse(
218216
autoDetectedLayers &&
219217
Object.keys(autoDetectedLayers).length > 0
220218
) {
221-
const autoDetectedPackagesWithChildren = getUserInstructionDeps(
222-
autoDetectedPackages,
223-
deps,
224-
);
225-
226219
const autoDetectedUserInstructionsFact: facts.AutoDetectedUserInstructionsFact =
227220
{
228221
type: "autoDetectedUserInstructions",
229222
data: {
230223
dockerfileLayers: autoDetectedLayers,
231-
dockerfilePackages: autoDetectedPackagesWithChildren!,
224+
dockerfilePackages: autoDetectedPackages,
232225
},
233226
};
234227
additionalFacts.push(autoDetectedUserInstructionsFact);
@@ -361,7 +354,6 @@ async function buildResponse(
361354
}
362355

363356
/**
364-
* @deprecated This function is deprecated and will be removed in a future version.
365357
* Expands the provided dockerfile packages to include transitive dependencies.
366358
* Transitive dependencies are keyed by their source segments.
367359
*
@@ -390,7 +382,6 @@ function getUserInstructionDeps(
390382

391383
if (dockerfilePackage) {
392384
for (const dep of collectDeps(dependencies[dependencyName])) {
393-
// Transitive dependencies are keyed by their source segments.
394385
dockerfilePackages[dep.split("/")[0]] = { ...dockerfilePackage };
395386
}
396387
}
@@ -411,59 +402,6 @@ function collectDeps(pkg) {
411402
: [];
412403
}
413404

414-
/**
415-
* Returns the package source name from a full dependency name.
416-
*
417-
* A package source refers to the top-level package name, such as "foo" in "foo/foo-dev".
418-
*
419-
* @param depName - The full dependency name.
420-
* @returns The package source name.
421-
*/
422-
function packageSource(depName: string): string {
423-
return depName.split("/")[0];
424-
}
425-
426-
/**
427-
* Expands the list of packages explicitly requested in the Dockerfile to include all transitive dependencies.
428-
* The returned package map is keyed by the full dependency names.
429-
*
430-
* @param dockerfilePackages - The packages explicitly requested in a Dockerfile.
431-
* @param deps - The dependencies of the image.
432-
* @returns A map of packages attributed to the Dockerfile.
433-
*/
434-
function expandDockerfilePackages(
435-
dockerfilePackages: DockerFilePackages,
436-
deps: { [depName: string]: types.DepTreeDep },
437-
): DockerFilePackages {
438-
const expandedPkgs = {};
439-
440-
function collectChildPackages(node: types.DepTreeDep, parentEntry: any) {
441-
if (!node.dependencies) {
442-
return;
443-
}
444-
for (const childKey of Object.keys(node.dependencies)) {
445-
if (!expandedPkgs[childKey]) {
446-
expandedPkgs[childKey] = parentEntry;
447-
collectChildPackages(node.dependencies[childKey], parentEntry);
448-
}
449-
}
450-
}
451-
452-
for (const rootKey of Object.keys(deps)) {
453-
const source = packageSource(rootKey);
454-
const dockerfileEntry =
455-
dockerfilePackages[rootKey] || dockerfilePackages[source];
456-
if (dockerfileEntry) {
457-
// All keys in the expanded packages are the full dependency names.
458-
expandedPkgs[rootKey] = dockerfileEntry;
459-
460-
collectChildPackages(deps[rootKey], dockerfileEntry);
461-
}
462-
}
463-
464-
return expandedPkgs;
465-
}
466-
467405
/**
468406
* Excludes base image dependencies from the dependency tree if excludeBaseImageVulns is true.
469407
*
@@ -484,50 +422,51 @@ function excludeBaseImageDeps(
484422
}
485423

486424
return Object.keys(deps)
487-
.filter((depName) => dockerfilePkgs[depName])
425+
.filter((depName) => {
426+
if (dockerfilePkgs[depName] !== undefined) {
427+
return true;
428+
}
429+
const source = depName.split("/")[0];
430+
return dockerfilePkgs[source] !== undefined;
431+
})
488432
.reduce((extractedDeps, depName) => {
489433
extractedDeps[depName] = deps[depName];
490434
return extractedDeps;
491435
}, {});
492436
}
493437

494438
/**
495-
* Annotates the dependency tree with layer IDs.
496-
*
439+
* Annotates the dependencies with the layer ID of the Dockerfile
440+
* instruction that installed them.
441+
*
497442
* @important
498443
* mutates the provided `deps` object.
499-
*
444+
500445
* @param deps - The dependencies of the image.
501446
* @param dockerfilePkgs - The expanded packages attributed to the Dockerfile.
502447
*/
503-
function annotateWithLayerIds(
504-
deps: { [depName: string]: types.DepTreeDep },
448+
function annotateLayerIds(
449+
deps: {
450+
[depName: string]: types.DepTreeDep;
451+
},
505452
dockerfilePkgs: DockerFilePackages | undefined,
506-
): void {
453+
) {
507454
if (!dockerfilePkgs) {
508455
return;
509456
}
510457

511-
function annotateRecursive(currentDeps: {
512-
[depName: string]: types.DepTreeDep;
513-
}) {
514-
for (const depKey of Object.keys(currentDeps)) {
515-
const node = currentDeps[depKey];
516-
const dockerfileEntry = dockerfilePkgs![depKey];
517-
518-
if (dockerfileEntry) {
519-
node.labels = {
520-
...(node.labels || {}),
521-
dockerLayerId: instructionDigest(dockerfileEntry.instruction),
522-
};
523-
524-
// Only progress down the dependency tree if the current node is a dockerfile package.
525-
if (node.dependencies) {
526-
annotateRecursive(node.dependencies);
527-
}
528-
}
458+
for (const dep of Object.keys(deps)) {
459+
const pkg = deps[dep];
460+
const pkgSource = dep.split("/")[0];
461+
const dockerfilePkg = dockerfilePkgs[dep] || dockerfilePkgs[pkgSource];
462+
if (dockerfilePkg) {
463+
pkg.labels = {
464+
...(pkg.labels || {}),
465+
dockerLayerId: instructionDigest(dockerfilePkg.instruction),
466+
};
467+
}
468+
if (pkg.dependencies) {
469+
annotateLayerIds(pkg.dependencies, dockerfilePkgs);
529470
}
530471
}
531-
532-
annotateRecursive(deps);
533472
}

0 commit comments

Comments
 (0)