mirror of https://github.com/sbt/sbt.git
Merge branch '1.0.x' into topic/generators
This commit is contained in:
commit
ba28c00a1a
|
|
@ -12,6 +12,7 @@ Migration notes
|
||||||
- Removes no-longer-documented old operators `<<=`, `<+=`, and `<++=`.
|
- Removes no-longer-documented old operators `<<=`, `<+=`, and `<++=`.
|
||||||
- Renames early command feature from `--<command>` to `early(<command>)`.
|
- Renames early command feature from `--<command>` to `early(<command>)`.
|
||||||
- Log options `-error`, `-warn`, `-info`, `-debug` are added as shorthand for `"early(error)"` etc.
|
- Log options `-error`, `-warn`, `-info`, `-debug` are added as shorthand for `"early(error)"` etc.
|
||||||
|
- `sbt.Process` and `sbt.ProcessExtra` are gone. Use `scala.sys.process` instead.
|
||||||
|
|
||||||
#### Additional import required
|
#### Additional import required
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ object Defaults extends BuildCommon {
|
||||||
retrieveManagedSync :== false,
|
retrieveManagedSync :== false,
|
||||||
configurationsToRetrieve :== None,
|
configurationsToRetrieve :== None,
|
||||||
scalaOrganization :== ScalaArtifacts.Organization,
|
scalaOrganization :== ScalaArtifacts.Organization,
|
||||||
|
scalaArtifacts :== ScalaArtifacts.Artifacts,
|
||||||
sbtResolver := { if (sbtVersion.value endsWith "-SNAPSHOT") Classpaths.sbtIvySnapshots else Classpaths.typesafeReleases },
|
sbtResolver := { if (sbtVersion.value endsWith "-SNAPSHOT") Classpaths.sbtIvySnapshots else Classpaths.typesafeReleases },
|
||||||
crossVersion :== Disabled(),
|
crossVersion :== Disabled(),
|
||||||
buildDependencies := Classpaths.constructBuildDependencies.value,
|
buildDependencies := Classpaths.constructBuildDependencies.value,
|
||||||
|
|
@ -368,7 +369,8 @@ object Defaults extends BuildCommon {
|
||||||
|
|
||||||
private[this] lazy val configGlobal = globalDefaults(Seq(
|
private[this] lazy val configGlobal = globalDefaults(Seq(
|
||||||
initialCommands :== "",
|
initialCommands :== "",
|
||||||
cleanupCommands :== ""
|
cleanupCommands :== "",
|
||||||
|
asciiGraphWidth :== 40
|
||||||
))
|
))
|
||||||
|
|
||||||
lazy val projectTasks: Seq[Setting[_]] = Seq(
|
lazy val projectTasks: Seq[Setting[_]] = Seq(
|
||||||
|
|
@ -1431,7 +1433,9 @@ object Classpaths {
|
||||||
(scalaVersion in update).value,
|
(scalaVersion in update).value,
|
||||||
(scalaBinaryVersion in update).value,
|
(scalaBinaryVersion in update).value,
|
||||||
Vector.empty, filterImplicit = false, checkExplicit = true, overrideScalaVersion = true
|
Vector.empty, filterImplicit = false, checkExplicit = true, overrideScalaVersion = true
|
||||||
).withScalaOrganization(scalaOrganization.value))
|
)
|
||||||
|
.withScalaOrganization(scalaOrganization.value)
|
||||||
|
.withScalaArtifacts(scalaArtifacts.value.toVector))
|
||||||
}
|
}
|
||||||
)).value,
|
)).value,
|
||||||
artifactPath in makePom := artifactPathSetting(artifact in makePom).value,
|
artifactPath in makePom := artifactPathSetting(artifact in makePom).value,
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,15 @@ object EvaluateTask {
|
||||||
import std.Transform
|
import std.Transform
|
||||||
import Keys.state
|
import Keys.state
|
||||||
|
|
||||||
|
lazy private val sharedProgress = new TaskTimings(shutdown = true)
|
||||||
|
|
||||||
private[sbt] def defaultProgress: ExecuteProgress[Task] =
|
private[sbt] def defaultProgress: ExecuteProgress[Task] =
|
||||||
if (java.lang.Boolean.getBoolean("sbt.task.timings")) new TaskTimings else ExecuteProgress.empty[Task]
|
if (java.lang.Boolean.getBoolean("sbt.task.timings")) {
|
||||||
|
if (java.lang.Boolean.getBoolean("sbt.task.timings.on.shutdown"))
|
||||||
|
sharedProgress
|
||||||
|
else
|
||||||
|
new TaskTimings(shutdown = false)
|
||||||
|
} else ExecuteProgress.empty[Task]
|
||||||
|
|
||||||
val SystemProcessors = Runtime.getRuntime.availableProcessors
|
val SystemProcessors = Runtime.getRuntime.availableProcessors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ object Keys {
|
||||||
val compileOrder = SettingKey[CompileOrder]("compile-order", "Configures the order in which Java and sources within a single compilation are compiled. Valid values are: JavaThenScala, ScalaThenJava, or Mixed.", BPlusSetting)
|
val compileOrder = SettingKey[CompileOrder]("compile-order", "Configures the order in which Java and sources within a single compilation are compiled. Valid values are: JavaThenScala, ScalaThenJava, or Mixed.", BPlusSetting)
|
||||||
val initialCommands = SettingKey[String]("initial-commands", "Initial commands to execute when starting up the Scala interpreter.", AMinusSetting)
|
val initialCommands = SettingKey[String]("initial-commands", "Initial commands to execute when starting up the Scala interpreter.", AMinusSetting)
|
||||||
val cleanupCommands = SettingKey[String]("cleanup-commands", "Commands to execute before the Scala interpreter exits.", BMinusSetting)
|
val cleanupCommands = SettingKey[String]("cleanup-commands", "Commands to execute before the Scala interpreter exits.", BMinusSetting)
|
||||||
|
val asciiGraphWidth = SettingKey[Int]("asciiGraphWidth", "Determines maximum width of the settings graph in ASCII mode", AMinusSetting)
|
||||||
val compileOptions = TaskKey[CompileOptions]("compile-options", "Collects basic options to configure compilers", DTask)
|
val compileOptions = TaskKey[CompileOptions]("compile-options", "Collects basic options to configure compilers", DTask)
|
||||||
val compileInputs = TaskKey[Inputs]("compile-inputs", "Collects all inputs needed for compilation.", DTask)
|
val compileInputs = TaskKey[Inputs]("compile-inputs", "Collects all inputs needed for compilation.", DTask)
|
||||||
val scalaHome = SettingKey[Option[File]]("scala-home", "If Some, defines the local Scala installation to use for compilation, running, and testing.", ASetting)
|
val scalaHome = SettingKey[Option[File]]("scala-home", "If Some, defines the local Scala installation to use for compilation, running, and testing.", ASetting)
|
||||||
|
|
@ -194,6 +195,7 @@ object Keys {
|
||||||
val printWarnings = TaskKey[Unit]("print-warnings", "Shows warnings from compilation, including ones that weren't printed initially.", BPlusTask)
|
val printWarnings = TaskKey[Unit]("print-warnings", "Shows warnings from compilation, including ones that weren't printed initially.", BPlusTask)
|
||||||
val fileInputOptions = SettingKey[Seq[String]]("file-input-options", "Options that take file input, which may invalidate the cache.", CSetting)
|
val fileInputOptions = SettingKey[Seq[String]]("file-input-options", "Options that take file input, which may invalidate the cache.", CSetting)
|
||||||
val scalaCompilerBridgeSource = SettingKey[ModuleID]("scala-compiler-bridge-source", "Configures the module ID of the sources of the compiler bridge.", CSetting)
|
val scalaCompilerBridgeSource = SettingKey[ModuleID]("scala-compiler-bridge-source", "Configures the module ID of the sources of the compiler bridge.", CSetting)
|
||||||
|
val scalaArtifacts = SettingKey[Seq[String]]("scala-artifacts", "Configures the list of artifacts which should match the Scala binary version", CSetting)
|
||||||
|
|
||||||
val clean = TaskKey[Unit]("clean", "Deletes files produced by the build, such as generated sources, compiled classes, and task caches.", APlusTask)
|
val clean = TaskKey[Unit]("clean", "Deletes files produced by the build, such as generated sources, compiled classes, and task caches.", APlusTask)
|
||||||
val console = TaskKey[Unit]("console", "Starts the Scala interpreter with the project classes on the classpath.", APlusTask)
|
val console = TaskKey[Unit]("console", "Starts the Scala interpreter with the project classes on the classpath.", APlusTask)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import sbt.internal.{
|
||||||
import sbt.internal.util.{ AttributeKey, AttributeMap, complete, ConsoleOut, GlobalLogging, LineRange, MainAppender, SimpleReader, Types }
|
import sbt.internal.util.{ AttributeKey, AttributeMap, complete, ConsoleOut, GlobalLogging, LineRange, MainAppender, SimpleReader, Types }
|
||||||
import sbt.util.{ Level, Logger }
|
import sbt.util.{ Level, Logger }
|
||||||
|
|
||||||
import complete.{ DefaultParsers, Parser }
|
import sbt.internal.util.complete.{ DefaultParsers, Parser }
|
||||||
import sbt.internal.inc.{ CompilerCache, ScalaInstance }
|
import sbt.internal.inc.{ CompilerCache, ScalaInstance }
|
||||||
import sbt.compiler.EvalImports
|
import sbt.compiler.EvalImports
|
||||||
import Types.{ const, idFun }
|
import Types.{ const, idFun }
|
||||||
|
|
@ -221,7 +221,7 @@ object BuiltinCommands {
|
||||||
Some(index.keyMap(key))
|
Some(index.keyMap(key))
|
||||||
catch {
|
catch {
|
||||||
case NonFatal(ex) =>
|
case NonFatal(ex) =>
|
||||||
s.log error ex.getMessage
|
s.log debug ex.getMessage
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}.collect { case Some(s) => s }.distinct
|
}.collect { case Some(s) => s }.distinct
|
||||||
|
|
@ -356,7 +356,7 @@ object BuiltinCommands {
|
||||||
val extracted = Project extract s
|
val extracted = Project extract s
|
||||||
import extracted.{ showKey, structure }
|
import extracted.{ showKey, structure }
|
||||||
val keysParser = token(flag("--last" <~ Space)) ~ Act.aggregatedKeyParser(extracted)
|
val keysParser = token(flag("--last" <~ Space)) ~ Act.aggregatedKeyParser(extracted)
|
||||||
val show = Aggregation.ShowConfig(settingValues = true, taskValues = false, print = println _, success = false)
|
val show = Aggregation.ShowConfig(settingValues = true, taskValues = false, print = println(_), success = false)
|
||||||
for {
|
for {
|
||||||
lastOnly_keys <- keysParser
|
lastOnly_keys <- keysParser
|
||||||
kvs = Act.keyValues(structure)(lastOnly_keys._2)
|
kvs = Act.keyValues(structure)(lastOnly_keys._2)
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ object Inspect {
|
||||||
Project.details(structure, actual, sk.scope, sk.key)
|
Project.details(structure, actual, sk.scope, sk.key)
|
||||||
case DependencyTreeMode =>
|
case DependencyTreeMode =>
|
||||||
val basedir = new File(Project.session(s).current.build)
|
val basedir = new File(Project.session(s).current.build)
|
||||||
Project.settingGraph(structure, basedir, sk).dependsAscii
|
Project.settingGraph(structure, basedir, sk).dependsAscii(get(sbt.Keys.asciiGraphWidth))
|
||||||
case UsesMode =>
|
case UsesMode =>
|
||||||
Project.showUses(Project.usedBy(structure, true, sk.key))
|
Project.showUses(Project.usedBy(structure, true, sk.key))
|
||||||
case DefinitionsMode =>
|
case DefinitionsMode =>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
package sbt
|
package sbt
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import sbt.internal.util.Show
|
import sbt.internal.util.{ Show, JLine }
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Def.{ compiled, flattenLocals, ScopedKey }
|
import Def.{ compiled, flattenLocals, ScopedKey }
|
||||||
|
|
@ -50,10 +50,11 @@ case class SettingGraph(
|
||||||
} getOrElse { d.typeName }
|
} getOrElse { d.typeName }
|
||||||
} getOrElse { "" }
|
} getOrElse { "" }
|
||||||
|
|
||||||
def dependsAscii: String = Graph.toAscii(
|
def dependsAscii(defaultWidth: Int): String = Graph.toAscii(
|
||||||
this,
|
this,
|
||||||
(x: SettingGraph) => x.depends.toSeq.sortBy(_.name),
|
(x: SettingGraph) => x.depends.toSeq.sortBy(_.name),
|
||||||
(x: SettingGraph) => "%s = %s" format (x.definedIn getOrElse { "" }, x.dataString)
|
(x: SettingGraph) => "%s = %s" format (x.definedIn getOrElse { "" }, x.dataString),
|
||||||
|
defaultWidth
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,10 +64,8 @@ object Graph {
|
||||||
// [info] | +-baz
|
// [info] | +-baz
|
||||||
// [info] |
|
// [info] |
|
||||||
// [info] +-quux
|
// [info] +-quux
|
||||||
def toAscii[A](top: A, children: A => Seq[A], display: A => String): String = {
|
def toAscii[A](top: A, children: A => Seq[A], display: A => String, defaultWidth: Int): String = {
|
||||||
val defaultWidth = 40
|
val maxColumn = math.max(JLine.usingTerminal(_.getWidth), defaultWidth) - 8
|
||||||
// TODO: Fix JLine
|
|
||||||
val maxColumn = math.max( /*JLine.usingTerminal(_.getWidth)*/ 0, defaultWidth) - 8
|
|
||||||
val twoSpaces = " " + " " // prevent accidentally being converted into a tab
|
val twoSpaces = " " + " " // prevent accidentally being converted into a tab
|
||||||
def limitLine(s: String): String =
|
def limitLine(s: String): String =
|
||||||
if (s.length > maxColumn) s.slice(0, maxColumn - 2) + ".."
|
if (s.length > maxColumn) s.slice(0, maxColumn - 2) + ".."
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,45 @@ import sbt.internal.util.RMap
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import TaskName._
|
import TaskName._
|
||||||
|
|
||||||
private[sbt] final class TaskTimings extends ExecuteProgress[Task] {
|
/**
|
||||||
|
* Measure the time elapsed for running tasks.
|
||||||
|
* This class is activated by adding -Dsbt.task.timing=true to the JVM options.
|
||||||
|
* Formatting options:
|
||||||
|
* - -Dsbt.task.timings.on.shutdown=true|false
|
||||||
|
* - -Dsbt.task.timings.unit=number
|
||||||
|
* - -Dsbt.task.timings.threshold=number
|
||||||
|
* @param shutdown Should the report be given when exiting the JVM (true) or immediatelly (false)?
|
||||||
|
*/
|
||||||
|
private[sbt] final class TaskTimings(shutdown: Boolean) extends ExecuteProgress[Task] {
|
||||||
private[this] val calledBy = new ConcurrentHashMap[Task[_], Task[_]]
|
private[this] val calledBy = new ConcurrentHashMap[Task[_], Task[_]]
|
||||||
private[this] val anonOwners = new ConcurrentHashMap[Task[_], Task[_]]
|
private[this] val anonOwners = new ConcurrentHashMap[Task[_], Task[_]]
|
||||||
private[this] val timings = new ConcurrentHashMap[Task[_], Long]
|
private[this] val timings = new ConcurrentHashMap[Task[_], Long]
|
||||||
private[this] var start = 0L
|
private[this] var start = 0L
|
||||||
|
private[this] val threshold = java.lang.Long.getLong("sbt.task.timings.threshold", 0L)
|
||||||
|
private[this] val omitPaths = java.lang.Boolean.getBoolean("sbt.task.timings.omit.paths")
|
||||||
|
private[this] val (unit, divider) = System.getProperty("sbt.task.timings.unit", "ms") match {
|
||||||
|
case "ns" => ("ns", 0)
|
||||||
|
case "us" => ("µs", 3)
|
||||||
|
case "ms" => ("ms", 6)
|
||||||
|
case "s" => ("sec", 9)
|
||||||
|
case x =>
|
||||||
|
System.err.println(s"Unknown sbt.task.timings.unit: $x.\nUsing milliseconds.")
|
||||||
|
("ms", 6)
|
||||||
|
}
|
||||||
|
|
||||||
type S = Unit
|
type S = Unit
|
||||||
|
|
||||||
def initial = { start = System.nanoTime }
|
if (shutdown) {
|
||||||
|
start = System.nanoTime
|
||||||
|
Runtime.getRuntime.addShutdownHook(new Thread {
|
||||||
|
override def run() = report()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
def initial = {
|
||||||
|
if (!shutdown)
|
||||||
|
start = System.nanoTime
|
||||||
|
}
|
||||||
def registered(state: Unit, task: Task[_], allDeps: Iterable[Task[_]], pendingDeps: Iterable[Task[_]]) = {
|
def registered(state: Unit, task: Task[_], allDeps: Iterable[Task[_]], pendingDeps: Iterable[Task[_]]) = {
|
||||||
pendingDeps foreach { t => if (transformNode(t).isEmpty) anonOwners.put(t, task) }
|
pendingDeps foreach { t => if (transformNode(t).isEmpty) anonOwners.put(t, task) }
|
||||||
}
|
}
|
||||||
|
|
@ -26,16 +56,34 @@ private[sbt] final class TaskTimings extends ExecuteProgress[Task] {
|
||||||
}
|
}
|
||||||
def completed[T](state: Unit, task: Task[T], result: Result[T]) = ()
|
def completed[T](state: Unit, task: Task[T], result: Result[T]) = ()
|
||||||
def allCompleted(state: Unit, results: RMap[Task, Result]) =
|
def allCompleted(state: Unit, results: RMap[Task, Result]) =
|
||||||
{
|
if (!shutdown) {
|
||||||
val total = System.nanoTime - start
|
report()
|
||||||
println("Total time: " + (total * 1e-6) + " ms")
|
|
||||||
import collection.JavaConverters._
|
|
||||||
def sumTimes(in: Seq[(Task[_], Long)]) = in.map(_._2).sum
|
|
||||||
val timingsByName = timings.asScala.toSeq.groupBy { case (t, time) => mappedName(t) } mapValues (sumTimes)
|
|
||||||
for ((taskName, time) <- timingsByName.toSeq.sortBy(_._2).reverse)
|
|
||||||
println(" " + taskName + ": " + (time * 1e-6) + " ms")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val reFilePath = raw"\{[^}]+\}".r
|
||||||
|
|
||||||
|
private[this] def report() = {
|
||||||
|
val total = divide(System.nanoTime - start)
|
||||||
|
println(s"Total time: $total $unit")
|
||||||
|
import collection.JavaConverters._
|
||||||
|
def sumTimes(in: Seq[(Task[_], Long)]) = in.map(_._2).sum
|
||||||
|
val timingsByName = timings.asScala.toSeq.groupBy { case (t, time) => mappedName(t) } mapValues (sumTimes)
|
||||||
|
val times = timingsByName.toSeq.sortBy(_._2).reverse
|
||||||
|
.map {
|
||||||
|
case (name, time) =>
|
||||||
|
(if (omitPaths) reFilePath.replaceFirstIn(name, "") else name, divide(time))
|
||||||
|
}.filter { _._2 > threshold }
|
||||||
|
if (times.size > 0) {
|
||||||
|
val maxTaskNameLength = times.map { _._1.length }.max
|
||||||
|
val maxTime = times.map { _._2 }.max.toString.length
|
||||||
|
times.foreach {
|
||||||
|
case (taskName, time) =>
|
||||||
|
println(s" ${taskName.padTo(maxTaskNameLength, ' ')}: ${"".padTo(maxTime - time.toString.length, ' ')}$time $unit")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private[this] def inferredName(t: Task[_]): Option[String] = nameDelegate(t) map mappedName
|
private[this] def inferredName(t: Task[_]): Option[String] = nameDelegate(t) map mappedName
|
||||||
private[this] def nameDelegate(t: Task[_]): Option[Task[_]] = Option(anonOwners.get(t)) orElse Option(calledBy.get(t))
|
private[this] def nameDelegate(t: Task[_]): Option[Task[_]] = Option(anonOwners.get(t)) orElse Option(calledBy.get(t))
|
||||||
private[this] def mappedName(t: Task[_]): String = definedName(t) orElse inferredName(t) getOrElse anonymousName(t)
|
private[this] def mappedName(t: Task[_]): String = definedName(t) orElse inferredName(t) getOrElse anonymousName(t)
|
||||||
|
private[this] def divide(time: Long) = (1L to divider.toLong).fold(time) { (a, b) => a / 10L }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
[@RomanIakovlev]: https://github.com/RomanIakovlev
|
||||||
|
|
||||||
|
### Fixes with compatibility implications
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
Add new global setting `asciiGraphWidth` that controls the maximum width of the ASCII graphs printed by commands like `inspect tree`. Default value corresponds to the previously hardcoded value of 40 characters. By [@RomanIakovlev][@RomanIakovlev].
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
@ -46,8 +46,6 @@ case class LoggedOutput(logger: Logger) extends OutputStrategy
|
||||||
*/
|
*/
|
||||||
case class CustomOutput(output: OutputStream) extends OutputStrategy
|
case class CustomOutput(output: OutputStream) extends OutputStrategy
|
||||||
|
|
||||||
import java.lang.{ ProcessBuilder => JProcessBuilder }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a command that can be forked.
|
* Represents a command that can be forked.
|
||||||
*
|
*
|
||||||
|
|
@ -75,20 +73,16 @@ final class Fork(val commandName: String, val runnerClass: Option[String]) {
|
||||||
val executable = Fork.javaCommand(javaHome, commandName).getAbsolutePath
|
val executable = Fork.javaCommand(javaHome, commandName).getAbsolutePath
|
||||||
val preOptions = makeOptions(runJVMOptions, bootJars, arguments)
|
val preOptions = makeOptions(runJVMOptions, bootJars, arguments)
|
||||||
val (classpathEnv, options) = Fork.fitClasspath(preOptions)
|
val (classpathEnv, options) = Fork.fitClasspath(preOptions)
|
||||||
val command = (executable +: options).toArray
|
val command = executable +: options
|
||||||
val builder = new JProcessBuilder(command: _*)
|
|
||||||
workingDirectory.foreach(wd => builder.directory(wd))
|
val environment = env ++ classpathEnv.map(value => Fork.ClasspathEnvKey -> value)
|
||||||
val environment = builder.environment
|
val process = Process(command, workingDirectory, environment.toList: _*)
|
||||||
for ((key, value) <- env)
|
|
||||||
environment.put(key, value)
|
|
||||||
for (cpenv <- classpathEnv)
|
|
||||||
// overriding, not appending, is correct due to the specified priorities of -classpath and CLASSPATH
|
|
||||||
environment.put(Fork.ClasspathEnvKey, cpenv)
|
|
||||||
outputStrategy.getOrElse(StdoutOutput) match {
|
outputStrategy.getOrElse(StdoutOutput) match {
|
||||||
case StdoutOutput => Process(builder).run(connectInput)
|
case StdoutOutput => process.run(connectInput)
|
||||||
case BufferedOutput(logger) => logger.buffer { Process(builder).run(logger, connectInput) }
|
case BufferedOutput(logger) => logger.buffer { process.run(logger, connectInput) }
|
||||||
case LoggedOutput(logger) => Process(builder).run(logger, connectInput)
|
case LoggedOutput(logger) => process.run(logger, connectInput)
|
||||||
case CustomOutput(output) => (Process(builder) #> output).run(connectInput)
|
case CustomOutput(output) => (process #> output).run(connectInput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private[this] def makeOptions(jvmOptions: Seq[String], bootJars: Iterable[File], arguments: Seq[String]): Seq[String] =
|
private[this] def makeOptions(jvmOptions: Seq[String], bootJars: Iterable[File], arguments: Seq[String]): Seq[String] =
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
package sbt
|
|
||||||
|
|
||||||
import java.lang.{ ProcessBuilder => JProcessBuilder }
|
|
||||||
|
|
||||||
trait ProcessExtra {
|
|
||||||
import scala.sys.process._
|
|
||||||
import scala.sys.process.Process._
|
|
||||||
implicit def builderToProcess(builder: JProcessBuilder): ProcessBuilder = apply(builder)
|
|
||||||
implicit def fileToProcess(file: File): ProcessBuilder.FileBuilder = apply(file)
|
|
||||||
implicit def urlToProcess(url: URL): ProcessBuilder.URLBuilder = apply(url)
|
|
||||||
implicit def buildersToProcess[T](builders: Seq[T])(implicit convert: T => ProcessBuilder.Source): Seq[ProcessBuilder.Source] = applySeq(builders)
|
|
||||||
|
|
||||||
implicit def stringToProcess(command: String): ProcessBuilder = apply(command)
|
|
||||||
implicit def stringSeqToProcess(command: Seq[String]): ProcessBuilder = apply(command)
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,7 @@ package sbt
|
||||||
|
|
||||||
object syntax extends syntax
|
object syntax extends syntax
|
||||||
|
|
||||||
abstract class syntax extends IOSyntax0 with sbt.std.TaskExtra with sbt.internal.util.Types with sbt.ProcessExtra
|
abstract class syntax extends IOSyntax0 with sbt.std.TaskExtra with sbt.internal.util.Types
|
||||||
with sbt.internal.librarymanagement.impl.DependencyBuilders with sbt.ProjectExtra
|
with sbt.internal.librarymanagement.impl.DependencyBuilders with sbt.ProjectExtra
|
||||||
with sbt.internal.librarymanagement.DependencyFilterExtra with sbt.BuildExtra with sbt.TaskMacroExtra
|
with sbt.internal.librarymanagement.DependencyFilterExtra with sbt.BuildExtra with sbt.TaskMacroExtra
|
||||||
with sbt.ScopeFilter.Make
|
with sbt.ScopeFilter.Make
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
scalaOrganization := "org.other"
|
||||||
|
|
||||||
|
scalaArtifacts += "thing"
|
||||||
|
|
||||||
|
scalaVersion := "2.11.8"
|
||||||
|
|
||||||
|
libraryDependencies ++= Seq(
|
||||||
|
"org.other" % "thing" % "1.2.3",
|
||||||
|
"org.other" %% "wotsit" % "4.5.6"
|
||||||
|
)
|
||||||
|
|
||||||
|
lazy val check = taskKey[Unit]("Runs the check")
|
||||||
|
|
||||||
|
check := {
|
||||||
|
val lastLog = BuiltinCommands lastLogFile state.value
|
||||||
|
val last = IO read lastLog.get
|
||||||
|
def containsWarn1 = last contains "Binary version (1.2.3) for dependency org.other#thing;1.2.3"
|
||||||
|
def containsWarn2 = last contains "Binary version (4.5.6) for dependency org.other#wotsit_2.11;4.5.6"
|
||||||
|
def containsWarn3 = last contains "differs from Scala binary version in project (2.11)."
|
||||||
|
if (!containsWarn1) sys error "thing should not be exempted from the Scala binary version check"
|
||||||
|
if (containsWarn2) sys error "wotsit should be exempted from the Scala binary version check"
|
||||||
|
if (!containsWarn3) sys error "Binary version check failed"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
> clean
|
||||||
|
|
||||||
|
> check
|
||||||
Loading…
Reference in New Issue