Skip to content

Commit 59abe7e

Browse files
committed
fix: restore use of getUserInstructionDeps
1 parent 7349c56 commit 59abe7e

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

@@ -71,9 +72,6 @@ async function buildResponse(
7172
}
7273

7374
if (dockerfileAnalysis !== undefined) {
74-
// Use legacy expansion function to maintain downstream compatibility.
75-
getUserInstructionDeps(dockerfileAnalysis.dockerfilePackages, deps);
76-
7775
const dockerfileAnalysisFact: facts.DockerfileAnalysisFact = {
7876
type: "dockerfileAnalysis",
7977
data: dockerfileAnalysis,
@@ -211,17 +209,12 @@ async function buildResponse(
211209
autoDetectedLayers &&
212210
Object.keys(autoDetectedLayers).length > 0
213211
) {
214-
const autoDetectedPackagesWithChildren = getUserInstructionDeps(
215-
autoDetectedPackages,
216-
deps,
217-
);
218-
219212
const autoDetectedUserInstructionsFact: facts.AutoDetectedUserInstructionsFact =
220213
{
221214
type: "autoDetectedUserInstructions",
222215
data: {
223216
dockerfileLayers: autoDetectedLayers,
224-
dockerfilePackages: autoDetectedPackagesWithChildren!,
217+
dockerfilePackages: autoDetectedPackages,
225218
},
226219
};
227220
additionalFacts.push(autoDetectedUserInstructionsFact);
@@ -354,7 +347,6 @@ async function buildResponse(
354347
}
355348

356349
/**
357-
* @deprecated This function is deprecated and will be removed in a future version.
358350
* Expands the provided dockerfile packages to include transitive dependencies.
359351
* Transitive dependencies are keyed by their source segments.
360352
*
@@ -383,7 +375,6 @@ function getUserInstructionDeps(
383375

384376
if (dockerfilePackage) {
385377
for (const dep of collectDeps(dependencies[dependencyName])) {
386-
// Transitive dependencies are keyed by their source segments.
387378
dockerfilePackages[dep.split("/")[0]] = { ...dockerfilePackage };
388379
}
389380
}
@@ -404,59 +395,6 @@ function collectDeps(pkg) {
404395
: [];
405396
}
406397

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

479417
return Object.keys(deps)
480-
.filter((depName) => dockerfilePkgs[depName])
418+
.filter((depName) => {
419+
if (dockerfilePkgs[depName] !== undefined) {
420+
return true;
421+
}
422+
const source = depName.split("/")[0];
423+
return dockerfilePkgs[source] !== undefined;
424+
})
481425
.reduce((extractedDeps, depName) => {
482426
extractedDeps[depName] = deps[depName];
483427
return extractedDeps;
484428
}, {});
485429
}
486430

487431
/**
488-
* Annotates the dependency tree with layer IDs.
489-
*
432+
* Annotates the dependencies with the layer ID of the Dockerfile
433+
* instruction that installed them.
434+
*
490435
* @important
491436
* mutates the provided `deps` object.
492-
*
437+
493438
* @param deps - The dependencies of the image.
494439
* @param dockerfilePkgs - The expanded packages attributed to the Dockerfile.
495440
*/
496-
function annotateWithLayerIds(
497-
deps: { [depName: string]: types.DepTreeDep },
441+
function annotateLayerIds(
442+
deps: {
443+
[depName: string]: types.DepTreeDep;
444+
},
498445
dockerfilePkgs: DockerFilePackages | undefined,
499-
): void {
446+
) {
500447
if (!dockerfilePkgs) {
501448
return;
502449
}
503450

504-
function annotateRecursive(currentDeps: {
505-
[depName: string]: types.DepTreeDep;
506-
}) {
507-
for (const depKey of Object.keys(currentDeps)) {
508-
const node = currentDeps[depKey];
509-
const dockerfileEntry = dockerfilePkgs![depKey];
510-
511-
if (dockerfileEntry) {
512-
node.labels = {
513-
...(node.labels || {}),
514-
dockerLayerId: instructionDigest(dockerfileEntry.instruction),
515-
};
516-
517-
// Only progress down the dependency tree if the current node is a dockerfile package.
518-
if (node.dependencies) {
519-
annotateRecursive(node.dependencies);
520-
}
521-
}
451+
for (const dep of Object.keys(deps)) {
452+
const pkg = deps[dep];
453+
const pkgSource = dep.split("/")[0];
454+
const dockerfilePkg = dockerfilePkgs[dep] || dockerfilePkgs[pkgSource];
455+
if (dockerfilePkg) {
456+
pkg.labels = {
457+
...(pkg.labels || {}),
458+
dockerLayerId: instructionDigest(dockerfilePkg.instruction),
459+
};
460+
}
461+
if (pkg.dependencies) {
462+
annotateLayerIds(pkg.dependencies, dockerfilePkgs);
522463
}
523464
}
524-
525-
annotateRecursive(deps);
526465
}

0 commit comments

Comments
 (0)