From ac8851c86558fe68766b4d3ccba6bbe287c05d07 Mon Sep 17 00:00:00 2001
From: Dale Wijnand <dale.wijnand@gmail.com>
Date: Mon, 8 May 2017 12:28:53 +0100
Subject: [PATCH] Cross build to sbt 1.0.0-M5

Complicated by sbt dropping its Process API.
---
 .travis.yml                                   |  4 ++-
 build.sbt                                     | 13 +++++---
 notes/1.3.0.markdown                          |  3 +-
 project/CrossBuildingPlugin.scala             | 25 ++++++++++++++++
 project/build.properties                      |  2 +-
 project/travis.sh                             |  8 ++++-
 src/main/scala/sbtdynver/DynVerPlugin.scala   | 16 ++++++----
 .../dynver/custom-version-string-0/build.sbt  | 30 ++++++++++++++++---
 .../dynver/custom-version-string/build.sbt    | 30 ++++++++++++++++---
 src/sbt-test/dynver/versions/build.sbt        | 30 ++++++++++++++++---
 10 files changed, 135 insertions(+), 26 deletions(-)
 create mode 100644 project/CrossBuildingPlugin.scala

diff --git a/.travis.yml b/.travis.yml
index 45a620b..aafe200 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,5 @@
 language: scala
 jdk: oraclejdk8
-scala: 2.10.6
 script: project/travis.sh
 
 # Build only master and version tags - http://stackoverflow.com/a/31882307/463761
@@ -13,6 +12,9 @@ env:
   global:
     - COURSIER_PROGRESS=0
     - secure: PJ5eWT7PR7VUFrZiaZ6HvTOk+Is09fvpmHNkhAz25rlwThV+8dSNRiUcJCs7uYi+MrvY5JpsTzDihKq1pPbyYdQUaQvTkAB1BLY6lixleBi0QGk9YS5KyEYr/eLfopqBalRtCu7tViG8Zo23MXGhu4ZBbdrBIJHBJIqAV/q3H90UPasgOYtBPSf0lor0Hevm+lDz+zxYoPfsLqe02KceAJwl8hvwsFl8sFao7V90xvkzA2uTqw+GbZGXZ/hNBnaAYD5j7oipDLvX8YBtS1lQdfl2ZGIpwy5AEyt39jdc718+C8e5xPiU9713ESSLApge6NgVyfZDGd6qZs7Zg/dy2o5w40VJ8qUMK5QMCQuZQVbeYyvXrBd3Ye8zBMu4QoSBM62VtJrWQ3eK9nyaIg8XkBDVWX3YiMSEUyVd8WbzMjpi4yFphLmqqKTHUliQgGGCc/N2Qh9s+o7slX4Ko29qN+OTZOIxIxdr6YRHpb2N/n1b4pDUqDIpsN+UMDA3SpGmKN9INx+/A3gBDhOXPFV/pYVo4yxp/Vs7TMpXoJCef1dCU6mQpOdCHppOSX2Q5a9Qxd31LXTFRcNVihLK6sTq2K3aHGWhI3/uoXSMzvvaFCQpNX0HAluyazryIWh6xTRqMDHAImBbATpOEamr3xt3K7Qo2AJH+8mlwTx0lB4lweE=
+  matrix:
+    - TRAVIS_SBT_VERSION=0.13.x
+    - TRAVIS_SBT_VERSION=1.0.0-M5
 
 cache:
   directories:
diff --git a/build.sbt b/build.sbt
index 494a21c..96114a7 100644
--- a/build.sbt
+++ b/build.sbt
@@ -10,7 +10,7 @@ organization := "com.dwijnand"
      scmInfo := Some(ScmInfo(url("https://github.com/dwijnand/sbt-dynver"), "scm:git:git@github.com:dwijnand/sbt-dynver.git"))
 
    sbtPlugin := true
-scalaVersion := "2.10.6"
+scalaVersion := (sbtVersionSeries.value match { case Sbt013 => "2.10.6"; case Sbt1 => "2.12.2" })
 
        maxErrors := 15
 triggeredMessage := Watched.clearWhenTriggered
@@ -24,7 +24,7 @@ scalacOptions  += "-Ywarn-numeric-widen"
 scalacOptions  += "-Ywarn-value-discard"
 
 libraryDependencies += "org.eclipse.jgit"  % "org.eclipse.jgit" % "4.4.1.201607150455-r" % Test
-libraryDependencies += "org.scalacheck"   %% "scalacheck"       % "1.13.2"               % Test
+libraryDependencies += "org.scalacheck"   %% "scalacheck"       % "1.13.5"               % Test
 
              fork in Test := false
       logBuffered in Test := false
@@ -38,13 +38,18 @@ def toSbtPlugin(m: ModuleID) = Def.setting(
   Defaults.sbtPluginExtra(m, (sbtBinaryVersion in update).value, (scalaBinaryVersion in update).value)
 )
 import com.typesafe.tools.mima.core._, ProblemFilters._
-mimaPreviousArtifacts := Set(toSbtPlugin("com.dwijnand" % "sbt-dynver" % "1.2.0").value)
+mimaPreviousArtifacts := (sbtVersionSeries.value match {
+  case Sbt013 => Set(toSbtPlugin("com.dwijnand" % "sbt-dynver" % "1.2.0").value)
+  case Sbt1   => Set.empty
+})
 mimaBinaryIssueFilters ++= Seq(
   exclude[MissingTypesProblem]("sbtdynver.DynVer$"),          // dropped synthetic abstract function parent
   exclude[MissingTypesProblem]("sbtdynver.GitRef$"),          // dropped synthetic abstract function parent
   exclude[MissingTypesProblem]("sbtdynver.GitCommitSuffix$"), // dropped synthetic abstract function parent
   exclude[MissingTypesProblem]("sbtdynver.GitDirtySuffix$"),  // dropped synthetic abstract function parent
-  exclude[DirectMissingMethodProblem]("sbtdynver.package.timestamp") // dropped package private method
+  exclude[DirectMissingMethodProblem]("sbtdynver.package.timestamp"), // dropped package private method
+  exclude[MissingClassProblem]("sbtdynver.NoProcessLogger$"), // sbt1 killed sbt.ProcessLogger so moved to impl
+  exclude[MissingClassProblem]("sbtdynver.NoProcessLogger")   // sbt1 killed sbt.ProcessLogger so moved to impl
 )
 
 TaskKey[Unit]("verify") := Def.sequential(test in Test, scripted.toTask(""), mimaReportBinaryIssues).value
diff --git a/notes/1.3.0.markdown b/notes/1.3.0.markdown
index 0720efe..69388c6 100644
--- a/notes/1.3.0.markdown
+++ b/notes/1.3.0.markdown
@@ -1,6 +1,7 @@
 ### Improvements
 
-- Introduce `GitRef.isTag` & `GitCommitSuffix.isEmpty` utilities. [#34][] by [@dwijnand][]
+- Introduces `GitRef.isTag` & `GitCommitSuffix.isEmpty` utilities. [#34][] by [@dwijnand][]
+- Cross builds against sbt 1.0.0-M5
 
 [#34]: https://github.com/dwijnand/sbt-dynver/pull/34
 [@dwijnand]: https://github.com/dwijnand
diff --git a/project/CrossBuildingPlugin.scala b/project/CrossBuildingPlugin.scala
new file mode 100644
index 0000000..a057660
--- /dev/null
+++ b/project/CrossBuildingPlugin.scala
@@ -0,0 +1,25 @@
+import sbt._, Keys._
+
+sealed trait SbtVersionSeries
+case object Sbt013 extends SbtVersionSeries
+case object Sbt1   extends SbtVersionSeries
+
+object CrossBuildingPlugin extends AutoPlugin {
+  override def requires = plugins.JvmPlugin
+  override def trigger  = allRequirements
+
+  object autoImport {
+    val sbtPartV = settingKey[Option[(Int, Int)]]("")
+    val sbtVersionSeries = settingKey[SbtVersionSeries]("")
+  }
+  import autoImport._
+
+  override def globalSettings = Seq(
+    sbtPartV := CrossVersion partialVersion (sbtVersion in pluginCrossBuild).value,
+    sbtVersionSeries := (sbtPartV.value match {
+      case Some((0, 13)) => Sbt013
+      case Some((1, _))  => Sbt1
+      case _             => sys error s"Unhandled sbt version ${(sbtVersion in pluginCrossBuild).value}"
+    })
+  )
+}
diff --git a/project/build.properties b/project/build.properties
index 27e88aa..d9654cd 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=0.13.13
+sbt.version=0.13.16-M1
diff --git a/project/travis.sh b/project/travis.sh
index 46ca380..7f88981 100755
--- a/project/travis.sh
+++ b/project/travis.sh
@@ -1,5 +1,11 @@
 #!/usr/bin/env bash
 
+if [[ "$TRAVIS_SBT_VERSION" == "0.13.x" ]]; then
+  SWITCH_SBT_VERSION=""
+else
+  SWITCH_SBT_VERSION="^^$TRAVIS_SBT_VERSION"
+fi
+
 [[ "$TRAVIS_PULL_REQUEST" == "false"
 && "$TRAVIS_BRANCH" == "master"
 && "$TRAVIS_SECURE_ENV_VARS" == "true"
@@ -24,4 +30,4 @@ else
   PUBLISH=publishLocal
 fi
 
-sbt ++$TRAVIS_SCALA_VERSION verify "$PUBLISH"
+sbt "$SWITCH_SBT_VERSION" verify "$PUBLISH"
diff --git a/src/main/scala/sbtdynver/DynVerPlugin.scala b/src/main/scala/sbtdynver/DynVerPlugin.scala
index 905bb09..440931a 100644
--- a/src/main/scala/sbtdynver/DynVerPlugin.scala
+++ b/src/main/scala/sbtdynver/DynVerPlugin.scala
@@ -111,8 +111,8 @@ sealed case class DynVer(wd: Option[File]) {
   def hasNoTags(): Boolean                = getGitDescribeOutput(new Date).hasNoTags
 
   def getGitDescribeOutput(d: Date) = {
-    val process = Process(s"""git describe --tags --abbrev=8 --match v[0-9]* --always --dirty=+${timestamp(d)}""", wd)
-    Try(process !! NoProcessLogger).toOption
+    val process = scala.sys.process.Process(s"""git describe --tags --abbrev=8 --match v[0-9]* --always --dirty=+${timestamp(d)}""", wd)
+    Try(process !! impl.NoProcessLogger).toOption
       .map(_.replaceAll("-([0-9]+)-g([0-9a-f]{8})", "+$1-$2"))
       .map(GitDescribeOutput.parse)
   }
@@ -124,8 +124,12 @@ object DynVer extends DynVer(None) with (Option[File] => DynVer)
 
 object `package`
 
-object NoProcessLogger extends ProcessLogger {
-  def info(s: => String)  = ()
-  def error(s: => String) = ()
-  def buffer[T](f: => T)  = f
+package impl {
+  object NoProcessLogger extends scala.sys.process.ProcessLogger {
+    def info(s: => String)  = ()
+    def out(s: => String)   = ()
+    def error(s: => String) = ()
+    def err(s: => String)   = ()
+    def buffer[T](f: => T)  = f
+  }
 }
diff --git a/src/sbt-test/dynver/custom-version-string-0/build.sbt b/src/sbt-test/dynver/custom-version-string-0/build.sbt
index 814cd76..d02ab1b 100644
--- a/src/sbt-test/dynver/custom-version-string-0/build.sbt
+++ b/src/sbt-test/dynver/custom-version-string-0/build.sbt
@@ -1,8 +1,13 @@
+import scala.sys.process.stringToProcess
+
 version in ThisBuild ~= (_.replace('+', '-'))
  dynver in ThisBuild ~= (_.replace('+', '-'))
 
 def tstamp = Def.setting(sbtdynver.DynVer timestamp dynverCurrentDate.value)
-def headSha = Def.task("git rev-parse --short=8 HEAD".!!(streams.value.log).trim)
+def headSha = {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  Def.task("git rev-parse --short=8 HEAD".!!(streams.value.log).trim)
+}
 
 def check(a: String, e: String) = assert(a == e, s"Version mismatch: Expected $e, Incoming $a")
 
@@ -16,17 +21,34 @@ TaskKey[Unit]("checkOnTagAndCommit")      := check(version.value, s"1.0.0-1-${he
 TaskKey[Unit]("checkOnTagAndCommitDirty") := check(version.value, s"1.0.0-1-${headSha.value}-${tstamp.value}")
 
 TaskKey[Unit]("gitInitSetup") := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
   "git init".!!(streams.value.log)
   "git config user.email dynver@mailinator.com".!!(streams.value.log)
   "git config user.name dynver".!!(streams.value.log)
 }
 
-TaskKey[Unit]("gitAdd")    := "git add .".!!(streams.value.log)
-TaskKey[Unit]("gitCommit") := "git commit -am1".!!(streams.value.log)
-TaskKey[Unit]("gitTag")    := "git tag -a v1.0.0 -m1.0.0".!!(streams.value.log)
+TaskKey[Unit]("gitAdd")    := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git add .".!!(streams.value.log)
+}
+TaskKey[Unit]("gitCommit") := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git commit -am1".!!(streams.value.log)
+}
+TaskKey[Unit]("gitTag")    := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git tag -a v1.0.0 -m1.0.0".!!(streams.value.log)
+}
 
 TaskKey[Unit]("dirty") := {
   import java.nio.file._, StandardOpenOption._
   import scala.collection.JavaConverters._
   Files.write(baseDirectory.value.toPath.resolve("f.txt"), Seq("1").asJava, CREATE, APPEND)
 }
+
+def sbtLoggerToScalaSysProcessLogger(log: Logger): scala.sys.process.ProcessLogger =
+  new scala.sys.process.ProcessLogger {
+    def buffer[T](f: => T): T   = f
+    def err(s: => String): Unit = log info s
+    def out(s: => String): Unit = log error s
+  }
diff --git a/src/sbt-test/dynver/custom-version-string/build.sbt b/src/sbt-test/dynver/custom-version-string/build.sbt
index 369c52a..0eac084 100644
--- a/src/sbt-test/dynver/custom-version-string/build.sbt
+++ b/src/sbt-test/dynver/custom-version-string/build.sbt
@@ -1,3 +1,5 @@
+import scala.sys.process.stringToProcess
+
 def versionFmt(out: sbtdynver.GitDescribeOutput): String =
   out.ref.dropV.value + out.commitSuffix.mkString("-", "-", "") + out.dirtySuffix.dropPlus.mkString("-", "")
 
@@ -12,7 +14,10 @@ inThisBuild(List(
 ))
 
 def tstamp = Def.setting(sbtdynver.DynVer timestamp dynverCurrentDate.value)
-def headSha = Def.task("git rev-parse --short=8 HEAD".!!(streams.value.log).trim)
+def headSha = {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  Def.task("git rev-parse --short=8 HEAD".!!(streams.value.log).trim)
+}
 
 def check(a: String, e: String) = assert(a == e, s"Version mismatch: Expected $e, Incoming $a")
 
@@ -26,17 +31,34 @@ TaskKey[Unit]("checkOnTagAndCommit")      := check(version.value, s"1.0.0-1-${he
 TaskKey[Unit]("checkOnTagAndCommitDirty") := check(version.value, s"1.0.0-1-${headSha.value}-${tstamp.value}")
 
 TaskKey[Unit]("gitInitSetup") := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
   "git init".!!(streams.value.log)
   "git config user.email dynver@mailinator.com".!!(streams.value.log)
   "git config user.name dynver".!!(streams.value.log)
 }
 
-TaskKey[Unit]("gitAdd")    := "git add .".!!(streams.value.log)
-TaskKey[Unit]("gitCommit") := "git commit -am1".!!(streams.value.log)
-TaskKey[Unit]("gitTag")    := "git tag -a v1.0.0 -m1.0.0".!!(streams.value.log)
+TaskKey[Unit]("gitAdd")    := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git add .".!!(streams.value.log)
+}
+TaskKey[Unit]("gitCommit") := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git commit -am1".!!(streams.value.log)
+}
+TaskKey[Unit]("gitTag")    := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git tag -a v1.0.0 -m1.0.0".!!(streams.value.log)
+}
 
 TaskKey[Unit]("dirty") := {
   import java.nio.file._, StandardOpenOption._
   import scala.collection.JavaConverters._
   Files.write(baseDirectory.value.toPath.resolve("f.txt"), Seq("1").asJava, CREATE, APPEND)
 }
+
+def sbtLoggerToScalaSysProcessLogger(log: Logger): scala.sys.process.ProcessLogger =
+  new scala.sys.process.ProcessLogger {
+    def buffer[T](f: => T): T   = f
+    def err(s: => String): Unit = log info s
+    def out(s: => String): Unit = log error s
+  }
diff --git a/src/sbt-test/dynver/versions/build.sbt b/src/sbt-test/dynver/versions/build.sbt
index 8c1168b..46d329c 100644
--- a/src/sbt-test/dynver/versions/build.sbt
+++ b/src/sbt-test/dynver/versions/build.sbt
@@ -1,5 +1,10 @@
+import scala.sys.process.stringToProcess
+
 def tstamp = Def.setting(sbtdynver.DynVer timestamp dynverCurrentDate.value)
-def headSha = Def.task("git rev-parse --short=8 HEAD".!!(streams.value.log).trim)
+def headSha = {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  Def.task("git rev-parse --short=8 HEAD".!!(streams.value.log).trim)
+}
 
 def check(a: String, e: String) = assert(a == e, s"Version mismatch: Expected $e, Incoming $a")
 
@@ -13,17 +18,34 @@ TaskKey[Unit]("checkOnTagAndCommit")      := check(version.value, s"1.0.0+1-${he
 TaskKey[Unit]("checkOnTagAndCommitDirty") := check(version.value, s"1.0.0+1-${headSha.value}+${tstamp.value}")
 
 TaskKey[Unit]("gitInitSetup") := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
   "git init".!!(streams.value.log)
   "git config user.email dynver@mailinator.com".!!(streams.value.log)
   "git config user.name dynver".!!(streams.value.log)
 }
 
-TaskKey[Unit]("gitAdd")    := "git add .".!!(streams.value.log)
-TaskKey[Unit]("gitCommit") := "git commit -am1".!!(streams.value.log)
-TaskKey[Unit]("gitTag")    := "git tag -a v1.0.0 -m1.0.0".!!(streams.value.log)
+TaskKey[Unit]("gitAdd")    := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git add .".!!(streams.value.log)
+}
+TaskKey[Unit]("gitCommit") := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git commit -am1".!!(streams.value.log)
+}
+TaskKey[Unit]("gitTag")    := {
+  implicit def log2log(log: Logger): scala.sys.process.ProcessLogger = sbtLoggerToScalaSysProcessLogger(log)
+  "git tag -a v1.0.0 -m1.0.0".!!(streams.value.log)
+}
 
 TaskKey[Unit]("dirty") := {
   import java.nio.file._, StandardOpenOption._
   import scala.collection.JavaConverters._
   Files.write(baseDirectory.value.toPath.resolve("f.txt"), Seq("1").asJava, CREATE, APPEND)
 }
+
+def sbtLoggerToScalaSysProcessLogger(log: Logger): scala.sys.process.ProcessLogger =
+  new scala.sys.process.ProcessLogger {
+    def buffer[T](f: => T): T   = f
+    def err(s: => String): Unit = log info s
+    def out(s: => String): Unit = log error s
+  }