def counts = 0 def projects2artifacts = [:] def artifacts2projects = [:] def modules2deps = [:] def inputProject = params.jenkins_project def report = [:] report['project'] = inputProject pipeline { agent { label 'CD' } parameters { string(name: 'jenkins_project', defaultValue: '', description: 'The name of the Jenkins project to analyze.') } stages { stage('walking projects') { steps { script { Jenkins.getInstance().getAllItems(TopLevelItem.class).each { p -> projects2artifacts[p.name] = [] p.getAllJobs().each { j -> projects2artifacts[p.name] << j.name; artifacts2projects[j.name] = p.name } } println "FOUND ${projects2artifacts.size()} projects" //projects2artifacts.each { k,v -> println ("PROJECT ${k} BUILDS ${v}") } } } } stage('walking maven modules') { steps { script { // get all the maven modules and their dependencies Jenkins.getInstance().getAllItems(hudson.maven.MavenModule.class).each { m -> modules2deps[m.name] = [] m.getDependencies().each { d -> modules2deps[m.name] << "${d.groupId}:${d.artifactId}" } } println "FOUND ${modules2deps.size()} modules" //modules2deps.each { k,v -> println ("MODULE ${k} DEPENDS on ${v}") } } } } stage('analyze downstream projects') { steps { script { // println "PROJECT ${inputProject} BUILDS ${projects2artifacts[inputProject]} artifacts" // first, let's find out what components depends on the project's artifacts (i.e. downstream dependencies) def downstreamdeps = [:] report['downstream_modules'] = [:] report['downstream_projects'] = [] report['downstream_modules']['L1'] = [:] projects2artifacts[inputProject].each { a -> report = analyzeDependency(modules2deps, artifacts2projects, report, a, 1)} } } } stage('print report') { steps { script { printReport(report) } } } } } // look for modules that use this artifact def findDownstreamDependencies(modules2deps, artifact) { def downdeps = [] //println "Looking for users of ${artifact}" modules2deps.each { k,v -> if (v.contains("${artifact}")) downdeps << k } downdeps } //build the report of the given dependency, go recursive on its dependencies def analyzeDependency(modules2deps, artifacts2projects, report, artifact, deep) { def level = "L${deep}" report['downstream_modules'][level][artifact] = [ 'dependencies':[], 'projects':[] ] // get all downstream dependencies report['downstream_modules'][level][artifact]['dependencies'].addAll(findDownstreamDependencies(modules2deps, artifact)) //println "${artifact} is used by ${report['downstream_modules'][level][artifact]['dependencies']}" // add the project that builds the artifact report['downstream_modules'][level][artifact]['projects'] << artifacts2projects[artifact] report['downstream_projects'] << artifacts2projects[artifact] // then we look for the projects that build the downstream dependencies and finally we go recursive if (report['downstream_modules'][level][artifact]['dependencies']) { def nextDeep = ++deep report['downstream_modules']["L${nextDeep}"] = [:] report['downstream_modules'][level][artifact]['dependencies'].each { d -> report['downstream_modules'][level][artifact]['projects'] << artifacts2projects[d] report['downstream_projects'] << artifacts2projects[d] // go recursive analyzeDependency(modules2deps, artifacts2projects, report, d, nextDeep) } } report } // print the final report def printReport(report) { def text = '' def indent = '\t' text += "Dependency Report for ${report['project']} (jenkins project)" text += "\n\n" text += "|--Project Modules\n" report['downstream_modules'].each { deep, artifacts -> artifacts.each { name, data -> text += "${indent}|--Module Name: ${name}\n" text += "${indent}|--Dependency Level: ${deep}\n" text += "${indent}|--Downstream Modules for ${name}\n" data['dependencies'].each {d -> text += "${indent}\t|--${d}" text += "\n" } text += "${indent}|--Downstream Projects for ${name}\n" data['projects'].each { p -> text += "${indent}\t|--${p}" text += "\n" } } } text += "\n\n" text += "|--All Downstream Projects\n" report['downstream_projects'].unique().sort() report['downstream_projects'].each { p -> text += "${indent}|--${p}" text += "\n" } println text } // debug job def printJob(job) { println("fullname ${job.fullName}") println("name ${job.name}") println("display name ${job.displayName}") job.getAllJobs().each {j -> println ("dep: ${j.name}")} }