API/api.medcify.app/node_modules/snyk/dist/scala/SnykSbtPlugin-0.1x.scala

133 lines
4.6 KiB
Scala
Raw Normal View History

2022-09-26 06:11:44 +00:00
package snyk
import java.io.StringWriter
import net.virtualvoid.sbt.graph.DependencyGraphKeys.moduleGraph
import net.virtualvoid.sbt.graph.{DependencyGraphPlugin, ModuleId}
import sbt._
import Keys._
import org.json4s._
object SnykSbtPlugin extends AutoPlugin {
val ConfigBlacklist: Set[String] =
Set("windows", "universal", "universal-docs", "debian", "rpm", "universal-src", "docker", "linux", "web-assets", "web-plugin", "web-assets-test", "scalafix")
case class SnykModuleInfo(version: String, configurations: Set[String])
case class SnykProjectData(projectId: String,
modules: Map[String, SnykModuleInfo],
dependencies: Map[String, Set[String]]) {
def merge(otherModules: Map[String, SnykModuleInfo], otherDeps: Map[String, Set[String]]): SnykProjectData = {
val mergedModules = otherModules.foldLeft(modules) {
case (acc, (moduleName, moduleInfo)) =>
acc.get(moduleName) match {
case Some(existing) =>
acc + (moduleName -> SnykModuleInfo(
existing.version,
existing.configurations ++ moduleInfo.configurations
))
case None =>
acc + (moduleName -> moduleInfo)
}
}
val mergedDeps = dependencies ++ otherDeps
SnykProjectData(projectId, mergedModules, mergedDeps)
}
}
object autoImport {
lazy val snykExtractProjectData = taskKey[SnykProjectData]("Extracts the dependency information for each project")
lazy val snykRenderTree = taskKey[Unit]("Renders the dependency information for all projects")
}
import autoImport._
override lazy val globalSettings = Seq(snykRenderTree := Def.taskDyn {
val allProjs = buildStructure.value.allProjectRefs
val filter = ScopeFilter(inProjects(allProjs: _*))
Def.task {
val allProjectDatas = snykExtractProjectData.all(filter).value
val writer = JsonWriter.streaming(new StringWriter())
writer.addJValue(
JObject(
allProjectDatas.toList.map {
case SnykProjectData(projectId, modules, deps) =>
projectId -> JObject(
"modules" -> JObject(
modules
.mapValues { moduleInfo =>
JObject(
List(
"version" -> JString(moduleInfo.version),
"configurations" -> JArray(moduleInfo.configurations.toList.map(JString))
)
)
}
.toList
),
"dependencies" -> JObject(
deps.mapValues(vs => JArray(vs.toList.map(JString))).toList
)
)
}
)
)
println("Snyk Output Start")
println(writer.result.toString)
println("Snyk Output End")
}
}.value)
override lazy val projectSettings = Seq(
snykExtractProjectData := Def.taskDyn {
def formatModuleId(m: ModuleId) = s"${m.organisation}:${m.name}"
val thisProjectId = formatModuleId((moduleGraph in Compile).value.roots.head.id)
val thisProjectConfigs = thisProject.value.configurations.filterNot { c =>
ConfigBlacklist.contains(c.name)
}
val filter = ScopeFilter(configurations = inConfigurations(thisProjectConfigs: _*))
val configAndModuleGraph = Def.task {
val graph = moduleGraph.value
val configName = configuration.value.name
configName -> graph
}
Def.task {
val graphs = configAndModuleGraph.all(filter).value
graphs.foldLeft(SnykProjectData(thisProjectId, Map.empty, Map.empty)) {
case (projectData, (configName, graph)) =>
val modules = graph.modules.flatMap {
case (moduleId, module) =>
if (module.isUsed) Some(formatModuleId(moduleId) -> SnykModuleInfo(moduleId.version, Set(configName)))
else None
}
val depMap = graph.dependencyMap
val dependencies = graph.modules.flatMap {
case (moduleId, module) =>
if (module.isUsed)
depMap.get(moduleId).map { deps =>
formatModuleId(moduleId) -> deps.collect {
case dep if dep.isUsed => formatModuleId(dep.id)
}.toSet
} else None
}
projectData.merge(modules, dependencies)
}
}
}.value
)
override def requires = sbt.plugins.JvmPlugin && DependencyGraphPlugin
override def trigger = allRequirements
}