project/CheckBeamDependencies.scala (57 lines of code) (raw):
/*
* Copyright 2019 Spotify AB.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.concurrent.ConcurrentHashMap
import java.util.function.{Function => JFunction}
import sbt._
import Keys._
import sbt.plugins.JvmPlugin
import scala.sys.process._
object CheckBeamDependencies extends AutoPlugin {
override def requires: JvmPlugin.type = sbt.plugins.JvmPlugin
override def trigger: PluginTrigger = allRequirements
object autoImport {
val checkBeamDependencies = taskKey[Unit]("check beam dependencies")
}
import autoImport._
private[this] val beamDeps = new ConcurrentHashMap[String, Map[String, Set[String]]]()
private def resolveBeamDependencies(deps: Seq[(String, String)]): Map[String, Set[String]] =
deps
.filter(d => d._1.startsWith("org.apache.beam"))
.map { case (orgName, rev) =>
beamDeps.computeIfAbsent(
orgName,
new JFunction[String, Map[String, Set[String]]] {
override def apply(key: String): Map[String, Set[String]] = {
val output = s"coursier resolve $key:$rev" lineStream_!
output
.flatMap { dep =>
dep.split(":").toList match {
case org :: name :: rev :: _ => Some((s"$org:$name", rev))
case _ => None
}
}
.toList
.groupBy(_._1)
.mapValues(_.map(_._2).toSet)
}
}
)
}
.foldLeft(Map.empty[String, Set[String]])(_ ++ _)
override lazy val projectSettings = Seq(
checkBeamDependencies := {
val deps = libraryDependencies.value.map(m => (s"${m.organization}:${m.name}", m.revision))
val beamDependencies = resolveBeamDependencies(deps)
val projectBeamDeps = deps
.map(dep => (dep, beamDependencies.getOrElse(dep._1, Nil)))
.collect { case ((dep, version), beamVersions) =>
beamVersions.map(v => (dep, (version, v)))
}
.flatten
streams.value.log.warn {
(thisProjectRef.value.project :: projectBeamDeps.collect {
case (org, (v1, v2)) if v1 != v2 =>
s"* $org:$v1 -> beam: $v2"
}.toList).mkString("\n")
}
}
)
}