Skip to content

Commit

Permalink
feat: support --print-graph with mvn-plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
dekelund committed May 10, 2024
1 parent 46769cc commit e6bc660
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 8 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
"snyk-go-plugin": "1.23.0",
"snyk-gradle-plugin": "4.1.0",
"snyk-module": "3.1.0",
"snyk-mvn-plugin": "3.4.2",
"snyk-mvn-plugin": "3.5.0",
"snyk-nodejs-lockfile-parser": "1.56.0",
"snyk-nodejs-plugin": "1.1.0",
"snyk-nuget-plugin": "2.4.5",
Expand Down
35 changes: 35 additions & 0 deletions test/acceptance/fake-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -667,15 +667,49 @@ export const fakeServer = (basePath: string, snykToken: string): FakeServer => {

let bom: Record<string, any> = { bomFormat: 'CycloneDX' };

interface dependency {
ref: string;
dependsOn: string[];
}

const dependencies: dependency[] = [];

const extractDependencies = (nodeIdMap: { [key: string]: string }, element: any) => {
dependencies.push({
ref: element.pkgId,
dependsOn: element.deps.map((d: any) => nodeIdMap[d.nodeId]),
});
}

if (Array.isArray(depGraphs) && req.body.subject) {
// Return a fixture of an all-projects SBOM.
name = req.body.subject.name;
components = depGraphs
.flatMap(({ pkgs }) => pkgs)
.map(({ info: { name } }) => ({ name }));

const nodeIdMap: { [key: string]: string } = {};

depGraphs.forEach((g: any) => {
g.graph.nodes.forEach((element: any) => {
nodeIdMap[element.nodeId] = element.pkgId;
});
});

depGraphs.forEach((g: any) => {
g.graph.nodes.forEach((e: any) => extractDependencies(nodeIdMap, e));
});
} else if (depGraph) {
name = depGraph.pkgs[0]?.info.name;
components = depGraph.pkgs.map(({ info: { name } }) => ({ name }));

const nodeIdMap: { [key: string]: string } = {};

depGraph.graph.nodes.forEach((element: any) => {
nodeIdMap[element.nodeId] = element.pkgId;
});

depGraph.graph.nodes.forEach((e: any) => extractDependencies(nodeIdMap, e));
}

switch (req.query.format) {
Expand All @@ -692,6 +726,7 @@ export const fakeServer = (basePath: string, snykToken: string): FakeServer => {
specVersion: '1.4',
$schema: 'http://cyclonedx.org/schema/bom-1.4.schema.json',
components,
dependencies: dependencies,
metadata: {
component: { name },
tools: [...tools, { name: 'fake-server', version: '42' }],
Expand Down
34 changes: 34 additions & 0 deletions test/acceptance/workspaces/maven-many-paths/child/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>io.snyk.example</groupId>
<artifactId>child-project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Test project</name>
<description>Test child project for Snyk CLI</description>

<properties>
<axis.version>1.4</axis.version>
</properties>

<dependencies>

<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>${axis.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
38 changes: 38 additions & 0 deletions test/acceptance/workspaces/maven-many-paths/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>io.snyk.example</groupId>
<artifactId>test-project</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Test project</name>
<description>Test project for Snyk CLI</description>

<modules>
<module>child-project</module>
</modules>

<properties>
<axis.version>1.4</axis.version>
</properties>

<dependencies>

<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>${axis.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
34 changes: 34 additions & 0 deletions test/fixtures/maven-print-graph/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>io.snyk.example</groupId>
<artifactId>test-project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Test project</name>
<description>Test project for the Maven CLI plugin</description>

<properties>
<axis.version>1.4</axis.version>
</properties>

<dependencies>

<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>${axis.version}</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
20 changes: 20 additions & 0 deletions test/jest/acceptance/snyk-sbom/maven-options.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ describe('snyk sbom: maven options (mocked server only)', () => {
expect(sbom.components.length).toBeGreaterThanOrEqual(11);
});

test('`sbom --file` generates an SBOM without pruning', async () => {
const sbom = await runSnykSbomCliCycloneDxJsonForFixture(
'maven-print-graph',
'--file=pom.xml',
env,
);

expect(sbom.metadata.component.name).toEqual(
'io.snyk.example:test-project',
);
expect(sbom.dependencies.length).toBeGreaterThanOrEqual(7);
expect(sbom.dependencies[6].ref).toEqual(
'commons-discovery:commons-discovery@0.2',
);
expect(sbom.dependencies[6].dependsOn.length).toEqual(1);
expect(sbom.dependencies[6].dependsOn[0]).toEqual(
'commons-logging:commons-logging@1.0.4',
);
});

test('`sbom --scan-unmanaged --file=<NAME>` generates an SBOM for the specific JAR file', async () => {
const sbom = await runSnykSbomCliCycloneDxJsonForFixture(
'maven-jars',
Expand Down
61 changes: 61 additions & 0 deletions test/jest/acceptance/snyk-test/print-graph.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createProjectFromWorkspace } from '../../util/createProject';
import { runSnykCLI } from '../../util/runSnykCLI';

jest.setTimeout(1000 * 60);

describe('print graph', () => {
test("`snyk test --print-graph` should print a project's dep-graph", async () => {
const project = await createProjectFromWorkspace('npm-package');

const { code, stdout } = await runSnykCLI('test --print-graph', {
cwd: project.path(),
});

expect(code).toEqual(0);
expect(stdout).toMatch('DepGraph data:');
expect(stdout).toMatch('DepGraph target:\npackage-lock.json');
});

test('`snyk test --print-graph` should not prune dependencies', async () => {
const project = await createProjectFromWorkspace('maven-many-paths');

const { code, stdout } = await runSnykCLI('test --print-graph', {
cwd: project.path(),
});

expect(code).toEqual(0);
const depGraph = JSON.parse(
stdout.split('DepGraph data:')[1]?.split('DepGraph target:')[0],
);
let numEdges = 0;
for (const node of depGraph.graph.nodes) {
numEdges += node.deps.length;
}
expect(numEdges).toEqual(7);
});

test('`snyk test --print-graph --all-projects` should not prune dependencies', async () => {
const project = await createProjectFromWorkspace('maven-many-paths');

const { code, stdout } = await runSnykCLI(
'test --print-graph --all-projects',
{
cwd: project.path(),
},
);

expect(code).toEqual(0);
const depGraphs = stdout
.split('DepGraph data:')
.filter(Boolean)
.map((s) => JSON.parse(s.split('DepGraph target:')[0]));

let numEdges = 0;
for (const depGraph of depGraphs) {
for (const node of depGraph.graph.nodes) {
numEdges += node.deps.length;
}
}
expect(numEdges).toEqual(14);
});
});

0 comments on commit e6bc660

Please sign in to comment.