mirror of https://github.com/sbt/sbt.git
commit
34945af631
|
|
@ -26,7 +26,9 @@ env:
|
|||
- SBT_CMD="scripted java/* package/* reporter/* run/* project-load/*"
|
||||
- SBT_CMD="scripted project/*1of2"
|
||||
- SBT_CMD="scripted project/*2of2"
|
||||
- SBT_CMD="scripted source-dependencies/*"
|
||||
- SBT_CMD="scripted source-dependencies/*1of3"
|
||||
- SBT_CMD="scripted source-dependencies/*2of3"
|
||||
- SBT_CMD="scripted source-dependencies/*3of3"
|
||||
- SBT_CMD="scripted tests/*"
|
||||
- SBT_CMD="repoOverrideTest:scripted dependency-management/*"
|
||||
|
||||
|
|
|
|||
12
build.sbt
12
build.sbt
|
|
@ -1,6 +1,7 @@
|
|||
import Util._
|
||||
import Dependencies._
|
||||
import Sxr.sxr
|
||||
import com.typesafe.tools.mima.core._, ProblemFilters._
|
||||
|
||||
// ThisBuild settings take lower precedence,
|
||||
// but can be shared across the multi projects.
|
||||
|
|
@ -66,7 +67,7 @@ def testedBaseSettings: Seq[Setting[_]] =
|
|||
|
||||
val mimaSettings = Def settings (
|
||||
mimaPreviousArtifacts := Set(
|
||||
organization.value % moduleName.value % "1.0.0-RC3"
|
||||
organization.value % moduleName.value % "1.0.0"
|
||||
cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled)
|
||||
)
|
||||
)
|
||||
|
|
@ -382,9 +383,18 @@ lazy val sbtProj = (project in file("sbt"))
|
|||
crossScalaVersions := Seq(baseScalaVersion),
|
||||
crossPaths := false,
|
||||
mimaSettings,
|
||||
mimaBinaryIssueFilters ++= sbtIgnoredProblems,
|
||||
)
|
||||
.configure(addSbtCompilerBridge)
|
||||
|
||||
lazy val sbtIgnoredProblems = {
|
||||
Seq(
|
||||
// Added more items to Import trait.
|
||||
exclude[ReversedMissingMethodProblem]("sbt.Import.sbt$Import$_setter_$WatchSource_="),
|
||||
exclude[ReversedMissingMethodProblem]("sbt.Import.WatchSource")
|
||||
)
|
||||
}
|
||||
|
||||
def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask {
|
||||
val result = scriptedSource(dir => (s: State) => Scripted.scriptedParser(dir)).parsed
|
||||
// publishLocalBinAll.value // TODO: Restore scripted needing only binary jars.
|
||||
|
|
|
|||
|
|
@ -6,11 +6,12 @@ package sbt
|
|||
import BasicCommandStrings.ClearOnFailure
|
||||
import State.FailureWall
|
||||
import annotation.tailrec
|
||||
import java.io.File
|
||||
import java.nio.file.FileSystems
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import sbt.io.WatchService
|
||||
import sbt.io.{ AllPassFilter, NothingFilter, FileFilter, WatchService }
|
||||
import sbt.internal.io.{ Source, SourceModificationWatch, WatchState }
|
||||
import sbt.internal.util.AttributeKey
|
||||
import sbt.internal.util.Types.const
|
||||
|
|
@ -18,7 +19,7 @@ import sbt.internal.util.Types.const
|
|||
trait Watched {
|
||||
|
||||
/** The files watched when an action is run with a preceeding ~ */
|
||||
def watchSources(s: State): Seq[Source] = Nil
|
||||
def watchSources(s: State): Seq[Watched.WatchSource] = Nil
|
||||
def terminateWatch(key: Int): Boolean = Watched.isEnter(key)
|
||||
|
||||
/**
|
||||
|
|
@ -44,6 +45,30 @@ object Watched {
|
|||
val clearWhenTriggered: WatchState => String = const(clearScreen)
|
||||
def clearScreen: String = "\u001b[2J\u001b[0;0H"
|
||||
|
||||
type WatchSource = Source
|
||||
object WatchSource {
|
||||
|
||||
/**
|
||||
* Creates a new `WatchSource` for watching files, with the given filters.
|
||||
*
|
||||
* @param base The base directory from which to include files.
|
||||
* @param includeFilter Choose what children of `base` to include.
|
||||
* @param excludeFilter Choose what children of `base` to exclude.
|
||||
* @return An instance of `Source`.
|
||||
*/
|
||||
def apply(base: File, includeFilter: FileFilter, excludeFilter: FileFilter): Source =
|
||||
new Source(base, includeFilter, excludeFilter)
|
||||
|
||||
/**
|
||||
* Creates a new `WatchSource` for watching files.
|
||||
*
|
||||
* @param base The base directory from which to include files.
|
||||
* @return An instance of `Source`.
|
||||
*/
|
||||
def apply(base: File): Source =
|
||||
apply(base, AllPassFilter, NothingFilter)
|
||||
}
|
||||
|
||||
private[this] class AWatched extends Watched
|
||||
|
||||
def multi(base: Watched, paths: Seq[Watched]): Watched =
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import scala.annotation.implicitNotFound
|
|||
import sbt.internal.util.Attributed
|
||||
import Def.Initialize
|
||||
import reflect.internal.annotations.compileTimeOnly
|
||||
import sbt.internal.io.Source
|
||||
import sbt.io.{ AllPassFilter, NothingFilter }
|
||||
|
||||
object Append {
|
||||
@implicitNotFound(
|
||||
|
|
@ -96,4 +98,11 @@ object Append {
|
|||
def appendValue(a: Seq[T], b: Option[T]): Seq[T] = b.fold(a)(a :+ _)
|
||||
def appendValues(a: Seq[T], b: Option[T]): Seq[T] = b.fold(a)(a :+ _)
|
||||
}
|
||||
implicit def appendSource: Sequence[Seq[Source], Seq[File], File] =
|
||||
new Sequence[Seq[Source], Seq[File], File] {
|
||||
def appendValue(a: Seq[Source], b: File): Seq[Source] =
|
||||
appendValues(a, Seq(b))
|
||||
def appendValues(a: Seq[Source], b: Seq[File]): Seq[Source] =
|
||||
a ++ b.map(new Source(_, AllPassFilter, NothingFilter))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import sbt.util.Logger
|
|||
import Def.{ ScopedKey, Classpath }
|
||||
import sbt.internal.util.complete._
|
||||
import java.io.File
|
||||
import scala.util.Try
|
||||
|
||||
abstract class BackgroundJobService extends Closeable {
|
||||
|
||||
|
|
@ -24,6 +25,12 @@ abstract class BackgroundJobService extends Closeable {
|
|||
def shutdown(): Unit
|
||||
def jobs: Vector[JobHandle]
|
||||
def stop(job: JobHandle): Unit
|
||||
|
||||
def waitForTry(job: JobHandle): Try[Unit] = {
|
||||
// This implementation is provided only for backward compatibility.
|
||||
Try(waitFor(job))
|
||||
}
|
||||
|
||||
def waitFor(job: JobHandle): Unit
|
||||
|
||||
/** Copies classpath to temporary directories. */
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
package sbt
|
||||
|
||||
import Keys._
|
||||
import Keys.{ version, _ }
|
||||
import sbt.internal.util.complete.{ DefaultParsers, Parser }
|
||||
import sbt.internal.util.AttributeKey
|
||||
import DefaultParsers._
|
||||
|
|
@ -18,6 +18,7 @@ import sbt.internal.CommandStrings.{
|
|||
}
|
||||
import java.io.File
|
||||
|
||||
import sbt.internal.Act
|
||||
import sbt.internal.inc.ScalaInstance
|
||||
import sbt.io.IO
|
||||
import sbt.librarymanagement.CrossVersion
|
||||
|
|
@ -125,10 +126,13 @@ object Cross {
|
|||
case Left(cmd) => (resolveAggregates(x), cmd)
|
||||
}
|
||||
|
||||
val projCrossVersions = aggs map { proj =>
|
||||
proj -> crossVersions(x, proj)
|
||||
}
|
||||
// if we support scalaVersion, projVersions should be cached somewhere since
|
||||
// running ++2.11.1 is at the root level is going to mess with the scalaVersion for the aggregated subproj
|
||||
val projVersions = (aggs flatMap { proj =>
|
||||
crossVersions(x, proj) map { (proj.project, _) }
|
||||
val projVersions = (projCrossVersions flatMap {
|
||||
case (proj, versions) => versions map { proj.project -> _ }
|
||||
}).toList
|
||||
|
||||
val verbose = if (args.verbose) "-v" else ""
|
||||
|
|
@ -136,19 +140,51 @@ object Cross {
|
|||
if (projVersions.isEmpty) {
|
||||
state
|
||||
} else {
|
||||
// Group all the projects by scala version
|
||||
val allCommands = projVersions.groupBy(_._2).mapValues(_.map(_._1)).toSeq.flatMap {
|
||||
case (version, Seq(project)) =>
|
||||
// If only one project for a version, issue it directly
|
||||
Seq(s"$SwitchCommand $verbose $version $project/$aggCommand")
|
||||
case (version, projects) if aggCommand.contains(" ") =>
|
||||
// If the command contains a space, then the all command won't work because it doesn't support issuing
|
||||
// commands with spaces, so revert to running the command on each project one at a time
|
||||
s"$SwitchCommand $verbose $version" :: projects.map(project => s"$project/$aggCommand")
|
||||
case (version, projects) =>
|
||||
// First switch scala version, then use the all command to run the command on each project concurrently
|
||||
Seq(s"$SwitchCommand $verbose $version",
|
||||
projects.map(_ + "/" + aggCommand).mkString("all ", " ", ""))
|
||||
// Detect whether a task or command has been issued
|
||||
val allCommands = Parser.parse(aggCommand, Act.aggregatedKeyParser(x)) match {
|
||||
case Left(_) =>
|
||||
// It's definitely not a task, check if it's a valid command, because we don't want to emit the warning
|
||||
// message below for typos.
|
||||
val validCommand = Parser.parse(aggCommand, state.combinedParser).isRight
|
||||
|
||||
val distinctCrossConfigs = projCrossVersions.map(_._2.toSet).distinct
|
||||
if (validCommand && distinctCrossConfigs.size > 1) {
|
||||
state.log.warn(
|
||||
"Issuing a cross building command, but not all sub projects have the same cross build " +
|
||||
"configuration. This could result in subprojects cross building against Scala versions that they are " +
|
||||
"not compatible with. Try issuing cross building command with tasks instead, since sbt will be able " +
|
||||
"to ensure that cross building is only done using configured project and Scala version combinations " +
|
||||
"that are configured.")
|
||||
state.log.debug("Scala versions configuration is:")
|
||||
projCrossVersions.foreach {
|
||||
case (project, versions) => state.log.debug(s"$project: $versions")
|
||||
}
|
||||
}
|
||||
|
||||
// Execute using a blanket switch
|
||||
projCrossVersions.toMap.apply(currentRef).flatMap { version =>
|
||||
// Force scala version
|
||||
Seq(s"$SwitchCommand $verbose $version!", aggCommand)
|
||||
}
|
||||
|
||||
case Right(_) =>
|
||||
// We have a key, we're likely to be able to cross build this using the per project behaviour.
|
||||
|
||||
// Group all the projects by scala version
|
||||
projVersions.groupBy(_._2).mapValues(_.map(_._1)).toSeq.flatMap {
|
||||
case (version, Seq(project)) =>
|
||||
// If only one project for a version, issue it directly
|
||||
Seq(s"$SwitchCommand $verbose $version $project/$aggCommand")
|
||||
case (version, projects) if aggCommand.contains(" ") =>
|
||||
// If the command contains a space, then the `all` command won't work because it doesn't support issuing
|
||||
// commands with spaces, so revert to running the command on each project one at a time
|
||||
s"$SwitchCommand $verbose $version" :: projects.map(project =>
|
||||
s"$project/$aggCommand")
|
||||
case (version, projects) =>
|
||||
// First switch scala version, then use the all command to run the command on each project concurrently
|
||||
Seq(s"$SwitchCommand $verbose $version",
|
||||
projects.map(_ + "/" + aggCommand).mkString("all ", " ", ""))
|
||||
}
|
||||
}
|
||||
|
||||
allCommands.toList ::: CrossRestoreSessionCommand :: captureCurrentSession(state, x)
|
||||
|
|
|
|||
|
|
@ -316,7 +316,9 @@ object Defaults extends BuildCommon {
|
|||
includeFilter in unmanagedSources,
|
||||
excludeFilter in unmanagedSources).value,
|
||||
watchSources in ConfigGlobal ++= {
|
||||
val bases = unmanagedSourceDirectories.value
|
||||
val baseDir = baseDirectory.value
|
||||
val bases = unmanagedSourceDirectories.value ++ (if (sourcesInBase.value) Seq(baseDir)
|
||||
else Seq.empty)
|
||||
val include = (includeFilter in unmanagedSources).value
|
||||
val exclude = (excludeFilter in unmanagedSources).value
|
||||
bases.map(b => new Source(b, include, exclude))
|
||||
|
|
@ -388,14 +390,7 @@ object Defaults extends BuildCommon {
|
|||
val _ = clean.value
|
||||
IvyActions.cleanCachedResolutionCache(ivyModule.value, streams.value.log)
|
||||
},
|
||||
scalaCompilerBridgeSource := {
|
||||
if (ScalaInstance.isDotty(scalaVersion.value))
|
||||
// Maintained at https://github.com/lampepfl/dotty/tree/master/sbt-bridge
|
||||
ModuleID(scalaOrganization.value, "dotty-sbt-bridge", scalaVersion.value)
|
||||
.withConfigurations(Some("component"))
|
||||
.sources()
|
||||
else ZincUtil.getDefaultBridgeModule(scalaVersion.value)
|
||||
}
|
||||
scalaCompilerBridgeSource := ZincUtil.getDefaultBridgeModule(scalaVersion.value)
|
||||
)
|
||||
// must be a val: duplication detected by object identity
|
||||
private[this] lazy val compileBaseGlobal: Seq[Setting[_]] = globalDefaults(
|
||||
|
|
@ -501,8 +496,8 @@ object Defaults extends BuildCommon {
|
|||
selectMainClass := mainClass.value orElse askForMainClass(discoveredMainClasses.value),
|
||||
mainClass in run := (selectMainClass in run).value,
|
||||
mainClass := pickMainClassOrWarn(discoveredMainClasses.value, streams.value.log),
|
||||
runMain := runMainTask(fullClasspath, runner in run).evaluated,
|
||||
run := runTask(fullClasspath, mainClass in run, runner in run).evaluated,
|
||||
runMain := foregroundRunMainTask.evaluated,
|
||||
run := foregroundRunTask.evaluated,
|
||||
copyResources := copyResourcesTask.value,
|
||||
// note that we use the same runner and mainClass as plain run
|
||||
bgRunMain := bgRunMainTask(exportedProductJars,
|
||||
|
|
@ -1166,14 +1161,14 @@ object Defaults extends BuildCommon {
|
|||
Def.inputTask {
|
||||
val handle = bgRunMain.evaluated
|
||||
val service = bgJobService.value
|
||||
service.waitFor(handle)
|
||||
service.waitForTry(handle).get
|
||||
}
|
||||
// run calls bgRun in the background and waits for the result.
|
||||
def foregroundRunTask: Initialize[InputTask[Unit]] =
|
||||
Def.inputTask {
|
||||
val handle = bgRun.evaluated
|
||||
val service = bgJobService.value
|
||||
service.waitFor(handle)
|
||||
service.waitForTry(handle).get
|
||||
}
|
||||
def runMainTask(classpath: Initialize[Task[Classpath]],
|
||||
scalaRun: Initialize[Task[ScalaRun]]): Initialize[InputTask[Unit]] = {
|
||||
|
|
@ -1538,8 +1533,11 @@ object Defaults extends BuildCommon {
|
|||
lazy val configSettings
|
||||
: Seq[Setting[_]] = Classpaths.configSettings ++ configTasks ++ configPaths ++ packageConfig ++ Classpaths.compilerPluginConfig ++ deprecationSettings
|
||||
|
||||
lazy val compileSettings
|
||||
: Seq[Setting[_]] = configSettings ++ (mainBgRunMainTask +: mainBgRunTask +: addBaseSources) ++ Classpaths.addUnmanagedLibrary
|
||||
lazy val compileSettings: Seq[Setting[_]] =
|
||||
configSettings ++
|
||||
(mainBgRunMainTask +: mainBgRunTask +: addBaseSources) ++
|
||||
Classpaths.addUnmanagedLibrary
|
||||
|
||||
lazy val testSettings: Seq[Setting[_]] = configSettings ++ testTasks
|
||||
|
||||
lazy val itSettings: Seq[Setting[_]] = inConfig(IntegrationTest)(testSettings)
|
||||
|
|
@ -2961,7 +2959,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
|
|||
*/
|
||||
def addSbtPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
|
||||
libraryDependencies += {
|
||||
val sbtV = (sbtBinaryVersion in update).value
|
||||
val sbtV = (sbtBinaryVersion in pluginCrossBuild).value
|
||||
val scalaV = (scalaBinaryVersion in update).value
|
||||
sbtPluginExtra(dependency, sbtV, scalaV)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ import sbt.internal.{
|
|||
LogManager
|
||||
}
|
||||
import sbt.io.{ FileFilter, WatchService }
|
||||
import sbt.internal.io.{ Source, WatchState }
|
||||
import sbt.internal.io.WatchState
|
||||
import sbt.internal.util.{ AttributeKey, SourcePosition }
|
||||
|
||||
import sbt.librarymanagement.Configurations.CompilerPlugin
|
||||
|
|
@ -132,8 +132,8 @@ object Keys {
|
|||
val suppressSbtShellNotification = settingKey[Boolean]("""True to suppress the "Executing in batch mode.." message.""").withRank(CSetting)
|
||||
val pollInterval = settingKey[FiniteDuration]("Interval between checks for modified sources by the continuous execution command.").withRank(BMinusSetting)
|
||||
val watchService = settingKey[() => WatchService]("Service to use to monitor file system changes.").withRank(BMinusSetting)
|
||||
val watchSources = taskKey[Seq[Source]]("Defines the sources in this project for continuous execution to watch for changes.").withRank(BMinusSetting)
|
||||
val watchTransitiveSources = taskKey[Seq[Source]]("Defines the sources in all projects for continuous execution to watch.").withRank(CSetting)
|
||||
val watchSources = taskKey[Seq[Watched.WatchSource]]("Defines the sources in this project for continuous execution to watch for changes.").withRank(BMinusSetting)
|
||||
val watchTransitiveSources = taskKey[Seq[Watched.WatchSource]]("Defines the sources in all projects for continuous execution to watch.").withRank(CSetting)
|
||||
val watchingMessage = settingKey[WatchState => String]("The message to show when triggered execution waits for sources to change.").withRank(DSetting)
|
||||
val triggeredMessage = settingKey[WatchState => String]("The message to show before triggered execution executes an action after sources change.").withRank(DSetting)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import java.util.concurrent.atomic.AtomicLong
|
|||
import java.io.Closeable
|
||||
import Def.{ ScopedKey, Setting, Classpath }
|
||||
import scala.concurrent.ExecutionContext
|
||||
import scala.util.Try
|
||||
import Scope.GlobalScope
|
||||
import java.io.File
|
||||
import sbt.io.{ IO, Hash }
|
||||
|
|
@ -18,6 +19,13 @@ import sbt.internal.util.{ Attributed, ManagedLogger }
|
|||
private[sbt] abstract class BackgroundJob {
|
||||
def humanReadableName: String
|
||||
def awaitTermination(): Unit
|
||||
|
||||
/** This waits till the job ends, and returns inner error via `Try`. */
|
||||
def awaitTerminationTry(): Try[Unit] = {
|
||||
// This implementation is provided only for backward compatibility.
|
||||
Try(awaitTermination())
|
||||
}
|
||||
|
||||
def shutdown(): Unit
|
||||
// this should be true on construction and stay true until
|
||||
// the job is complete
|
||||
|
|
@ -132,15 +140,27 @@ private[sbt] abstract class AbstractBackgroundJobService extends BackgroundJobSe
|
|||
|
||||
private def withHandle(job: JobHandle)(f: ThreadJobHandle => Unit): Unit = job match {
|
||||
case handle: ThreadJobHandle @unchecked => f(handle)
|
||||
case dead: DeadHandle @unchecked => () // nothing to stop or wait for
|
||||
case _: DeadHandle @unchecked => () // nothing to stop or wait for
|
||||
case other =>
|
||||
sys.error(
|
||||
s"BackgroundJobHandle does not originate with the current BackgroundJobService: $other")
|
||||
}
|
||||
|
||||
private def withHandleTry(job: JobHandle)(f: ThreadJobHandle => Try[Unit]): Try[Unit] =
|
||||
job match {
|
||||
case handle: ThreadJobHandle @unchecked => f(handle)
|
||||
case _: DeadHandle @unchecked => Try(()) // nothing to stop or wait for
|
||||
case other =>
|
||||
Try(sys.error(
|
||||
s"BackgroundJobHandle does not originate with the current BackgroundJobService: $other"))
|
||||
}
|
||||
|
||||
override def stop(job: JobHandle): Unit =
|
||||
withHandle(job)(_.job.shutdown())
|
||||
|
||||
override def waitForTry(job: JobHandle): Try[Unit] =
|
||||
withHandleTry(job)(_.job.awaitTerminationTry())
|
||||
|
||||
override def waitFor(job: JobHandle): Unit =
|
||||
withHandle(job)(_.job.awaitTermination())
|
||||
|
||||
|
|
@ -212,6 +232,9 @@ private[sbt] class BackgroundThreadPool extends java.io.Closeable {
|
|||
@volatile
|
||||
private var status: Status = Waiting
|
||||
|
||||
// This is used to capture exceptions that are caught in this background job.
|
||||
private var exitTry: Option[Try[Unit]] = None
|
||||
|
||||
// double-finally for extra paranoia that we will finishedLatch.countDown
|
||||
override def run() =
|
||||
try {
|
||||
|
|
@ -226,7 +249,11 @@ private[sbt] class BackgroundThreadPool extends java.io.Closeable {
|
|||
throw new RuntimeException("Impossible status of bg thread")
|
||||
}
|
||||
}
|
||||
try { if (go) body() } finally cleanup()
|
||||
try {
|
||||
if (go) {
|
||||
exitTry = Option(Try(body()))
|
||||
}
|
||||
} finally cleanup()
|
||||
} finally finishedLatch.countDown()
|
||||
|
||||
private class StopListener(val callback: () => Unit, val executionContext: ExecutionContext)
|
||||
|
|
@ -269,6 +296,12 @@ private[sbt] class BackgroundThreadPool extends java.io.Closeable {
|
|||
result
|
||||
}
|
||||
override def awaitTermination(): Unit = finishedLatch.await()
|
||||
|
||||
override def awaitTerminationTry(): Try[Unit] = {
|
||||
awaitTermination()
|
||||
exitTry.getOrElse(Try(()))
|
||||
}
|
||||
|
||||
override def humanReadableName: String = taskName
|
||||
override def isRunning(): Boolean =
|
||||
status match {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
### Bug fixes
|
||||
|
||||
- Fixes `addSbtPlugin` to use the correct version of sbt. [#3393][]/[#3397][] by [@dwijnand][]
|
||||
|
||||
[#3393]: https://github.com/sbt/sbt/issues/3393
|
||||
[#3397]: https://github.com/sbt/sbt/pull/3397
|
||||
[@dwijnand]: http://github.com/dwijnand
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
This is a hotfix release for sbt 1.0.x series.
|
||||
|
||||
### Improvements
|
||||
|
||||
- Various improves around watch source feature. See below.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fixes command support for cross building `+` command. The `+` added to sbt 1.0 traveres over the subprojects, respecting `crossScalaVersions`; however, it no longer accepted commands as arguments. This brings back the support for it. [#3446][3446] by [@jroper][@jroper]
|
||||
- Fixes `addSbtPlugin` to use the correct version of sbt during cross building. [#3442][3442] by [@dwijnand][@dwijnand]
|
||||
- Fixes `run in Compile` task not including `Runtime` configuration, by reimplementing `run` in terms of `bgRun`. [#3477][3477] by [@eed3si9n][@eed3si9n]
|
||||
- Shows `actual` as a potential option of `inspect` [#3335][3335] by [@Duhemm][@Duhemm]
|
||||
- Includes base directory to watched sources. [#3439][3439] by [@Duhemm][@Duhemm]
|
||||
- Adds an attempt to workaround intermittent `NullPointerException` arround logging. [util#121][util121] by [@eed3si9n][@eed3si9n]
|
||||
- Reverts a bad forward porting. [#3481][3481] by [@eed3si9n][@eed3si9n]
|
||||
|
||||
### WatchSource
|
||||
|
||||
The watch source feature went through a major change from sbt 0.13 to sbt 1.0 using NIO; however, it did not have clear migration path, so we are rectifying that in sbt 1.0.1.
|
||||
|
||||
First, `sbt.WatchSource` is a new alias for `sbt.internal.io.Source`. Hopefully this is easy enough to remember because the key is named `watchSources`. Next, `def apply(base: File)` and `def apply(base: File, includeFilter: FileFilter, excludeFilter: FileFilter)` constructors were added to the companion object of `sbt.WatchSource`.
|
||||
|
||||
For backward compatiblity, sbt 1.0.1 adds `+=` support (`Append` instance) from `File` to `Seq[WatchSource]`.
|
||||
|
||||
So, if you have a directory you want to watch:
|
||||
|
||||
watchSources += WatchSource(sourceDirectory.value)
|
||||
|
||||
If you have a list of files:
|
||||
|
||||
watchSources ++= (sourceDirectory.value ** "*.scala").get
|
||||
|
||||
[#3438][3438] by [@Duhemm][@Duhemm]; [#3478][3478] and [io#74][io74] by [@eed3si9n][@eed3si9n]
|
||||
|
||||
[3335]: https://github.com/sbt/sbt/pull/3335
|
||||
[3438]: https://github.com/sbt/sbt/pull/3438
|
||||
[3478]: https://github.com/sbt/sbt/pull/3478
|
||||
[3439]: https://github.com/sbt/sbt/pull/3439
|
||||
[io74]: https://github.com/sbt/io/pull/74
|
||||
[3442]: https://github.com/sbt/sbt/pull/3442
|
||||
[3446]: https://github.com/sbt/sbt/pull/3446
|
||||
[3477]: https://github.com/sbt/sbt/pull/3477
|
||||
[3481]: https://github.com/sbt/sbt/pull/3481
|
||||
[util121]: https://github.com/sbt/util/pull/121
|
||||
[@eed3si9n]: https://github.com/eed3si9n
|
||||
[@dwijnand]: http://github.com/dwijnand
|
||||
[@jvican]: https://github.com/jvican
|
||||
[@Duhemm]: https://github.com/Duhemm
|
||||
[@jroper]: https://github.com/jroper
|
||||
|
|
@ -12,8 +12,8 @@ object Dependencies {
|
|||
val baseScalaVersion = scala212
|
||||
|
||||
// sbt modules
|
||||
private val ioVersion = "1.0.0"
|
||||
private val utilVersion = "1.0.0"
|
||||
private val ioVersion = "1.0.1"
|
||||
private val utilVersion = "1.0.1"
|
||||
private val lmVersion = "1.0.0"
|
||||
private val zincVersion = "1.0.0"
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
sbt.version=1.0.0-RC3
|
||||
sbt.version=1.0.0
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ trait Import {
|
|||
type RichFile = sbt.io.RichFile
|
||||
type SimpleFileFilter = sbt.io.SimpleFileFilter
|
||||
type SimpleFilter = sbt.io.SimpleFilter
|
||||
type WatchSource = sbt.internal.io.Source
|
||||
val WatchSource = sbt.internal.io.Source
|
||||
|
||||
// sbt.util
|
||||
type AbstractLogger = sbt.util.AbstractLogger
|
||||
|
|
|
|||
|
|
@ -19,3 +19,5 @@ lazy val fooPlugin =(project in file("sbt-foo")).
|
|||
scalaVersion := "2.12.1",
|
||||
crossScalaVersions := Seq("2.12.1")
|
||||
)
|
||||
|
||||
addCommandAlias("build", "compile")
|
||||
|
|
|
|||
|
|
@ -36,3 +36,13 @@ $ exists lib/target/scala-2.11
|
|||
# -$ exists lib/target/scala-2.12
|
||||
# -$ exists sbt-foo/target/scala-2.12
|
||||
# $ exists sbt-foo/target/scala-2.11
|
||||
|
||||
> clean
|
||||
# Test legacy cross build with command support
|
||||
> + build
|
||||
|
||||
# Uses the root project scala version config, which is only configured to build for Scala 2.12
|
||||
$ exists lib/target/scala-2.12
|
||||
-$ exists lib/target/scala-2.11
|
||||
$ exists sbt-foo/target/scala-2.12
|
||||
-$ exists sbt-foo/target/scala-2.11
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
scalaVersion in ThisBuild := "2.12.3"
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.novocode" % "junit-interface" % "0.5" % "test",
|
||||
"junit" % "junit" % "4.8" % "test"
|
||||
"com.novocode" % "junit-interface" % "0.5" % Test,
|
||||
"junit" % "junit" % "4.8" % Test,
|
||||
"commons-io" % "commons-io" % "2.5" % Runtime,
|
||||
)
|
||||
|
||||
libraryDependencies += scalaVersion("org.scala-lang" % "scala-compiler" % _ ).value
|
||||
|
|
|
|||
|
|
@ -28,10 +28,11 @@ class Foo {
|
|||
catch { case _: URISyntaxException => new File(url.getPath) }
|
||||
}
|
||||
|
||||
object Test
|
||||
{
|
||||
def main(args: Array[String])
|
||||
{
|
||||
object Test {
|
||||
def main(args: Array[String]): Unit = {
|
||||
// test that Runtime configuration is included
|
||||
Class.forName("org.apache.commons.io.ByteOrderMark")
|
||||
|
||||
val foo = new Foo
|
||||
args.foreach { arg => foo.eval(arg) == arg.toInt }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,39 +4,38 @@ val buildCrossList = List("2.10.6", "2.11.11", "2.12.2")
|
|||
scalaVersion in ThisBuild := "2.12.2"
|
||||
crossScalaVersions in ThisBuild := buildCrossList
|
||||
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0")
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.settings(
|
||||
sbtPlugin := true,
|
||||
|
||||
TaskKey[Unit]("check") := {
|
||||
val crossV = (sbtVersion in pluginCrossBuild).value
|
||||
val sv = projectID.value.extraAttributes("e:scalaVersion")
|
||||
assert(sbtVersion.value startsWith baseSbt, s"Wrong sbt version: ${sbtVersion.value}")
|
||||
assert(sv == "2.12", s"Wrong e:scalaVersion: $sv")
|
||||
assert(scalaBinaryVersion.value == "2.12", s"Wrong Scala binary version: ${scalaBinaryVersion.value}")
|
||||
assert(crossV startsWith "1.0.", s"Wrong `sbtVersion in pluginCrossBuild`: $crossV")
|
||||
|
||||
// crossScalaVersions in app should not be affected
|
||||
val appCrossScalaVersions = (crossScalaVersions in app).value.toList
|
||||
val appScalaVersion = (scalaVersion in app).value
|
||||
assert(appCrossScalaVersions == buildCrossList, s"Wrong `crossScalaVersions in app`: $appCrossScalaVersions")
|
||||
assert(appScalaVersion startsWith "2.12", s"Wrong `scalaVersion in app`: $appScalaVersion")
|
||||
},
|
||||
|
||||
TaskKey[Unit]("check2") := {
|
||||
val crossV = (sbtVersion in pluginCrossBuild).value
|
||||
val sv = projectID.value.extraAttributes("e:scalaVersion")
|
||||
assert(sbtVersion.value startsWith baseSbt, s"Wrong sbt version: ${sbtVersion.value}")
|
||||
assert(sv == "2.10", s"Wrong e:scalaVersion: $sv")
|
||||
assert(scalaBinaryVersion.value == "2.10", s"Wrong Scala binary version: ${scalaBinaryVersion.value}")
|
||||
assert(crossV startsWith "0.13", s"Wrong `sbtVersion in pluginCrossBuild`: $crossV")
|
||||
|
||||
// ^^ should not affect app's crossScalaVersions
|
||||
val appCrossScalaVersions = (crossScalaVersions in app).value.toList
|
||||
val appScalaVersion = (scalaVersion in app).value
|
||||
assert(appCrossScalaVersions == buildCrossList, s"Wrong `crossScalaVersions in app`: $appCrossScalaVersions")
|
||||
assert(appScalaVersion startsWith "2.12", s"Wrong `scalaVersion in app`: $appScalaVersion")
|
||||
}
|
||||
TaskKey[Unit]("check") := mkCheck("2.12", "1.0").value,
|
||||
TaskKey[Unit]("check2") := mkCheck("2.10", "0.13").value
|
||||
)
|
||||
|
||||
lazy val app = (project in file("app"))
|
||||
|
||||
def mkCheck(scalaBinV: String, sbtBinVer: String) = Def task {
|
||||
val crossV = (sbtVersion in pluginCrossBuild).value
|
||||
val crossBinV = (sbtBinaryVersion in pluginCrossBuild).value
|
||||
val sv = projectID.value.extraAttributes("e:scalaVersion")
|
||||
assert(sbtVersion.value startsWith baseSbt, s"Wrong sbt version: ${sbtVersion.value}")
|
||||
assert(sv == scalaBinV, s"Wrong e:scalaVersion: $sv")
|
||||
assert(scalaBinaryVersion.value == scalaBinV, s"Wrong Scala binary version: ${scalaBinaryVersion.value}")
|
||||
assert(crossV startsWith sbtBinVer, s"Wrong `sbtVersion in pluginCrossBuild`: $crossV")
|
||||
|
||||
val ur = update.value
|
||||
val cr = ur.configuration(Compile).get
|
||||
val mr = cr.modules.find(mr => mr.module.organization == "com.eed3si9n" && mr.module.name == "sbt-buildinfo").get
|
||||
val plugSv = mr.module.extraAttributes("scalaVersion")
|
||||
val plugSbtV = mr.module.extraAttributes("sbtVersion")
|
||||
assert(plugSv == scalaBinV, s"Wrong plugin scalaVersion: $plugSv")
|
||||
assert(plugSbtV == sbtBinVer, s"Wrong plugin scalaVersion: $sbtBinVer")
|
||||
|
||||
// crossScalaVersions in app should not be affected, per se or after ^^
|
||||
val appCrossScalaVersions = (crossScalaVersions in app).value.toList
|
||||
val appScalaVersion = (scalaVersion in app).value
|
||||
assert(appCrossScalaVersions == buildCrossList, s"Wrong `crossScalaVersions in app`: $appCrossScalaVersions")
|
||||
assert(appScalaVersion startsWith "2.12", s"Wrong `scalaVersion in app`: $appScalaVersion")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ def unpackageSettings(name: String) = Seq(
|
|||
unmanagedSourceDirectories := (baseDirectory.value / name) :: Nil,
|
||||
excludeFilter in unmanagedResources := (includeFilter in unmanagedSources).value,
|
||||
unmanagedResourceDirectories := unmanagedSourceDirectories.value,
|
||||
unpackage := IO.unzip(artifactPath in packageSrc value, baseDirectory.value / name)
|
||||
unpackage := {
|
||||
IO.unzip(artifactPath in packageSrc value, baseDirectory.value / name)
|
||||
IO.delete(baseDirectory.value / name / "META-INF")
|
||||
}
|
||||
)
|
||||
|
||||
val unpackage = TaskKey[Unit]("unpackage")
|
||||
|
|
|
|||
Loading…
Reference in New Issue