diff --git a/build.sbt b/build.sbt index d6481a771..065e68569 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,5 @@ seq(lsSettings :_*) -CrossBuilding.crossSbtVersions := Seq("0.11.1", "0.11.2", "0.11.3", "0.12") \ No newline at end of file +CrossBuilding.crossSbtVersions := Seq("0.11.1", "0.11.2", "0.11.3", "0.12") + +CrossBuilding.scriptedSettings diff --git a/src/main/scala-sbt-0.11/net/virtualvoid/sbt/graph/Compat.scala b/src/main/scala-sbt-0.11/net/virtualvoid/sbt/graph/Compat.scala new file mode 100644 index 000000000..d34e555f6 --- /dev/null +++ b/src/main/scala-sbt-0.11/net/virtualvoid/sbt/graph/Compat.scala @@ -0,0 +1,20 @@ +package net.virtualvoid.sbt.graph + +import sbt._ +import Keys._ + +import Plugin.ignoreMissingUpdate + +object Compat { + /** + * This is copied directly from sbt/main/Defaults.java and then changed to update the UpdateConfiguration + * to ignore missing artifacts. + */ + def ignoreMissingUpdateT = + ignoreMissingUpdate <<= (ivyModule, thisProjectRef, updateConfiguration, cacheDirectory, scalaInstance, transitiveUpdate, streams) map { (module, ref, config, cacheDirectory, si, reports, s) => + val depsUpdated = reports.exists(!_.stats.cached) + val missingOkConfig = new UpdateConfiguration(config.retrieve, true, config.logging) + + Classpaths.cachedUpdate(cacheDirectory / "update", Project.display(ref), module, missingOkConfig, Some(si), depsUpdated, s.log) + } +} \ No newline at end of file diff --git a/src/main/scala-sbt-0.12/net/virtualvoid/sbt/graph/Compat.scala b/src/main/scala-sbt-0.12/net/virtualvoid/sbt/graph/Compat.scala new file mode 100644 index 000000000..5bc770217 --- /dev/null +++ b/src/main/scala-sbt-0.12/net/virtualvoid/sbt/graph/Compat.scala @@ -0,0 +1,22 @@ +package net.virtualvoid.sbt.graph + +import sbt._ +import Keys._ + +import Plugin.ignoreMissingUpdate + +object Compat { + /** + * This is copied directly from sbt/main/Defaults.java and then changed to update the UpdateConfiguration + * to ignore missing artifacts. + */ + def ignoreMissingUpdateT = + ignoreMissingUpdate <<= (ivyModule, thisProjectRef, updateConfiguration, cacheDirectory, scalaInstance, transitiveUpdate, executionRoots, resolvedScoped, skip in update, streams) map { + (module, ref, config, cacheDirectory, si, reports, roots, resolved, skip, s) => + val depsUpdated = reports.exists(!_.stats.cached) + val isRoot = roots contains resolved + val missingOkConfig = new UpdateConfiguration(config.retrieve, true, config.logging) + + Classpaths.cachedUpdate(cacheDirectory / "update", Project.display(ref), module, missingOkConfig, Some(si), skip = skip, force = isRoot, depsUpdated = depsUpdated, log = s.log) + } tag(Tags.Update, Tags.Network) +} \ No newline at end of file diff --git a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala index cecb82785..526a02ac5 100644 --- a/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/IvyGraphMLDependencies.scala @@ -25,7 +25,7 @@ import sbt.Graph import xml.{Document, XML, Node} object IvyGraphMLDependencies extends App { - case class Module(organisation: String, name: String, version: String) { + case class Module(organisation: String, name: String, version: String, error: Option[String] = None) { def id: String = organisation+":"+name+":"+version } @@ -36,7 +36,7 @@ object IvyGraphMLDependencies extends App { mod <- doc \ "dependencies" \ "module" caller <- mod \ "revision" \ "caller" callerModule = nodeFromElement(caller, caller.attribute("callerrev").get.text) - depModule = nodeFromElement(mod, caller.attribute("rev").get.text) + depModule = nodeFromElement(mod, caller.attribute("rev").get.text, (mod \ "revision").head.attribute("error").map(_.text)) } yield (callerModule, depModule) val nodes = edges.flatMap(e => Seq(e._1, e._2)).distinct @@ -57,7 +57,7 @@ object IvyGraphMLDependencies extends App { // there should only be one root node (the project itself) val roots = nodes.filter(n => !edges.exists(_._2 == n)).sortBy(_.id) roots.map(root => - Graph.toAscii[Module](root, node => deps.getOrElse(node.id, Seq.empty[Module]), _.id) + Graph.toAscii[Module](root, node => deps.getOrElse(node.id, Seq.empty[Module]), x => x.id + x.error.map(" (error: "+_+")").getOrElse("")) ).mkString("\n") } @@ -93,8 +93,8 @@ object IvyGraphMLDependencies extends App { XML.save(outputFile, xml) } - private def nodeFromElement(element: Node, version: String): Module = - Module(element.attribute("organisation").get.text, element.attribute("name").get.text, version) + private def nodeFromElement(element: Node, version: String, error: Option[String] = None): Module = + Module(element.attribute("organisation").get.text, element.attribute("name").get.text, version, error) private def buildDoc(ivyReportFile: String) = ConstructingParser.fromSource(io.Source.fromFile(ivyReportFile), false).document diff --git a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala index fa9286e1c..fc37bc7fa 100755 --- a/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala +++ b/src/main/scala/net/virtualvoid/sbt/graph/Plugin.scala @@ -33,6 +33,8 @@ object Plugin extends sbt.Plugin { "A function which returns the file containing the ivy report from the ivy cache for a given configuration") val ivyReport = TaskKey[File]("ivy-report", "A task which returns the location of the ivy report file for a given configuration (default `compile`).") + val ignoreMissingUpdate = TaskKey[UpdateReport]("update-ignore-missing", + "A copy of the update task which ignores missing artifacts") def graphSettings = seq( ivyReportFunction <<= (sbtVersion, target, projectID, ivyModule, appConfiguration, streams) map { (sbtV, target, projectID, ivyModule, config, streams) => @@ -50,11 +52,12 @@ object Plugin extends sbt.Plugin { ) ++ Seq(Compile, Test, Runtime, Provided, Optional).flatMap(ivyReportForConfig) def ivyReportForConfig(config: Configuration) = inConfig(config)(seq( - ivyReport <<= ivyReportFunction map (_(config.toString)) dependsOn(update), + ivyReport <<= ivyReportFunction map (_(config.toString)) dependsOn(ignoreMissingUpdate), asciiGraph <<= asciiGraphTask, dependencyGraph <<= printAsciiGraphTask, dependencyGraphMLFile <<= target / "dependencies-%s.graphml".format(config.toString), - dependencyGraphML <<= dependencyGraphMLTask + dependencyGraphML <<= dependencyGraphMLTask, + Compat.ignoreMissingUpdateT )) def asciiGraphTask = (ivyReport) map { report => diff --git a/src/sbt-test/sbt-dependency-graph/showMissingUpdates/build.sbt b/src/sbt-test/sbt-dependency-graph/showMissingUpdates/build.sbt new file mode 100644 index 000000000..f610bcf02 --- /dev/null +++ b/src/sbt-test/sbt-dependency-graph/showMissingUpdates/build.sbt @@ -0,0 +1,19 @@ +import net.virtualvoid.sbt.graph.Plugin._ + +graphSettings + +scalaVersion := "2.9.2" + +libraryDependencies += + "at.blub" % "blib" % "1.2.3" % "test" + +TaskKey[Unit]("check") <<= (ivyReport in Test, asciiGraph in Test) map { (report, graph) => + def sanitize(str: String): String = str.split('\n').drop(1).mkString("\n") + val expectedGraph = + """default:default-91180e_2.9.2:0.1-SNAPSHOT + | +-at.blub:blib:1.2.3 (error: not found) + | +-org.scala-lang:scala-library:2.9.2 + | """.stripMargin + require(sanitize(graph) == sanitize(expectedGraph), "Graph for report %s was '\n%s' but should have been '\n%s'" format (report, sanitize(graph), sanitize(expectedGraph))) + () +} diff --git a/src/sbt-test/sbt-dependency-graph/showMissingUpdates/project/plugins.sbt b/src/sbt-test/sbt-dependency-graph/showMissingUpdates/project/plugins.sbt new file mode 100644 index 000000000..08b3f3d0a --- /dev/null +++ b/src/sbt-test/sbt-dependency-graph/showMissingUpdates/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.6.1-SNAPSHOT") \ No newline at end of file diff --git a/src/sbt-test/sbt-dependency-graph/showMissingUpdates/test b/src/sbt-test/sbt-dependency-graph/showMissingUpdates/test new file mode 100644 index 000000000..a5912a391 --- /dev/null +++ b/src/sbt-test/sbt-dependency-graph/showMissingUpdates/test @@ -0,0 +1 @@ +> check \ No newline at end of file