diff --git a/src/depgraph.test.ts b/src/depgraph.test.ts index 316ff73..729cb26 100644 --- a/src/depgraph.test.ts +++ b/src/depgraph.test.ts @@ -116,6 +116,25 @@ describe('depgraph', () => { }); }); + describe('cycle-tree', () => { + let depGraph; + beforeAll(() => { + depGraph = parseDependencyJson(getTestDataFile("cycle-tree")); + }); + + it('should parse out the top level dependencies', () => { + const mavenDependencies = new MavenDependencyGraph(depGraph); + expect(mavenDependencies.getPackageCount()).to.equal(3); + }); + + it('should be able to generate a manifest despite having a cycle', () => { + const mavenDependencies = new MavenDependencyGraph(depGraph); + const manifest = mavenDependencies.createManifest(); + + expect(manifest.name).to.equal('hadoop-main'); + expect(manifest.countDependencies()).to.equal(2); + }) + }); describe('bs-parent-dep-tree', () => { diff --git a/src/depgraph.ts b/src/depgraph.ts index b74df74..b54e3a2 100644 --- a/src/depgraph.ts +++ b/src/depgraph.ts @@ -85,13 +85,19 @@ export class MavenDependencyGraph { let scope = getDependencyScopeForMavenScope(artifact.scopes); manifest.addDirectDependency(depPackage, scope); - function addTransitiveDeps(dependencies) { + function addTransitiveDeps(dependencies, seen: Set = new Set()) { if (dependencies) { dependencies.forEach(transitiveDep => { - const transitiveDepArtifact = packageUrlToArtifact[transitiveDep.packageURL.toString()]; + let purl = transitiveDep.packageURL.toString(); + if (seen.has(purl)) { + // we're in a cycle! skip this one. + return; + } + const transitiveDepArtifact = packageUrlToArtifact[purl]; const transitiveDepScope = getDependencyScopeForMavenScope(transitiveDepArtifact.scopes); manifest.addIndirectDependency(transitiveDep, transitiveDepScope); - addTransitiveDeps(transitiveDep.dependencies); + seen.add(purl); + addTransitiveDeps(transitiveDep.dependencies, seen); }); } } diff --git a/src/snapshot-generator.ts b/src/snapshot-generator.ts index 19f0a1e..bbfd6bb 100644 --- a/src/snapshot-generator.ts +++ b/src/snapshot-generator.ts @@ -58,12 +58,12 @@ export async function generateSnapshot(directory: string, mvnConfig?: MavenConfi ? snapshotConfig.correlator : snapshot.job?.correlator; - const specifiedRef = getNonEmtptyValue(snapshotConfig?.ref); + const specifiedRef = getNonEmptyValue(snapshotConfig?.ref); if (specifiedRef) { snapshot.ref = specifiedRef; } - const specifiedSha = getNonEmtptyValue(snapshot?.sha); + const specifiedSha = getNonEmptyValue(snapshot?.sha); if (specifiedSha) { snapshot.sha = specifiedSha; } @@ -173,7 +173,7 @@ function getRepositoryRelativePath(file) { return result; } -function getNonEmtptyValue(str?: string) { +function getNonEmptyValue(str?: string) { if (str) { const trimmed = str.trim(); if (trimmed.length > 0) { diff --git a/test-data/dependency-trees/cycle-tree.json b/test-data/dependency-trees/cycle-tree.json new file mode 100644 index 0000000..ce1ed61 --- /dev/null +++ b/test-data/dependency-trees/cycle-tree.json @@ -0,0 +1,57 @@ +{ + "graphName" : "hadoop-main", + "artifacts" : [ { + "id" : "org.apache.hadoop:hadoop-annotations:jar:compile", + "numericId" : 1, + "groupId" : "org.apache.hadoop", + "artifactId" : "hadoop-annotations", + "version" : "3.5.0-SNAPSHOT", + "optional" : false, + "scopes" : [ "compile" ], + "types" : [ "jar" ] + }, { + "id" : "jdiff:jdiff:jar:provided", + "numericId" : 2, + "groupId" : "jdiff", + "artifactId" : "jdiff", + "version" : "1.0.9", + "optional" : false, + "scopes" : [ "provided" ], + "types" : [ "jar" ] + }, { + "id" : "org.apache.hadoop:hadoop-project-dist:pom:compile", + "numericId" : 3, + "groupId" : "org.apache.hadoop", + "artifactId" : "hadoop-project-dist", + "version" : "3.5.0-SNAPSHOT", + "optional" : false, + "scopes" : [ "compile" ], + "types" : [ "pom" ] + } ], + "dependencies" : [ { + "from" : "org.apache.hadoop:hadoop-annotations:jar:compile", + "to" : "jdiff:jdiff:jar:provided", + "numericFrom" : 1, + "numericTo" : 2, + "resolution" : "INCLUDED" + }, { + "from" : "org.apache.hadoop:hadoop-annotations:jar:compile", + "to" : "jdiff:jdiff:jar:provided", + "numericFrom" : 1, + "numericTo" : 3, + "resolution" : "INCLUDED" + }, { + "from" : "jdiff:jdiff:jar:provided", + "to" : "org.apache.hadoop:hadoop-project-dist:pom:compile", + "numericFrom" : 2, + "numericTo" : 3, + "resolution" : "INCLUDED" + }, { + "from" : "org.apache.hadoop:hadoop-project-dist:pom:compile", + "to" : "jdiff:jdiff:jar:provided", + "numericFrom" : 3, + "numericTo" : 2, + "resolution" : "INCLUDED" + } +] +} \ No newline at end of file