mirror of https://github.com/sbt/sbt.git
half-broken initial attempt at sbt 1.0.0 support
This commit is contained in:
parent
279dea3514
commit
0e20a090f3
19
build.sbt
19
build.sbt
|
|
@ -1,7 +1,8 @@
|
|||
ScriptedPlugin.scriptedSettings
|
||||
|
||||
libraryDependencies ++= {
|
||||
if (sbtVersion.value startsWith "0.13")
|
||||
println(s"Evaluated ${sbtVersion in pluginCrossBuild value}")
|
||||
if ((sbtVersion in pluginCrossBuild).value startsWith "0.13")
|
||||
Seq("com.github.mdr" %% "ascii-graphs" % "0.0.3")
|
||||
else
|
||||
Nil
|
||||
|
|
@ -12,3 +13,19 @@ libraryDependencies += "org.specs2" %% "specs2-core" % "3.9.1" % "test"
|
|||
scalacOptions ++= Seq("-deprecation", "-unchecked")
|
||||
|
||||
ScalariformSupport.formatSettings
|
||||
|
||||
crossSbtVersions := Seq("1.0.1", "0.13.16")
|
||||
|
||||
//sbtVersion in pluginCrossBuild := "1.0.0"
|
||||
|
||||
/*
|
||||
Try to prevent silly warnings
|
||||
|
||||
libraryDependencies += ("org.scala-sbt" %% "main-settings" % "1.0.1-SNAPSHOT")//.excludeAll(ExclusionRule(organization = "org.scala-sbt"))
|
||||
|
||||
libraryDependencies += "org.scala-sbt" %% "command" % "1.0.0"force()
|
||||
libraryDependencies += "org.scala-sbt" %% "completion" % "1.0.0"force()
|
||||
libraryDependencies += "org.scala-sbt" %% "task-system" % "1.0.0"force()
|
||||
libraryDependencies += "org.scala-sbt" %% "core-macros" % "1.0.0" force()
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package sbt.compat
|
||||
|
||||
object SbtCompat {
|
||||
object librarymanagement
|
||||
object internal {
|
||||
object librarymanagement
|
||||
object util {
|
||||
val JLine: { def usingTerminal[T](f: jline.Terminal => T): T } = sbt.JLine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package sbt.compat
|
||||
|
||||
object SbtCompat
|
||||
|
|
@ -25,48 +25,58 @@ import net.virtualvoid.sbt.graph.backend.{ IvyReport, SbtUpdateReport }
|
|||
import net.virtualvoid.sbt.graph.rendering.{ AsciiGraph, DagreHTML }
|
||||
import net.virtualvoid.sbt.graph.util.IOUtil
|
||||
|
||||
import sbt.compat.SbtCompat._
|
||||
import internal.librarymanagement._
|
||||
import librarymanagement._
|
||||
|
||||
object DependencyGraphSettings {
|
||||
import DependencyGraphKeys._
|
||||
import ModuleGraphProtocol._
|
||||
|
||||
def graphSettings = Seq(
|
||||
ivyReportFunction <<= ivyReportFunctionTask,
|
||||
updateConfiguration in ignoreMissingUpdate <<= updateConfiguration(config ⇒ new UpdateConfiguration(config.retrieve, true, config.logging)),
|
||||
ignoreMissingUpdateT,
|
||||
ivyReportFunction := ivyReportFunctionTask.value,
|
||||
updateConfiguration in ignoreMissingUpdate := updateConfiguration.value.withMissingOk(true),
|
||||
ignoreMissingUpdate := update.value,
|
||||
filterScalaLibrary in Global := true) ++ Seq(Compile, Test, IntegrationTest, Runtime, Provided, Optional).flatMap(ivyReportForConfig)
|
||||
|
||||
def ivyReportForConfig(config: Configuration) = inConfig(config)(Seq(
|
||||
ivyReport <<= ivyReportFunction map (_(config.toString)) dependsOn (ignoreMissingUpdate),
|
||||
crossProjectId <<= (scalaVersion, scalaBinaryVersion, projectID)((sV, sBV, id) ⇒ CrossVersion(sV, sBV)(id)),
|
||||
moduleGraphSbt <<= moduleGraphSbtTask,
|
||||
moduleGraphIvyReport <<= moduleGraphIvyReportTask,
|
||||
moduleGraph <<= (sbtVersion, moduleGraphSbt, moduleGraphIvyReport) { (version, graphSbt, graphIvy) ⇒
|
||||
version match {
|
||||
case Version(0, 13, x, _) if x >= 6 ⇒ graphSbt
|
||||
case _ ⇒ graphIvy
|
||||
ivyReport := { Def.task { ivyReportFunction.value.apply(config.toString) } dependsOn (ignoreMissingUpdate) }.value,
|
||||
crossProjectId := sbt.CrossVersion(scalaVersion.value, scalaBinaryVersion.value)(projectID.value),
|
||||
moduleGraphSbt :=
|
||||
ignoreMissingUpdate.value.configuration(configuration.value).map(report ⇒ SbtUpdateReport.fromConfigurationReport(report, crossProjectId.value)).getOrElse(ModuleGraph.empty),
|
||||
moduleGraphIvyReport := IvyReport.fromReportFile(absoluteReportPath(ivyReport.value)),
|
||||
moduleGraph := {
|
||||
sbtVersion.value match {
|
||||
case Version(0, 13, x, _) if x >= 6 ⇒ moduleGraphSbt.value
|
||||
case Version(1, _, _, _) ⇒ moduleGraphSbt.value
|
||||
}
|
||||
},
|
||||
moduleGraph <<= (scalaVersion, moduleGraph, filterScalaLibrary) map { (scalaV, graph, filter) ⇒
|
||||
if (filter) GraphTransformations.ignoreScalaLibrary(scalaV, graph)
|
||||
else graph
|
||||
moduleGraph := {
|
||||
// FIXME: remove busywork
|
||||
val scalaVersion = Keys.scalaVersion.value
|
||||
val moduleGraph = DependencyGraphKeys.moduleGraph.value
|
||||
|
||||
if (filterScalaLibrary.value) GraphTransformations.ignoreScalaLibrary(scalaVersion, moduleGraph)
|
||||
else moduleGraph
|
||||
},
|
||||
moduleGraphStore <<= moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph,
|
||||
asciiTree <<= moduleGraph map rendering.AsciiTree.asciiTree,
|
||||
dependencyTree <<= print(asciiTree),
|
||||
dependencyGraphMLFile <<= target / "dependencies-%s.graphml".format(config.toString),
|
||||
dependencyGraphML <<= dependencyGraphMLTask,
|
||||
dependencyDotFile <<= target / "dependencies-%s.dot".format(config.toString),
|
||||
dependencyDotString <<= dependencyDotStringTask,
|
||||
dependencyDot <<= writeToFile(dependencyDotString, dependencyDotFile),
|
||||
dependencyBrowseGraphTarget <<= target / "browse-dependency-graph",
|
||||
dependencyBrowseGraphHTML <<= browseGraphHTMLTask,
|
||||
dependencyBrowseGraph <<= (dependencyBrowseGraphHTML, streams).map { (uri, streams) ⇒
|
||||
streams.log.info("Opening in browser...")
|
||||
moduleGraphStore := (moduleGraph storeAs moduleGraphStore triggeredBy moduleGraph).value,
|
||||
asciiTree := rendering.AsciiTree.asciiTree(moduleGraph.value),
|
||||
dependencyTree := print(asciiTree).value,
|
||||
dependencyGraphMLFile := { target.value / "dependencies-%s.graphml".format(config.toString) },
|
||||
dependencyGraphML := dependencyGraphMLTask.value,
|
||||
dependencyDotFile := { target.value / "dependencies-%s.dot".format(config.toString) },
|
||||
dependencyDotString := rendering.DOT.dotGraph(moduleGraph.value, dependencyDotHeader.value, dependencyDotNodeLabel.value, rendering.DOT.AngleBrackets),
|
||||
dependencyDot := writeToFile(dependencyDotString, dependencyDotFile).value,
|
||||
dependencyBrowseGraphTarget := { target.value / "browse-dependency-graph" },
|
||||
dependencyBrowseGraphHTML := browseGraphHTMLTask.value,
|
||||
dependencyBrowseGraph := {
|
||||
val uri = dependencyBrowseGraphHTML.value
|
||||
streams.value.log.info("Opening in browser...")
|
||||
java.awt.Desktop.getDesktop.browse(uri)
|
||||
uri
|
||||
},
|
||||
dependencyList <<= printFromGraph(rendering.FlatList.render(_, _.id.idString)),
|
||||
dependencyStats <<= printFromGraph(rendering.Statistics.renderModuleStatsList),
|
||||
dependencyList := printFromGraph(rendering.FlatList.render(_, _.id.idString)).value,
|
||||
dependencyStats := printFromGraph(rendering.Statistics.renderModuleStatsList).value,
|
||||
dependencyDotHeader := """digraph "dependency-graph" {
|
||||
| graph[rankdir="LR"]
|
||||
| edge [
|
||||
|
|
@ -75,79 +85,71 @@ object DependencyGraphSettings {
|
|||
dependencyDotNodeLabel := { (organisation: String, name: String, version: String) ⇒
|
||||
"""%s<BR/><B>%s</B><BR/>%s""".format(organisation, name, version)
|
||||
},
|
||||
whatDependsOn <<= InputTask(artifactIdParser) { module ⇒
|
||||
(module, streams, moduleGraph) map { (module, streams, graph) ⇒
|
||||
streams.log.info(rendering.AsciiTree.asciiTree(GraphTransformations.reverseGraphStartingAt(graph, module)))
|
||||
}
|
||||
whatDependsOn := {
|
||||
val module = artifactIdParser.parsed
|
||||
streams.value.log.info(rendering.AsciiTree.asciiTree(GraphTransformations.reverseGraphStartingAt(moduleGraph.value, module)))
|
||||
},
|
||||
licenseInfo <<= (moduleGraph, streams) map showLicenseInfo) ++ AsciiGraph.asciiGraphSetttings)
|
||||
licenseInfo := showLicenseInfo(moduleGraph.value, streams.value)) ++ AsciiGraph.asciiGraphSetttings)
|
||||
|
||||
def ivyReportFunctionTask =
|
||||
(sbtVersion, target, projectID, ivyModule, appConfiguration, streams) map { (sbtV, target, projectID, ivyModule, config, streams) ⇒
|
||||
sbtV match {
|
||||
case Version(0, min, fix, _) if min > 12 || (min == 12 && fix >= 3) ⇒
|
||||
(c: String) ⇒ file("%s/resolution-cache/reports/%s-%s-%s.xml".format(target, projectID.organization, crossName(ivyModule), c))
|
||||
case Version(0, min, fix, _) if min == 12 && fix >= 1 && fix < 3 ⇒
|
||||
ivyModule.withModule(streams.log) { (i, moduleDesc, _) ⇒
|
||||
val id = ResolveOptions.getDefaultResolveId(moduleDesc)
|
||||
(c: String) ⇒ file("%s/resolution-cache/reports/%s/%s-resolved.xml" format (target, id, c))
|
||||
}
|
||||
case _ ⇒
|
||||
val home = config.provider.scalaProvider.launcher.ivyHome
|
||||
(c: String) ⇒ file("%s/cache/%s-%s-%s.xml" format (home, projectID.organization, crossName(ivyModule), c))
|
||||
}
|
||||
def ivyReportFunctionTask = Def.task {
|
||||
// FIXME: and remove busywork after https://github.com/sbt/sbt/issues/3299 is fixed
|
||||
val target = Keys.target.value
|
||||
val projectID = Keys.projectID.value
|
||||
val ivyModule = Keys.ivyModule.value
|
||||
|
||||
sbtVersion.value match {
|
||||
case Version(0, min, fix, _) if min > 12 || (min == 12 && fix >= 3) ⇒
|
||||
(c: String) ⇒ file("%s/resolution-cache/reports/%s-%s-%s.xml".format(target, projectID.organization, crossName(ivyModule), c))
|
||||
case Version(0, min, fix, _) if min == 12 && fix >= 1 && fix < 3 ⇒
|
||||
ivyModule.withModule(streams.value.log) { (i, moduleDesc, _) ⇒
|
||||
val id = ResolveOptions.getDefaultResolveId(moduleDesc)
|
||||
(c: String) ⇒ file("%s/resolution-cache/reports/%s/%s-resolved.xml" format (target, id, c))
|
||||
}
|
||||
case _ ⇒
|
||||
val home = appConfiguration.value.provider.scalaProvider.launcher.ivyHome
|
||||
(c: String) ⇒ file("%s/cache/%s-%s-%s.xml" format (home, projectID.organization, crossName(ivyModule), c))
|
||||
}
|
||||
|
||||
def moduleGraphIvyReportTask = ivyReport map (absoluteReportPath.andThen(IvyReport.fromReportFile))
|
||||
def moduleGraphSbtTask =
|
||||
(ignoreMissingUpdate, crossProjectId, configuration) map { (update, root, config) ⇒
|
||||
update.configuration(config.name).map(report ⇒ SbtUpdateReport.fromConfigurationReport(report, root)).getOrElse(ModuleGraph.empty)
|
||||
}
|
||||
|
||||
def printAsciiGraphTask =
|
||||
(streams, asciiGraph) map (_.log.info(_))
|
||||
}
|
||||
|
||||
def dependencyGraphMLTask =
|
||||
(moduleGraph, dependencyGraphMLFile, streams) map { (graph, resultFile, streams) ⇒
|
||||
rendering.GraphML.saveAsGraphML(graph, resultFile.getAbsolutePath)
|
||||
streams.log.info("Wrote dependency graph to '%s'" format resultFile)
|
||||
Def.task {
|
||||
val resultFile = dependencyGraphMLFile.value
|
||||
rendering.GraphML.saveAsGraphML(moduleGraph.value, resultFile.getAbsolutePath)
|
||||
streams.value.log.info("Wrote dependency graph to '%s'" format resultFile)
|
||||
resultFile
|
||||
}
|
||||
def dependencyDotStringTask =
|
||||
(moduleGraph, dependencyDotHeader, dependencyDotNodeLabel).map {
|
||||
(graph, dotHead, nodeLabel) ⇒ rendering.DOT.dotGraph(graph, dotHead, nodeLabel, rendering.DOT.AngleBrackets)
|
||||
}
|
||||
|
||||
def browseGraphHTMLTask =
|
||||
(moduleGraph, dependencyDotHeader, dependencyDotNodeLabel, dependencyBrowseGraphTarget, streams).map { (graph, dotHead, nodeLabel, target, streams) ⇒
|
||||
val dotGraph = rendering.DOT.dotGraph(graph, dotHead, nodeLabel, rendering.DOT.LabelTypeHtml)
|
||||
val link = DagreHTML.createLink(dotGraph, target)
|
||||
streams.log.info(s"HTML graph written to $link")
|
||||
Def.task {
|
||||
val dotGraph = rendering.DOT.dotGraph(moduleGraph.value, dependencyDotHeader.value, dependencyDotNodeLabel.value, rendering.DOT.LabelTypeHtml)
|
||||
val link = DagreHTML.createLink(dotGraph, target.value)
|
||||
streams.value.log.info(s"HTML graph written to $link")
|
||||
link
|
||||
}
|
||||
|
||||
def writeToFile(dataTask: TaskKey[String], fileTask: SettingKey[File]) =
|
||||
(dataTask, fileTask, streams).map { (data, outFile, streams) ⇒
|
||||
IOUtil.writeToFile(data, outFile)
|
||||
Def.task {
|
||||
val outFile = fileTask.value
|
||||
IOUtil.writeToFile(dataTask.value, outFile)
|
||||
|
||||
streams.log.info("Wrote dependency graph to '%s'" format outFile)
|
||||
streams.value.log.info("Wrote dependency graph to '%s'" format outFile)
|
||||
outFile
|
||||
}
|
||||
|
||||
def absoluteReportPath = (file: File) ⇒ file.getAbsolutePath
|
||||
|
||||
def print(key: TaskKey[String]) =
|
||||
(streams, key) map (_.log.info(_))
|
||||
Def.task { streams.value.log.info(key.value) }
|
||||
|
||||
def printFromGraph(f: ModuleGraph ⇒ String) =
|
||||
(streams, moduleGraph) map ((streams, graph) ⇒ streams.log.info(f(graph)))
|
||||
Def.task { streams.value.log.info(f(moduleGraph.value)) }
|
||||
|
||||
def showLicenseInfo(graph: ModuleGraph, streams: TaskStreams) {
|
||||
val output =
|
||||
graph.nodes.filter(_.isUsed).groupBy(_.license).toSeq.sortBy(_._1).map {
|
||||
case (license, modules) ⇒
|
||||
license.getOrElse("No license specified") + "\n" +
|
||||
modules.map(_.id.idString formatted "\t %s").mkString("\n")
|
||||
modules.map("\t %s" format _.id.idString).mkString("\n")
|
||||
}.mkString("\n\n")
|
||||
streams.log.info(output)
|
||||
}
|
||||
|
|
@ -159,7 +161,7 @@ object DependencyGraphSettings {
|
|||
(Space ~> token("--force")).?.map(_.isDefined)
|
||||
}
|
||||
|
||||
val artifactIdParser: Initialize[State ⇒ Parser[ModuleId]] =
|
||||
val artifactIdParser: Def.Initialize[State ⇒ Parser[ModuleId]] =
|
||||
resolvedScoped { ctx ⇒
|
||||
(state: State) ⇒
|
||||
val graph = loadFromContext(moduleGraphStore, ctx, state) getOrElse ModuleGraph(Nil, Nil)
|
||||
|
|
@ -197,11 +199,17 @@ object DependencyGraphSettings {
|
|||
}
|
||||
|
||||
/**
|
||||
* This is copied directly from sbt/main/Defaults.java and then changed to update the UpdateConfiguration
|
||||
* This is copied directly from sbt/main/Defaults.scala and then changed to update the UpdateConfiguration
|
||||
* to ignore missing artifacts.
|
||||
*/
|
||||
def ignoreMissingUpdateT =
|
||||
ignoreMissingUpdate <<= Def.task {
|
||||
/*def ignoreMissingUpdateT =
|
||||
ignoreMissingUpdate := {
|
||||
// FIXME: remove busywork
|
||||
|
||||
val scalaVersion = Keys.scalaVersion.value
|
||||
val unmanagedScalaInstanceOnly = SbtAccess.unmanagedScalaInstanceOnly.value
|
||||
val scalaOrganization = Keys.scalaOrganization.value
|
||||
|
||||
val depsUpdated = transitiveUpdate.value.exists(!_.stats.cached)
|
||||
val isRoot = executionRoots.value contains resolvedScoped.value
|
||||
val s = streams.value
|
||||
|
|
@ -211,18 +219,19 @@ object DependencyGraphSettings {
|
|||
// the resolved Scala version and the scalaHome version: compatible (weakly- no qualifier checked)
|
||||
// the resolved Scala version and the declared scalaVersion: assume the user intended scalaHome to override anything with scalaVersion
|
||||
def subUnmanaged(subVersion: String, jars: Seq[File]) = (sv: String) ⇒
|
||||
(partialVersion(sv), partialVersion(subVersion), partialVersion(scalaVersion.value)) match {
|
||||
(partialVersion(sv), partialVersion(subVersion), partialVersion(scalaVersion)) match {
|
||||
case (Some(res), Some(sh), _) if res == sh ⇒ jars
|
||||
case (Some(res), _, Some(decl)) if res == decl ⇒ jars
|
||||
case _ ⇒ Nil
|
||||
}
|
||||
val subScalaJars: String ⇒ Seq[File] = SbtAccess.unmanagedScalaInstanceOnly.value match {
|
||||
case Some(si) ⇒ subUnmanaged(si.version, si.jars)
|
||||
val subScalaJars: String ⇒ Seq[File] = unmanagedScalaInstanceOnly match {
|
||||
case Some(si) ⇒ subUnmanaged(si.version, si.allJars)
|
||||
case None ⇒ sv ⇒ if (scalaProvider.version == sv) scalaProvider.jars else Nil
|
||||
}
|
||||
val transform: UpdateReport ⇒ UpdateReport = r ⇒ Classpaths.substituteScalaFiles(scalaOrganization.value, r)(subScalaJars)
|
||||
val transform: UpdateReport ⇒ UpdateReport = r ⇒ Classpaths.substituteScalaFiles(scalaOrganization, r)(subScalaJars)
|
||||
|
||||
val show = Reference.display(thisProjectRef.value)
|
||||
Classpaths.cachedUpdate(s.cacheDirectory, show, ivyModule.value, (updateConfiguration in ignoreMissingUpdate).value, transform, skip = (skip in update).value, force = isRoot, depsUpdated = depsUpdated, log = s.log)
|
||||
}
|
||||
SbtAccess.cachedUpdater(
|
||||
s.cacheDirectory, show, ivyModule.value, (updateConfiguration in ignoreMissingUpdate).value, transform, skip = (skip in update).value, force = isRoot, depsUpdated = depsUpdated, log = s.log)
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@
|
|||
|
||||
package net.virtualvoid.sbt.graph
|
||||
|
||||
import java.io.File
|
||||
import java.io.{ ByteArrayInputStream, ByteArrayOutputStream, File }
|
||||
import java.util.Base64
|
||||
|
||||
import scala.collection.mutable.{ MultiMap, HashMap, Set }
|
||||
import sbinary.{ JavaInput, JavaOutput }
|
||||
import sjsonnew.{ Builder, Unbuilder }
|
||||
|
||||
import scala.collection.mutable.{ HashMap, MultiMap, Set }
|
||||
|
||||
case class ModuleId(organisation: String,
|
||||
name: String,
|
||||
|
|
@ -71,4 +75,21 @@ object ModuleGraphProtocol extends DefaultProtocol {
|
|||
implicit val ModuleIdFormat: Format[ModuleId] = asProduct3(ModuleId)(ModuleId.unapply(_).get)
|
||||
implicit val ModuleFormat: Format[Module] = asProduct6(Module)(Module.unapply(_).get)
|
||||
implicit val ModuleGraphFormat: Format[ModuleGraph] = asProduct2(ModuleGraph.apply _)(ModuleGraph.unapply(_).get)
|
||||
|
||||
//
|
||||
implicit def sjsonNewAndShinyTransformAndTranspileAdapterFactoryModuleImplementation[T](implicit format: Format[T]): sjsonnew.JsonFormat[T] =
|
||||
new sjsonnew.JsonFormat[T] {
|
||||
// note, how this is simpler to write than to learn any sjonnew protocol syntax
|
||||
def write[J](obj: T, builder: Builder[J]): Unit = {
|
||||
val baos = new ByteArrayOutputStream()
|
||||
format.writes(new JavaOutput(baos), obj)
|
||||
val str = Base64.getEncoder.encodeToString(baos.toByteArray)
|
||||
builder.writeString(str)
|
||||
}
|
||||
def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): T = {
|
||||
val str = unbuilder.readString(jsOpt.get)
|
||||
val bais = new ByteArrayInputStream(Base64.getDecoder.decode(str))
|
||||
format.reads(new JavaInput(bais))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,18 @@
|
|||
|
||||
package sbt
|
||||
|
||||
import sbt.compat.SbtCompat._
|
||||
import librarymanagement._
|
||||
import internal._
|
||||
import librarymanagement._
|
||||
import Classpaths._
|
||||
import LibraryManagement._
|
||||
import internal.util.JLine
|
||||
|
||||
/** Accessors to private[sbt] symbols. */
|
||||
object SbtAccess {
|
||||
val unmanagedScalaInstanceOnly = Defaults.unmanagedScalaInstanceOnly
|
||||
|
||||
def getTerminalWidth: Int = JLine.usingTerminal(_.getWidth)
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue