2011-02-06 03:40:10 +01:00
|
|
|
/* sbt -- Simple Build Tool
|
|
|
|
|
* Copyright 2011 Mark Harrah
|
|
|
|
|
*/
|
2011-02-03 13:17:47 +01:00
|
|
|
package sbt
|
|
|
|
|
|
2011-02-25 05:30:06 +01:00
|
|
|
import Build.data
|
2011-02-27 22:28:00 +01:00
|
|
|
import Scope.{GlobalScope, ThisScope}
|
2011-03-02 12:46:28 +01:00
|
|
|
import compiler.Discovery
|
2011-04-14 13:32:42 +02:00
|
|
|
import Project.{inConfig, Initialize, inScope, inTask, ScopedKey, Setting, SettingsDefinition}
|
2011-04-20 04:24:52 +02:00
|
|
|
import Configurations.{Compile, CompilerPlugin, IntegrationTest, Runtime, Test}
|
2011-02-12 02:22:17 +01:00
|
|
|
import complete._
|
2011-02-03 13:17:47 +01:00
|
|
|
import std.TaskExtra._
|
2011-05-08 04:02:06 +02:00
|
|
|
import org.scalatools.testing.{AnnotatedFingerprint, SubclassFingerprint}
|
2011-03-14 02:34:17 +01:00
|
|
|
|
2011-02-03 13:17:47 +01:00
|
|
|
import scala.xml.{Node => XNode,NodeSeq}
|
|
|
|
|
import org.apache.ivy.core.module.{descriptor, id}
|
|
|
|
|
import descriptor.ModuleDescriptor, id.ModuleRevisionId
|
2011-03-14 02:34:17 +01:00
|
|
|
import java.io.File
|
|
|
|
|
import java.net.URL
|
2011-04-23 02:13:24 +02:00
|
|
|
import sbinary.DefaultProtocol.StringFormat
|
|
|
|
|
import Cache.seqFormat
|
2011-02-12 02:22:17 +01:00
|
|
|
|
2011-03-14 02:34:17 +01:00
|
|
|
import Types._
|
2011-02-03 13:17:47 +01:00
|
|
|
import Path._
|
|
|
|
|
import GlobFilter._
|
|
|
|
|
import Keys._
|
2011-03-14 02:34:17 +01:00
|
|
|
|
|
|
|
|
object Defaults
|
|
|
|
|
{
|
2011-03-02 12:46:28 +01:00
|
|
|
def configSrcSub(key: ScopedSetting[File]): Initialize[File] = (key, configuration) { (src, conf) => src / nameForSrc(conf.name) }
|
2011-02-03 13:17:47 +01:00
|
|
|
def nameForSrc(config: String) = if(config == "compile") "main" else config
|
|
|
|
|
def prefix(config: String) = if(config == "compile") "" else config + "-"
|
|
|
|
|
|
2011-04-16 17:14:45 +02:00
|
|
|
def lock(app: xsbti.AppConfiguration): xsbti.GlobalLock = app.provider.scalaProvider.launcher.globalLock
|
|
|
|
|
|
2011-02-27 05:56:30 +01:00
|
|
|
def extractAnalysis[T](a: Attributed[T]): (T, inc.Analysis) =
|
2011-03-02 12:46:28 +01:00
|
|
|
(a.data, a.metadata get Keys.analysis getOrElse inc.Analysis.Empty)
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-02-27 05:56:30 +01:00
|
|
|
def analysisMap[T](cp: Seq[Attributed[T]]): Map[T, inc.Analysis] =
|
2011-02-03 13:17:47 +01:00
|
|
|
(cp map extractAnalysis).toMap
|
|
|
|
|
|
2011-03-16 01:35:43 +01:00
|
|
|
def buildCore: Seq[Setting[_]] = thisBuildCore ++ globalCore
|
|
|
|
|
def thisBuildCore: Seq[Setting[_]] = inScope(GlobalScope.copy(project = Select(ThisBuild)))(Seq(
|
|
|
|
|
managedDirectory <<= baseDirectory(_ / "lib_managed")
|
|
|
|
|
))
|
|
|
|
|
def globalCore: Seq[Setting[_]] = inScope(GlobalScope)(Seq(
|
2011-03-10 00:04:53 +01:00
|
|
|
pollInterval :== 500,
|
2011-05-08 04:02:06 +02:00
|
|
|
logBuffered :== false,
|
|
|
|
|
logBuffered in testOnly :== true,
|
|
|
|
|
logBuffered in test :== true,
|
2011-04-12 04:12:03 +02:00
|
|
|
autoCompilerPlugins :== true,
|
2011-04-20 04:24:52 +02:00
|
|
|
internalConfigurationMap :== Configurations.internalMap _,
|
2011-04-05 00:23:51 +02:00
|
|
|
initialize :== (),
|
2011-04-06 00:44:47 +02:00
|
|
|
credentials :== Nil,
|
2011-03-10 00:04:53 +01:00
|
|
|
scalaHome :== None,
|
2011-03-02 12:46:28 +01:00
|
|
|
javaHome :== None,
|
|
|
|
|
outputStrategy :== None,
|
|
|
|
|
fork :== false,
|
|
|
|
|
javaOptions :== Nil,
|
2011-03-14 02:34:17 +01:00
|
|
|
sbtPlugin :== false,
|
2011-03-02 12:46:28 +01:00
|
|
|
crossPaths :== true,
|
2011-03-25 23:25:52 +01:00
|
|
|
classpathTypes := Set("jar", "bundle"),
|
2011-03-02 12:46:28 +01:00
|
|
|
aggregate :== Aggregation.Enabled,
|
|
|
|
|
maxErrors :== 100,
|
2011-03-07 03:57:31 +01:00
|
|
|
showTiming :== true,
|
|
|
|
|
timingFormat :== Aggregation.defaultFormat,
|
|
|
|
|
showSuccess :== true,
|
2011-03-02 12:46:28 +01:00
|
|
|
commands :== Nil,
|
2011-03-16 01:35:43 +01:00
|
|
|
retrieveManaged :== false,
|
2011-04-09 04:03:41 +02:00
|
|
|
buildStructure <<= state map Project.structure,
|
2011-04-14 13:45:43 +02:00
|
|
|
settings <<= buildStructure map ( _.data ),
|
|
|
|
|
artifactClassifier :== None,
|
|
|
|
|
artifactClassifier in packageSrc :== Some(SourceClassifier),
|
2011-04-16 00:25:54 +02:00
|
|
|
artifactClassifier in packageDoc :== Some(DocClassifier),
|
2011-04-22 02:49:38 +02:00
|
|
|
checksums :== IvySbt.DefaultChecksums,
|
|
|
|
|
pomExtra := NodeSeq.Empty,
|
|
|
|
|
pomPostProcess := idFun,
|
|
|
|
|
pomIncludeRepository := Classpaths.defaultRepositoryFilter
|
2011-02-27 22:28:00 +01:00
|
|
|
))
|
|
|
|
|
def projectCore: Seq[Setting[_]] = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
name <<= thisProject(_.id),
|
|
|
|
|
version :== "0.1"
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
|
|
|
|
def paths = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
baseDirectory <<= thisProject(_.base),
|
|
|
|
|
target <<= baseDirectory / "target",
|
|
|
|
|
defaultExcludes in GlobalScope :== (".*" - ".") || HiddenFileFilter,
|
|
|
|
|
historyPath <<= target(t => Some(t / ".history")),
|
|
|
|
|
sourceDirectory <<= baseDirectory / "src",
|
|
|
|
|
sourceFilter in GlobalScope :== ("*.java" | "*.scala"),
|
2011-04-27 03:07:53 +02:00
|
|
|
sourceManaged <<= crossTarget / "src_managed",
|
2011-04-13 02:58:40 +02:00
|
|
|
cacheDirectory <<= target / "cache"
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
|
|
|
|
|
2011-04-27 03:07:53 +02:00
|
|
|
lazy val configPaths = sourceConfigPaths ++ resourceConfigPaths ++ outputConfigPaths
|
|
|
|
|
lazy val sourceConfigPaths = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
sourceDirectory <<= configSrcSub( sourceDirectory in Scope(This,Global,This,This) ),
|
|
|
|
|
sourceManaged <<= configSrcSub(sourceManaged),
|
|
|
|
|
scalaSource <<= sourceDirectory / "scala",
|
|
|
|
|
javaSource <<= sourceDirectory / "java",
|
2011-04-27 03:07:53 +02:00
|
|
|
unmanagedSourceDirectories <<= Seq(scalaSource, javaSource).join,
|
2011-05-08 04:02:06 +02:00
|
|
|
unmanagedSources <<= collectFiles(unmanagedSourceDirectories, sourceFilter, defaultExcludes in unmanagedSources),
|
2011-04-27 03:07:53 +02:00
|
|
|
managedSourceDirectories :== Nil,
|
2011-05-08 04:02:06 +02:00
|
|
|
managedSources <<= collectFiles(managedSourceDirectories, sourceFilter, defaultExcludes in managedSources),
|
2011-04-27 03:07:53 +02:00
|
|
|
sources <<= Classpaths.concat(unmanagedSources, managedSources)
|
|
|
|
|
)
|
|
|
|
|
lazy val resourceConfigPaths = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
resourceDirectory <<= sourceDirectory / "resources",
|
2011-04-27 03:07:53 +02:00
|
|
|
resourceManaged <<= sourceManaged / "res_managed",
|
|
|
|
|
unmanagedResourceDirectories <<= Seq(resourceDirectory).join,
|
|
|
|
|
managedResourceDirectories <<= Seq(resourceManaged).join,
|
|
|
|
|
resourceDirectories <<= Classpaths.concatSettings(unmanagedResourceDirectories, managedResourceDirectories),
|
2011-05-08 04:02:06 +02:00
|
|
|
unmanagedResources <<= (unmanagedResourceDirectories, defaultExcludes in unmanagedResources) map unmanagedResourcesTask,
|
2011-04-27 03:07:53 +02:00
|
|
|
managedResources <<= (definedSbtPlugins, resourceManaged) map writePluginsDescriptor,
|
|
|
|
|
resources <<= Classpaths.concat(managedResources, unmanagedResources)
|
|
|
|
|
)
|
|
|
|
|
lazy val outputConfigPaths = Seq(
|
|
|
|
|
cacheDirectory <<= (cacheDirectory, configuration) { _ / _.name },
|
|
|
|
|
classDirectory <<= (crossTarget, configuration) { (outDir, conf) => outDir / (prefix(conf.name) + "classes") },
|
|
|
|
|
docDirectory <<= (crossTarget, configuration) { (outDir, conf) => outDir / (prefix(conf.name) + "api") }
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
|
|
|
|
def addBaseSources = Seq(
|
2011-05-08 04:02:06 +02:00
|
|
|
unmanagedSources <<= (unmanagedSources, baseDirectory, sourceFilter, defaultExcludes in unmanagedSources) map {
|
2011-04-27 03:07:53 +02:00
|
|
|
(srcs,b,f,excl) => (srcs +++ b * (f -- excl)).getFiles
|
|
|
|
|
}
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def compileBase = Seq(
|
2011-03-08 23:50:19 +01:00
|
|
|
classpathOptions in GlobalScope :== ClasspathOptions.auto,
|
2011-04-04 03:15:35 +02:00
|
|
|
compileOrder in GlobalScope :== CompileOrder.Mixed,
|
2011-03-10 00:04:53 +01:00
|
|
|
compilers <<= (scalaInstance, appConfiguration, streams, classpathOptions, javaHome) map { (si, app, s, co, jh) => Compiler.compilers(si, co, jh)(app, s.log) },
|
2011-03-02 12:46:28 +01:00
|
|
|
javacOptions in GlobalScope :== Nil,
|
|
|
|
|
scalacOptions in GlobalScope :== Nil,
|
2011-03-10 00:04:53 +01:00
|
|
|
scalaInstance <<= scalaInstanceSetting,
|
2011-03-29 04:28:54 +02:00
|
|
|
scalaVersion in GlobalScope <<= appConfiguration( _.provider.scalaProvider.version),
|
2011-04-10 02:42:57 +02:00
|
|
|
crossScalaVersions <<= Seq(scalaVersion).join,
|
2011-04-13 02:58:40 +02:00
|
|
|
crossTarget <<= (target, scalaInstance, crossPaths)( (t,si,cross) => if(cross) t / ("scala-" + si.actualVersion) else t ),
|
|
|
|
|
cacheDirectory <<= crossTarget / "cache"
|
2011-02-06 03:40:10 +01:00
|
|
|
)
|
|
|
|
|
|
2011-02-26 00:35:52 +01:00
|
|
|
lazy val configTasks = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
initialCommands in GlobalScope :== "",
|
|
|
|
|
compile <<= compileTask,
|
|
|
|
|
compileInputs <<= compileInputsTask,
|
|
|
|
|
console <<= consoleTask,
|
|
|
|
|
consoleQuick <<= consoleQuickTask,
|
2011-04-23 19:17:21 +02:00
|
|
|
discoveredMainClasses <<= TaskData.write(compile map discoverMainClasses) triggeredBy compile,
|
2011-03-14 02:34:17 +01:00
|
|
|
definedSbtPlugins <<= discoverPlugins,
|
2011-03-02 12:46:28 +01:00
|
|
|
inTask(run)(runnerSetting :: Nil).head,
|
|
|
|
|
selectMainClass <<= discoveredMainClasses map selectRunMain,
|
2011-04-16 17:24:58 +02:00
|
|
|
mainClass in run <<= (selectMainClass in run).identity,
|
2011-03-02 12:46:28 +01:00
|
|
|
mainClass <<= discoveredMainClasses map selectPackageMain,
|
|
|
|
|
run <<= runTask(fullClasspath, mainClass in run, runner in run),
|
2011-03-28 00:09:40 +02:00
|
|
|
runMain <<= runMainTask(fullClasspath, runner in run),
|
2011-04-16 17:24:58 +02:00
|
|
|
scaladocOptions <<= scalacOptions.identity,
|
2011-03-02 12:46:28 +01:00
|
|
|
doc <<= docTask,
|
|
|
|
|
copyResources <<= copyResourcesTask
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
|
|
|
|
|
2011-02-26 00:35:52 +01:00
|
|
|
lazy val projectTasks: Seq[Setting[_]] = Seq(
|
2011-04-27 03:07:53 +02:00
|
|
|
cleanFiles <<= Seq(managedDirectory, target).join,
|
2011-04-13 02:58:40 +02:00
|
|
|
cleanKeepFiles <<= historyPath(_.toList),
|
|
|
|
|
clean <<= (cleanFiles, cleanKeepFiles) map doClean,
|
2011-03-02 12:46:28 +01:00
|
|
|
consoleProject <<= consoleProjectTask,
|
|
|
|
|
watchSources <<= watchSourcesTask,
|
|
|
|
|
watchTransitiveSources <<= watchTransitiveSourcesTask,
|
|
|
|
|
watch <<= watchSetting
|
2011-02-06 17:33:29 +01:00
|
|
|
)
|
|
|
|
|
|
2011-04-07 03:00:48 +02:00
|
|
|
def inAllConfigurations[T](key: ScopedTask[T]): Initialize[Task[Seq[T]]] = (state, thisProjectRef) flatMap { (state, ref) =>
|
2011-03-01 14:54:06 +01:00
|
|
|
val structure = Project structure state
|
|
|
|
|
val configurations = Project.getProject(ref, structure).toList.flatMap(_.configurations)
|
|
|
|
|
configurations.flatMap { conf =>
|
|
|
|
|
key in (ref, conf) get structure.data
|
|
|
|
|
} join
|
|
|
|
|
}
|
2011-03-02 12:46:28 +01:00
|
|
|
def watchTransitiveSourcesTask: Initialize[Task[Seq[File]]] =
|
2011-04-07 03:00:48 +02:00
|
|
|
(state, thisProjectRef) flatMap { (s, base) =>
|
2011-04-12 04:12:03 +02:00
|
|
|
inAllDependencies(base, watchSources.task, Project structure s).join.map(_.flatten)
|
2011-03-01 14:54:06 +01:00
|
|
|
}
|
2011-04-27 03:07:53 +02:00
|
|
|
def watchSourcesTask: Initialize[Task[Seq[File]]] =
|
|
|
|
|
Seq(unmanagedSources, unmanagedResources).map(inAllConfigurations).join { _.join.map(_.flatten.flatten.distinct) }
|
2011-03-01 14:54:06 +01:00
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def watchSetting: Initialize[Watched] = (pollInterval, thisProjectRef) { (interval, base) =>
|
2011-03-01 14:54:06 +01:00
|
|
|
new Watched {
|
2011-03-02 12:46:28 +01:00
|
|
|
val scoped = watchTransitiveSources in base
|
2011-03-01 14:54:06 +01:00
|
|
|
val key = ScopedKey(scoped.scope, scoped.key)
|
|
|
|
|
override def pollInterval = interval
|
2011-04-27 03:07:53 +02:00
|
|
|
override def watchPaths(s: State) = EvaluateTask.evaluateTask(Project structure s, key, s, base) match {
|
|
|
|
|
case Some(Value(ps)) => ps
|
|
|
|
|
case Some(Inc(i)) => throw i
|
|
|
|
|
case None => error("key not found: " + Project.display(key))
|
|
|
|
|
}
|
2011-03-01 14:54:06 +01:00
|
|
|
}
|
|
|
|
|
}
|
2011-03-10 00:04:53 +01:00
|
|
|
def scalaInstanceSetting = (appConfiguration, scalaVersion, scalaHome){ (app, version, home) =>
|
|
|
|
|
val launcher = app.provider.scalaProvider.launcher
|
|
|
|
|
home match {
|
|
|
|
|
case None => ScalaInstance(version, launcher)
|
|
|
|
|
case Some(h) => ScalaInstance(h, launcher)
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-27 03:07:53 +02:00
|
|
|
def unmanagedResourcesTask(dirs: Seq[File], excl: FileFilter) =
|
|
|
|
|
dirs.descendentsExcept("*",excl).getFiles
|
2011-03-01 14:54:06 +01:00
|
|
|
|
2011-04-07 02:55:30 +02:00
|
|
|
lazy val testTasks = testTaskOptions(test) ++ testTaskOptions(testOnly) ++ Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
testLoader <<= (fullClasspath, scalaInstance) map { (cp, si) => TestFramework.createTestLoader(data(cp), si) },
|
|
|
|
|
testFrameworks in GlobalScope :== {
|
2011-02-06 17:33:29 +01:00
|
|
|
import sbt.TestFrameworks._
|
|
|
|
|
Seq(ScalaCheck, Specs, ScalaTest, ScalaCheckCompat, ScalaTestCompat, SpecsCompat, JUnit)
|
|
|
|
|
},
|
2011-03-02 12:46:28 +01:00
|
|
|
loadedTestFrameworks <<= (testFrameworks, streams, testLoader) map { (frameworks, s, loader) =>
|
2011-02-06 17:33:29 +01:00
|
|
|
frameworks.flatMap(f => f.create(loader, s.log).map( x => (f,x)).toIterable).toMap
|
|
|
|
|
},
|
2011-04-23 19:17:21 +02:00
|
|
|
definedTests <<= TaskData.writeRelated(detectTests)(_.map(_.name).distinct) triggeredBy compile,
|
2011-04-07 02:55:30 +02:00
|
|
|
testListeners :== Nil,
|
|
|
|
|
testOptions :== Nil,
|
|
|
|
|
executeTests <<= (streams in test, loadedTestFrameworks, testOptions in test, testLoader, definedTests) flatMap {
|
2011-03-05 14:25:17 +01:00
|
|
|
(s, frameworkMap, options, loader, discovered) => Tests(frameworkMap, loader, discovered, options, s.log)
|
2011-02-06 17:33:29 +01:00
|
|
|
},
|
2011-03-05 14:25:17 +01:00
|
|
|
test <<= (executeTests, streams) map { (results, s) => Tests.showResults(s.log, results) },
|
2011-03-02 12:46:28 +01:00
|
|
|
testOnly <<= testOnlyTask
|
2011-02-06 03:40:10 +01:00
|
|
|
)
|
|
|
|
|
|
2011-04-07 02:55:30 +02:00
|
|
|
def testTaskOptions(key: Scoped): Seq[Setting[_]] = inTask(key)( Seq(
|
2011-05-08 04:02:06 +02:00
|
|
|
testListeners <<= (streams, resolvedScoped, streamsManager, logBuffered in key, testListeners) map { (s, sco, sm, buff, ls) =>
|
|
|
|
|
TestLogger(s.log, testLogger(sm, test in sco.scope), buff) +: ls
|
|
|
|
|
},
|
2011-04-07 02:55:30 +02:00
|
|
|
testOptions <<= (testOptions, testListeners) map { (options, ls) => Tests.Listeners(ls) +: options }
|
|
|
|
|
) )
|
2011-05-08 04:02:06 +02:00
|
|
|
def testLogger(manager: Streams, baseKey: Scoped)(tdef: TestDefinition): Logger =
|
|
|
|
|
{
|
|
|
|
|
val scope = baseKey.scope
|
|
|
|
|
val extra = scope.extra match { case Select(x) => x; case _ => AttributeMap.empty }
|
|
|
|
|
val key = ScopedKey(scope.copy(extra = Select(testExtra(extra, tdef))), baseKey.key)
|
|
|
|
|
manager(key).log
|
|
|
|
|
}
|
|
|
|
|
def buffered(log: Logger): Logger = new BufferedLogger(FullLogger(log))
|
|
|
|
|
def testExtra(extra: AttributeMap, tdef: TestDefinition): AttributeMap =
|
|
|
|
|
{
|
|
|
|
|
val mod = tdef.fingerprint match { case f: SubclassFingerprint => f.isModule; case f: AnnotatedFingerprint => f.isModule; case _ => false }
|
|
|
|
|
extra.put(name.key, tdef.name).put(isModule, mod)
|
|
|
|
|
}
|
2011-04-07 02:55:30 +02:00
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def testOnlyTask =
|
2011-04-23 02:13:24 +02:00
|
|
|
InputTask( TaskData(definedTests)(testOnlyParser)(Nil) ) { result =>
|
2011-04-07 02:55:30 +02:00
|
|
|
(streams, loadedTestFrameworks, testOptions in testOnly, testLoader, definedTests, result) flatMap {
|
2011-02-26 00:35:52 +01:00
|
|
|
case (s, frameworks, opts, loader, discovered, (tests, frameworkOptions)) =>
|
2011-03-05 14:25:17 +01:00
|
|
|
val modifiedOpts = Tests.Filter(if(tests.isEmpty) _ => true else tests.toSet ) +: Tests.Argument(frameworkOptions : _*) +: opts
|
|
|
|
|
Tests(frameworks, loader, discovered, modifiedOpts, s.log) map { results =>
|
|
|
|
|
Tests.showResults(s.log, results)
|
2011-02-12 02:22:17 +01:00
|
|
|
}
|
|
|
|
|
}
|
2011-04-23 02:13:24 +02:00
|
|
|
}
|
|
|
|
|
def detectTests: Initialize[Task[Seq[TestDefinition]]] = (loadedTestFrameworks, compile, streams) map { (frameworkMap, analysis, s) =>
|
|
|
|
|
Tests.discover(frameworkMap.values.toSeq, analysis, s.log)._1
|
|
|
|
|
}
|
2011-03-14 02:34:17 +01:00
|
|
|
|
2011-02-10 14:16:07 +01:00
|
|
|
lazy val packageBase = Seq(
|
2011-05-08 04:02:05 +02:00
|
|
|
artifact <<= normalizedName(n => Artifact(n)),
|
2011-03-02 12:46:28 +01:00
|
|
|
packageOptions in GlobalScope :== Nil,
|
2011-04-14 13:32:42 +02:00
|
|
|
artifactName in GlobalScope :== ( Artifact.artifactName _ )
|
2011-02-10 14:16:07 +01:00
|
|
|
)
|
|
|
|
|
lazy val packageConfig = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
packageOptions in packageBin <<= (packageOptions, mainClass in packageBin) map { _ ++ _.map(Package.MainClass.apply).toList }
|
2011-02-10 14:16:07 +01:00
|
|
|
) ++
|
2011-04-14 13:45:43 +02:00
|
|
|
packageTasks(packageBin, packageBinTask) ++
|
|
|
|
|
packageTasks(packageSrc, packageSrcTask) ++
|
|
|
|
|
packageTasks(packageDoc, packageDocTask)
|
2011-04-14 13:32:42 +02:00
|
|
|
|
|
|
|
|
final val SourceClassifier = "sources"
|
|
|
|
|
final val DocClassifier = "javadoc"
|
2011-02-10 14:16:07 +01:00
|
|
|
|
2011-04-22 02:50:15 +02:00
|
|
|
private[this] val allSubpaths = (dir: File) => (dir.*** --- dir) x (relativeTo(dir)|flat)
|
2011-02-10 14:16:07 +01:00
|
|
|
|
2011-03-17 03:22:20 +01:00
|
|
|
def packageBinTask = classMappings
|
2011-03-02 12:46:28 +01:00
|
|
|
def packageDocTask = doc map allSubpaths
|
2011-04-27 03:07:53 +02:00
|
|
|
def packageSrcTask = concatMappings(resourceMappings, sourceMappings)
|
2011-02-24 01:19:44 +01:00
|
|
|
|
|
|
|
|
private type Mappings = Initialize[Task[Seq[(File, String)]]]
|
2011-04-27 03:07:53 +02:00
|
|
|
def concatMappings(as: Mappings, bs: Mappings) = (as zipWith bs)( (a,b) => (a :^: b :^: KNil) map { case a :+: b :+: HNil => a ++ b } )
|
2011-03-17 03:22:20 +01:00
|
|
|
def classMappings = (compileInputs, products) map { (in, _) => allSubpaths(in.config.classesDirectory) }
|
2011-02-24 01:19:44 +01:00
|
|
|
// drop base directories, since there are no valid mappings for these
|
2011-04-27 03:07:53 +02:00
|
|
|
def sourceMappings = (unmanagedSources, unmanagedSourceDirectories, baseDirectory) map { (srcs, sdirs, base) =>
|
2011-04-22 02:50:15 +02:00
|
|
|
( (srcs --- sdirs --- base) x (relativeTo(sdirs)|relativeTo(base)|flat)) toSeq
|
2011-02-24 01:19:44 +01:00
|
|
|
}
|
2011-04-27 03:07:53 +02:00
|
|
|
def resourceMappings = (unmanagedResources, unmanagedResourceDirectories) map { (rs, rdirs) =>
|
2011-04-22 02:50:15 +02:00
|
|
|
(rs --- rdirs) x (relativeTo(rdirs)|flat) toSeq
|
2011-02-10 14:16:07 +01:00
|
|
|
}
|
2011-02-24 01:19:44 +01:00
|
|
|
|
2011-04-27 03:07:53 +02:00
|
|
|
def collectFiles(dirs: ScopedTaskable[Seq[File]], filter: ScopedTaskable[FileFilter], excludes: ScopedTaskable[FileFilter]): Initialize[Task[Seq[File]]] =
|
|
|
|
|
(dirs, filter, excludes) map { (d,f,excl) => d.descendentsExcept(f,excl).getFiles }
|
|
|
|
|
|
2011-04-16 01:55:22 +02:00
|
|
|
def artifactPathSetting(art: ScopedSetting[Artifact]) = (crossTarget, projectID, art, scalaVersion, artifactName) { (t, module, a, sv, toString) => t / toString(sv, module, a) asFile }
|
2011-02-10 14:16:07 +01:00
|
|
|
|
2011-04-14 13:32:42 +02:00
|
|
|
def pairID[A,B] = (a: A, b: B) => (a,b)
|
2011-04-14 13:45:43 +02:00
|
|
|
def packageTasks(key: TaskKey[File], mappingsTask: Initialize[Task[Seq[(File,String)]]]) =
|
2011-02-10 14:16:07 +01:00
|
|
|
inTask(key)( Seq(
|
|
|
|
|
key in ThisScope.copy(task = Global) <<= packageTask,
|
2011-04-14 13:32:42 +02:00
|
|
|
packageConfiguration <<= packageConfigurationTask,
|
2011-03-02 12:46:28 +01:00
|
|
|
mappings <<= mappingsTask,
|
2011-04-14 13:32:42 +02:00
|
|
|
packagedArtifact <<= (artifact, key) map pairID,
|
|
|
|
|
artifact <<= (artifact, artifactClassifier, configuration) { (a,classifier,c) =>
|
|
|
|
|
val cPart = if(c == Compile) Nil else c.name :: Nil
|
|
|
|
|
val combined = cPart ++ classifier.toList
|
|
|
|
|
a.copy(classifier = if(combined.isEmpty) None else Some(combined mkString "-"))
|
|
|
|
|
},
|
2011-03-02 12:46:28 +01:00
|
|
|
cacheDirectory <<= cacheDirectory / key.key.label,
|
2011-04-16 01:55:22 +02:00
|
|
|
artifactPath <<= artifactPathSetting(artifact)
|
2011-02-10 14:16:07 +01:00
|
|
|
))
|
2011-04-14 13:32:42 +02:00
|
|
|
def packageTask: Initialize[Task[File]] =
|
|
|
|
|
(packageConfiguration, cacheDirectory, streams) map { (config, cacheDir, s) =>
|
2011-03-02 12:46:28 +01:00
|
|
|
Package(config, cacheDir, s.log)
|
2011-04-14 13:32:42 +02:00
|
|
|
config.jar
|
|
|
|
|
}
|
|
|
|
|
def packageConfigurationTask: Initialize[Task[Package.Configuration]] =
|
|
|
|
|
(mappings, artifactPath, packageOptions) map { (srcs, path, options) =>
|
|
|
|
|
new Package.Configuration(srcs, path, options)
|
2011-02-10 14:16:07 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-06 03:40:10 +01:00
|
|
|
def selectRunMain(classes: Seq[String]): Option[String] =
|
|
|
|
|
sbt.SelectMainClass(Some(SimpleReader readLine _), classes)
|
2011-02-12 02:22:17 +01:00
|
|
|
def selectPackageMain(classes: Seq[String]): Option[String] =
|
|
|
|
|
sbt.SelectMainClass(None, classes)
|
|
|
|
|
|
2011-04-13 02:58:40 +02:00
|
|
|
def doClean(clean: Seq[File], preserve: Seq[File]): Unit =
|
|
|
|
|
IO.withTemporaryDirectory { temp =>
|
2011-04-13 05:10:36 +02:00
|
|
|
val mappings = preserve.filter(_.exists).zipWithIndex map { case (f, i) => (f, new File(temp, i.toHexString)) }
|
2011-04-13 02:58:40 +02:00
|
|
|
IO.move(mappings)
|
|
|
|
|
IO.delete(clean)
|
|
|
|
|
IO.move(mappings.map(_.swap))
|
|
|
|
|
}
|
2011-03-28 00:09:40 +02:00
|
|
|
def runMainTask(classpath: ScopedTask[Classpath], scalaRun: ScopedSetting[ScalaRun]): Initialize[InputTask[Unit]] =
|
|
|
|
|
{
|
|
|
|
|
import DefaultParsers._
|
2011-04-23 19:17:21 +02:00
|
|
|
InputTask( TaskData(discoveredMainClasses)(runMainParser)(Nil) ) { result =>
|
2011-03-28 00:09:40 +02:00
|
|
|
(classpath, scalaRun, streams, result) map { case (cp, runner, s, (mainClass, args)) =>
|
|
|
|
|
runner.run(mainClass, data(cp), args, s.log) foreach error
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-03-02 12:46:28 +01:00
|
|
|
def runTask(classpath: ScopedTask[Classpath], mainClassTask: ScopedTask[Option[String]], scalaRun: ScopedSetting[ScalaRun]): Initialize[InputTask[Unit]] =
|
2011-02-12 02:22:17 +01:00
|
|
|
InputTask(_ => complete.Parsers.spaceDelimited("<arg>")) { result =>
|
2011-03-02 12:46:28 +01:00
|
|
|
(classpath, mainClassTask, scalaRun, streams, result) map { (cp, main, runner, s, args) =>
|
2011-02-12 02:22:17 +01:00
|
|
|
val mainClass = main getOrElse error("No main class detected.")
|
|
|
|
|
runner.run(mainClass, data(cp), args, s.log) foreach error
|
2011-02-06 03:40:10 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def runnerSetting =
|
|
|
|
|
runner <<= (scalaInstance, baseDirectory, javaOptions, outputStrategy, fork, javaHome) { (si, base, options, strategy, forkRun, javaHomeDir) =>
|
|
|
|
|
if(forkRun) {
|
|
|
|
|
new ForkRun( ForkOptions(scalaJars = si.jars, javaHome = javaHomeDir, outputStrategy = strategy,
|
2011-02-26 00:35:52 +01:00
|
|
|
runJVMOptions = options, workingDirectory = Some(base)) )
|
|
|
|
|
} else
|
|
|
|
|
new Run(si)
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-12 02:22:17 +01:00
|
|
|
def docTask: Initialize[Task[File]] =
|
2011-04-21 00:31:10 +02:00
|
|
|
(cacheDirectory, compileInputs, streams, docDirectory, configuration, scaladocOptions) map { (cache, in, s, target, config, options) =>
|
2011-02-06 17:33:29 +01:00
|
|
|
val d = new Scaladoc(in.config.maxErrors, in.compilers.scalac)
|
2011-04-21 00:31:10 +02:00
|
|
|
val cp = in.config.classpath.toList - in.config.classesDirectory
|
|
|
|
|
d.cached(cache / "doc", nameForSrc(config.name), in.config.sources, cp, target, options, s.log)
|
2011-02-10 14:16:07 +01:00
|
|
|
target
|
2011-02-06 17:33:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-04-20 04:24:52 +02:00
|
|
|
def mainRunTask = run <<= runTask(fullClasspath in Runtime, mainClass in run, runner in run)
|
|
|
|
|
def mainRunMainTask = runMain <<= runMainTask(fullClasspath in Runtime, runner in run)
|
2011-02-06 03:40:10 +01:00
|
|
|
|
2011-02-27 05:56:30 +01:00
|
|
|
def discoverMainClasses(analysis: inc.Analysis): Seq[String] =
|
2011-03-05 14:25:17 +01:00
|
|
|
Discovery.applications(Tests.allDefs(analysis)) collect { case (definition, discovered) if(discovered.hasMain) => definition.name }
|
2011-03-02 12:46:28 +01:00
|
|
|
|
2011-04-09 01:15:13 +02:00
|
|
|
def consoleProjectTask = (state, streams, initialCommands in consoleProject) map { (state, s, extra) => ConsoleProject(state, extra)(s.log); println() }
|
2011-03-02 12:46:28 +01:00
|
|
|
def consoleTask: Initialize[Task[Unit]] = consoleTask(fullClasspath, console)
|
|
|
|
|
def consoleQuickTask = consoleTask(externalDependencyClasspath, consoleQuick)
|
|
|
|
|
def consoleTask(classpath: TaskKey[Classpath], task: TaskKey[_]): Initialize[Task[Unit]] = (compilers, classpath, scalacOptions in task, initialCommands in task, streams) map {
|
|
|
|
|
(cs, cp, options, initCommands, s) =>
|
|
|
|
|
(new Console(cs.scalac))(data(cp), options, initCommands, s.log).foreach(msg => error(msg))
|
2011-02-06 03:40:10 +01:00
|
|
|
println()
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-05 14:25:17 +01:00
|
|
|
def compileTask = (compileInputs, streams) map { (i,s) => Compiler(i,s.log) }
|
2011-02-03 13:17:47 +01:00
|
|
|
def compileInputsTask =
|
2011-04-04 03:15:35 +02:00
|
|
|
(dependencyClasspath, sources, compilers, javacOptions, scalacOptions, cacheDirectory, classDirectory, compileOrder, streams) map {
|
|
|
|
|
(cp, srcs, cs, javacOpts, scalacOpts, cacheDir, classes, order, s) =>
|
2011-02-03 13:17:47 +01:00
|
|
|
val classpath = classes +: data(cp)
|
|
|
|
|
val analysis = analysisMap(cp)
|
2011-03-02 12:46:28 +01:00
|
|
|
val cache = cacheDir / "compile"
|
2011-04-04 03:15:35 +02:00
|
|
|
Compiler.inputs(classpath, srcs, classes, scalacOpts, javacOpts, analysis, cache, 100, order)(cs, s.log)
|
2011-02-03 13:17:47 +01:00
|
|
|
}
|
|
|
|
|
|
2011-03-14 02:34:17 +01:00
|
|
|
def writePluginsDescriptor(plugins: Set[String], dir: File): List[File] =
|
|
|
|
|
{
|
|
|
|
|
val descriptor: File = dir / "sbt" / "sbt.plugins"
|
|
|
|
|
if(plugins.isEmpty)
|
|
|
|
|
{
|
|
|
|
|
IO.delete(descriptor)
|
|
|
|
|
Nil
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2011-03-17 03:21:02 +01:00
|
|
|
IO.writeLines(descriptor, plugins.toSeq.sorted)
|
2011-03-14 02:34:17 +01:00
|
|
|
descriptor :: Nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
def discoverPlugins: Initialize[Task[Set[String]]] = (compile, sbtPlugin, streams) map { (analysis, isPlugin, s) => if(isPlugin) discoverSbtPlugins(analysis, s.log) else Set.empty }
|
|
|
|
|
def discoverSbtPlugins(analysis: inc.Analysis, log: Logger): Set[String] =
|
|
|
|
|
{
|
|
|
|
|
val pluginClass = classOf[Plugin].getName
|
|
|
|
|
val discovery = Discovery(Set(pluginClass), Set.empty)( Tests allDefs analysis )
|
|
|
|
|
discovery collect { case (df, disc) if (disc.baseClasses contains pluginClass) && disc.isModule => df.name } toSet;
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def copyResourcesTask =
|
|
|
|
|
(classDirectory, cacheDirectory, resources, resourceDirectories, streams) map { (target, cache, resrcs, dirs, s) =>
|
2011-02-06 19:01:50 +01:00
|
|
|
val cacheFile = cache / "copy-resources"
|
2011-04-22 02:50:15 +02:00
|
|
|
val mappings = (resrcs --- dirs) x (rebase(dirs, target) | flat(target))
|
2011-02-06 19:01:50 +01:00
|
|
|
s.log.debug("Copy resource mappings: " + mappings.mkString("\n\t","\n\t",""))
|
|
|
|
|
Sync(cacheFile)( mappings )
|
|
|
|
|
mappings
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-23 19:17:21 +02:00
|
|
|
def runMainParser: (State, Seq[String]) => Parser[(String, Seq[String])] =
|
|
|
|
|
{
|
|
|
|
|
import DefaultParsers._
|
|
|
|
|
(state, mainClasses) => Space ~> token(NotSpace examples mainClasses.toSet) ~ spaceDelimited("<arg>")
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-23 02:13:24 +02:00
|
|
|
def testOnlyParser: (State, Seq[String]) => Parser[(Seq[String],Seq[String])] =
|
|
|
|
|
{ (state, tests) =>
|
2011-02-12 02:22:17 +01:00
|
|
|
import DefaultParsers._
|
|
|
|
|
def distinctParser(exs: Set[String]): Parser[Seq[String]] =
|
2011-04-19 23:56:12 +02:00
|
|
|
(token(Space) ~> token((NotSpace - "--") examples exs) ).flatMap(ex => distinctParser(exs - ex).map(ex +: _)) ?? Nil
|
2011-02-12 02:22:17 +01:00
|
|
|
val selectTests = distinctParser(tests.toSet) // todo: proper IDs
|
2011-04-19 23:56:12 +02:00
|
|
|
val options = (token(Space) ~> token("--") ~> spaceDelimited("<option>")) ?? Nil
|
2011-02-12 02:22:17 +01:00
|
|
|
selectTests ~ options
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-01 14:54:06 +01:00
|
|
|
def inAllDependencies[T](base: ProjectRef, key: ScopedSetting[T], structure: Load.BuildStructure): Seq[T] =
|
|
|
|
|
{
|
|
|
|
|
def deps(ref: ProjectRef): Seq[ProjectRef] =
|
|
|
|
|
Project.getProject(ref, structure).toList.flatMap { p =>
|
|
|
|
|
p.dependencies.map(_.project) ++ p.aggregate
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inAllDeps(base, deps, key, structure.data)
|
|
|
|
|
}
|
|
|
|
|
def inAllDeps[T](base: ProjectRef, deps: ProjectRef => Seq[ProjectRef], key: ScopedSetting[T], data: Settings[Scope]): Seq[T] =
|
|
|
|
|
inAllProjects(Dag.topologicalSort(base)(deps), key, data)
|
2011-03-03 12:44:19 +01:00
|
|
|
def inAllProjects[T](allProjects: Seq[Reference], key: ScopedSetting[T], data: Settings[Scope]): Seq[T] =
|
2011-03-01 14:54:06 +01:00
|
|
|
allProjects.flatMap { p => key in p get data }
|
|
|
|
|
|
2011-02-12 02:22:17 +01:00
|
|
|
val CompletionsID = "completions"
|
2011-02-21 16:07:58 +01:00
|
|
|
|
2011-03-03 12:44:19 +01:00
|
|
|
def noAggregation = Seq(run, console, consoleQuick, consoleProject)
|
2011-02-21 16:07:58 +01:00
|
|
|
lazy val disableAggregation = noAggregation map disableAggregate
|
|
|
|
|
def disableAggregate(k: Scoped) =
|
2011-03-02 12:46:28 +01:00
|
|
|
aggregate in Scope.GlobalScope.copy(task = Select(k.key)) :== false
|
2011-02-21 16:07:58 +01:00
|
|
|
|
2011-02-26 00:35:52 +01:00
|
|
|
lazy val baseTasks: Seq[Setting[_]] = projectTasks ++ packageBase
|
2011-02-06 03:40:10 +01:00
|
|
|
|
2011-02-26 00:35:52 +01:00
|
|
|
lazy val baseClasspaths = Classpaths.publishSettings ++ Classpaths.baseSettings
|
2011-04-12 04:12:03 +02:00
|
|
|
lazy val configSettings = Classpaths.configSettings ++ configTasks ++ configPaths ++ packageConfig ++ Classpaths.compilerPluginConfig
|
2011-02-26 00:35:52 +01:00
|
|
|
|
2011-03-28 00:09:40 +02:00
|
|
|
lazy val compileSettings = configSettings ++ (mainRunMainTask +: mainRunTask +: addBaseSources)
|
2011-02-26 00:35:52 +01:00
|
|
|
lazy val testSettings = configSettings ++ testTasks
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-04-20 04:24:52 +02:00
|
|
|
lazy val itSettings = inConfig(IntegrationTest)(testSettings)
|
2011-05-03 02:41:36 +02:00
|
|
|
lazy val defaultConfigs = inConfig(Compile)(compileSettings) ++ inConfig(Test)(testSettings) ++ inConfig(Runtime)(Classpaths.configSettings)
|
2011-04-20 04:24:52 +02:00
|
|
|
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-04-09 01:15:13 +02:00
|
|
|
// settings that are not specific to a configuration
|
|
|
|
|
lazy val projectBaseSettings: Seq[Setting[_]] = projectCore ++ paths ++ baseClasspaths ++ baseTasks ++ compileBase ++ disableAggregation
|
|
|
|
|
lazy val defaultSettings: Seq[Setting[_]] = projectBaseSettings ++ defaultConfigs
|
2011-02-03 13:17:47 +01:00
|
|
|
}
|
|
|
|
|
object Classpaths
|
|
|
|
|
{
|
|
|
|
|
import Path._
|
|
|
|
|
import GlobFilter._
|
|
|
|
|
import Keys._
|
|
|
|
|
import Scope.ThisScope
|
2011-03-05 14:25:17 +01:00
|
|
|
import Defaults._
|
2011-02-05 04:02:39 +01:00
|
|
|
import Attributed.{blank, blankSeq}
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-02-12 02:22:17 +01:00
|
|
|
def concat[T](a: ScopedTaskable[Seq[T]], b: ScopedTaskable[Seq[T]]): Initialize[Task[Seq[T]]] = (a,b) map (_ ++ _)
|
2011-04-27 03:07:53 +02:00
|
|
|
def concatSettings[T](a: ScopedSetting[Seq[T]], b: ScopedSetting[Seq[T]]): Initialize[Seq[T]] = (a,b)(_ ++ _)
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-02-27 05:56:30 +01:00
|
|
|
lazy val configSettings: Seq[Setting[_]] = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
externalDependencyClasspath <<= concat(unmanagedClasspath, managedClasspath),
|
|
|
|
|
dependencyClasspath <<= concat(internalDependencyClasspath, externalDependencyClasspath),
|
|
|
|
|
fullClasspath <<= concat(products, dependencyClasspath),
|
|
|
|
|
internalDependencyClasspath <<= internalDependencies,
|
|
|
|
|
unmanagedClasspath <<= unmanagedDependencies,
|
|
|
|
|
products <<= makeProducts,
|
2011-04-20 04:24:52 +02:00
|
|
|
classpathConfiguration <<= (internalConfigurationMap, configuration)( _ apply _ ),
|
|
|
|
|
managedClasspath <<= (classpathConfiguration, classpathTypes, update) map managedJars,
|
2011-05-08 04:02:06 +02:00
|
|
|
unmanagedJars <<= (configuration, unmanagedBase, classpathFilter, defaultExcludes in unmanagedJars) map { (config, base, filter, excl) =>
|
2011-03-17 03:22:20 +01:00
|
|
|
(base * (filter -- excl) +++ (base / config.name).descendentsExcept(filter, excl)).getFiles
|
2011-02-05 04:02:39 +01:00
|
|
|
}
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
2011-04-14 13:32:42 +02:00
|
|
|
def defaultPackageKeys = Seq(packageBin, packageSrc, packageDoc)
|
|
|
|
|
lazy val defaultPackages: Seq[ScopedTask[File]] =
|
|
|
|
|
for(task <- defaultPackageKeys; conf <- Seq(Compile, Test)) yield (task in conf)
|
|
|
|
|
lazy val defaultArtifactTasks: Seq[ScopedTask[File]] = makePom +: defaultPackages
|
|
|
|
|
|
|
|
|
|
def packaged(pkgTasks: Seq[ScopedTask[File]]): Initialize[Task[Map[Artifact, File]]] =
|
|
|
|
|
enabledOnly(packagedArtifact.task, pkgTasks).map(_.join.map(_.toMap))
|
|
|
|
|
def artifactDefs(pkgTasks: Seq[ScopedTask[File]]): Initialize[Seq[Artifact]] =
|
|
|
|
|
enabledOnly(artifact, pkgTasks)
|
|
|
|
|
|
|
|
|
|
def enabledOnly[T](key: ScopedSetting[T], pkgTasks: Seq[ScopedTask[File]]): Initialize[Seq[T]] =
|
|
|
|
|
( forallIn(key, pkgTasks) zipWith forallIn(publishArtifact, pkgTasks) ) ( _ zip _ collect { case (a, true) => a } )
|
|
|
|
|
def forallIn[T](key: ScopedSetting[T], pkgTasks: Seq[ScopedTask[_]]): Initialize[Seq[T]] =
|
|
|
|
|
pkgTasks.map( pkg => key in pkg.scope in pkg ).join
|
|
|
|
|
|
2011-02-27 05:56:30 +01:00
|
|
|
val publishSettings: Seq[Setting[_]] = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
publishMavenStyle in GlobalScope :== true,
|
2011-04-14 13:32:42 +02:00
|
|
|
publishArtifact in GlobalScope in Compile :== true,
|
|
|
|
|
publishArtifact in GlobalScope in Test:== false,
|
|
|
|
|
artifacts <<= artifactDefs(defaultArtifactTasks),
|
|
|
|
|
packagedArtifacts <<= packaged(defaultArtifactTasks),
|
|
|
|
|
makePom <<= (ivyModule, makePomConfiguration, streams) map { (module, config, s) => IvyActions.makePom(module, config, s.log); config.file },
|
|
|
|
|
packagedArtifact in makePom <<= (artifact in makePom, makePom) map pairID,
|
|
|
|
|
deliver <<= deliverTask(deliverConfiguration),
|
|
|
|
|
deliverLocal <<= deliverTask(deliverLocalConfiguration),
|
2011-03-02 12:46:28 +01:00
|
|
|
publish <<= publishTask(publishConfiguration, deliver),
|
|
|
|
|
publishLocal <<= publishTask(publishLocalConfiguration, deliverLocal)
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
2011-02-27 05:56:30 +01:00
|
|
|
val baseSettings: Seq[Setting[_]] = Seq(
|
2011-03-02 12:46:28 +01:00
|
|
|
unmanagedBase <<= baseDirectory / "lib",
|
|
|
|
|
normalizedName <<= name(StringUtilities.normalize),
|
2011-04-16 17:24:58 +02:00
|
|
|
organization <<= normalizedName.identity,
|
2011-03-02 12:46:28 +01:00
|
|
|
classpathFilter in GlobalScope :== "*.jar",
|
2011-03-17 01:09:59 +01:00
|
|
|
fullResolvers <<= (projectResolver,resolvers,sbtPlugin,sbtResolver) map { (pr,rs,isPlugin,sr) =>
|
|
|
|
|
val base = pr +: Resolver.withDefaultResolvers(rs)
|
|
|
|
|
if(isPlugin) sr +: base else base
|
|
|
|
|
},
|
2011-03-02 12:46:28 +01:00
|
|
|
offline in GlobalScope :== false,
|
2011-04-16 17:24:58 +02:00
|
|
|
moduleID <<= normalizedName.identity,
|
2011-03-02 12:46:28 +01:00
|
|
|
defaultConfiguration in GlobalScope :== Some(Configurations.Compile),
|
|
|
|
|
defaultConfigurationMapping in GlobalScope <<= defaultConfiguration{ case Some(d) => "*->" + d.name; case None => "*->*" },
|
2011-04-23 21:58:59 +02:00
|
|
|
ivyPaths <<= (baseDirectory, appConfiguration) { (base, app) => new IvyPaths(base, bootIvyHome(app)) },
|
2011-04-02 03:06:49 +02:00
|
|
|
otherResolvers <<= publishTo(_.toList),
|
2011-03-02 12:46:28 +01:00
|
|
|
projectResolver <<= projectResolverTask,
|
|
|
|
|
projectDependencies <<= projectDependenciesTask,
|
|
|
|
|
libraryDependencies in GlobalScope :== Nil,
|
2011-03-17 01:09:59 +01:00
|
|
|
allDependencies <<= (projectDependencies,libraryDependencies,sbtPlugin,sbtDependency) map { (projDeps, libDeps, isPlugin, sbtDep) =>
|
|
|
|
|
val base = projDeps ++ libDeps
|
|
|
|
|
if(isPlugin) sbtDep +: base else base
|
|
|
|
|
},
|
2011-03-02 12:46:28 +01:00
|
|
|
ivyLoggingLevel in GlobalScope :== UpdateLogging.Quiet,
|
|
|
|
|
ivyXML in GlobalScope :== NodeSeq.Empty,
|
|
|
|
|
ivyValidate in GlobalScope :== false,
|
2011-04-17 02:18:16 +02:00
|
|
|
ivyScala in GlobalScope <<= (scalaHome, scalaVersion)((sh,v) => Some(new IvyScala(v, Nil, filterImplicit = true, checkExplicit = true, overrideScalaVersion = sh.isEmpty))),
|
2011-03-02 12:46:28 +01:00
|
|
|
moduleConfigurations in GlobalScope :== Nil,
|
|
|
|
|
publishTo in GlobalScope :== None,
|
2011-04-16 01:55:22 +02:00
|
|
|
artifactPath in makePom <<= artifactPathSetting(artifact in makePom),
|
2011-04-16 17:24:58 +02:00
|
|
|
publishArtifact in makePom <<= publishMavenStyle.identity,
|
2011-04-14 13:32:42 +02:00
|
|
|
artifact in makePom <<= moduleID( name => Artifact(name, "pom", "pom") ),
|
2011-05-08 04:02:05 +02:00
|
|
|
projectID <<= (organization,moduleID,version,artifacts,crossPaths){ (org,module,version,as,crossEnabled) =>
|
|
|
|
|
ModuleID(org, module, version).cross(crossEnabled).artifacts(as : _*)
|
2011-02-21 16:22:39 +01:00
|
|
|
},
|
2011-03-10 00:04:53 +01:00
|
|
|
resolvers in GlobalScope :== Nil,
|
2011-03-02 12:46:28 +01:00
|
|
|
projectDescriptors <<= depMap,
|
2011-03-29 04:28:54 +02:00
|
|
|
retrievePattern in GlobalScope :== "[type]/[organisation]/[module]/[artifact](-[revision])(-[classifier]).[ext]",
|
2011-03-16 01:35:43 +01:00
|
|
|
updateConfiguration <<= (retrieveConfiguration, ivyLoggingLevel)((conf,level) => new UpdateConfiguration(conf, false, level) ),
|
|
|
|
|
retrieveConfiguration <<= (managedDirectory, retrievePattern, retrieveManaged) { (libm, pattern, enabled) => if(enabled) Some(new RetrieveConfiguration(libm, pattern)) else None },
|
2011-04-16 00:25:54 +02:00
|
|
|
ivyConfiguration <<= (fullResolvers, ivyPaths, otherResolvers, moduleConfigurations, offline, checksums, appConfiguration, streams) map { (rs, paths, other, moduleConfs, off, check, app, s) =>
|
2011-04-16 17:14:45 +02:00
|
|
|
new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, Some(lock(app)), check, s.log)
|
2011-02-05 04:02:39 +01:00
|
|
|
},
|
2011-04-20 04:24:52 +02:00
|
|
|
ivyConfigurations <<= (autoCompilerPlugins, internalConfigurationMap, thisProject) { (auto, internalMap, project) =>
|
|
|
|
|
(project.configurations ++ project.configurations.map(internalMap) ++ (if(auto) CompilerPlugin :: Nil else Nil)).distinct
|
2011-04-12 04:12:03 +02:00
|
|
|
},
|
2011-04-14 13:32:42 +02:00
|
|
|
moduleSettings <<= moduleSettings0,
|
2011-04-22 02:49:38 +02:00
|
|
|
makePomConfiguration <<= (artifactPath in makePom, pomExtra, pomPostProcess, pomIncludeRepository) {
|
|
|
|
|
(file, extra, process, include) => new MakePomConfiguration(file, None, extra, process, include)
|
|
|
|
|
},
|
2011-04-14 13:32:42 +02:00
|
|
|
deliverLocalConfiguration <<= (crossTarget, ivyLoggingLevel) map { (outDir, level) => deliverConfig( outDir, logging = level ) },
|
2011-04-16 17:24:58 +02:00
|
|
|
deliverConfiguration <<= deliverLocalConfiguration.identity,
|
2011-04-14 13:32:42 +02:00
|
|
|
publishConfiguration <<= (packagedArtifacts, publishTo, publishMavenStyle, deliver, ivyLoggingLevel) map { (arts, publishTo, mavenStyle, ivyFile, level) =>
|
|
|
|
|
publishConfig(arts, if(mavenStyle) None else Some(ivyFile), resolverName = getPublishTo(publishTo).name, logging = level)
|
|
|
|
|
},
|
|
|
|
|
publishLocalConfiguration <<= (packagedArtifacts, deliverLocal, ivyLoggingLevel) map {
|
|
|
|
|
(arts, ivyFile, level) => publishConfig(arts, Some(ivyFile), logging = level )
|
2011-02-05 04:02:39 +01:00
|
|
|
},
|
2011-04-13 02:58:40 +02:00
|
|
|
ivySbt <<= (ivyConfiguration, credentials, streams) map { (conf, creds, s) =>
|
|
|
|
|
Credentials.register(creds, s.log)
|
|
|
|
|
new IvySbt(conf)
|
|
|
|
|
},
|
2011-03-02 12:46:28 +01:00
|
|
|
ivyModule <<= (ivySbt, moduleSettings) map { (ivySbt, settings) => new ivySbt.Module(settings) },
|
2011-04-16 00:32:20 +02:00
|
|
|
update <<= (ivyModule, updateConfiguration, cacheDirectory, scalaInstance, streams) map { (module, config, cacheDirectory, si, s) =>
|
|
|
|
|
cachedUpdate(cacheDirectory / "update", module, config, Some(si), s.log)
|
2011-03-16 01:35:43 +01:00
|
|
|
},
|
|
|
|
|
transitiveClassifiers :== Seq("sources", "javadoc"),
|
2011-03-22 23:19:48 +01:00
|
|
|
updateClassifiers <<= (ivySbt, projectID, update, transitiveClassifiers, updateConfiguration, ivyScala, streams) map { (is, pid, up, classifiers, c, ivyScala, s) =>
|
|
|
|
|
IvyActions.transitive(is, pid, up, classifiers, c, ivyScala, s.log)
|
|
|
|
|
},
|
|
|
|
|
updateSbtClassifiers <<= (ivySbt, projectID, transitiveClassifiers, updateConfiguration, sbtDependency, ivyScala, streams) map { (is, pid, classifiers, c, sbtDep, ivyScala, s) =>
|
|
|
|
|
IvyActions.transitiveScratch(is, pid, "sbt", sbtDep :: Nil, classifiers, c, ivyScala, s.log)
|
2011-03-17 01:09:59 +01:00
|
|
|
},
|
|
|
|
|
sbtResolver in GlobalScope :== dbResolver,
|
|
|
|
|
sbtDependency in GlobalScope <<= appConfiguration { app =>
|
2011-03-16 01:35:43 +01:00
|
|
|
val id = app.provider.id
|
2011-03-17 01:09:59 +01:00
|
|
|
ModuleID(id.groupID, id.name, id.version, crossVersion = id.crossVersioned)
|
2011-02-05 04:02:39 +01:00
|
|
|
}
|
2011-02-03 13:17:47 +01:00
|
|
|
)
|
|
|
|
|
|
2011-04-14 13:32:42 +02:00
|
|
|
def moduleSettings0: Initialize[Task[ModuleSettings]] =
|
|
|
|
|
(projectID, allDependencies, ivyXML, ivyConfigurations, defaultConfiguration, ivyScala, ivyValidate) map {
|
|
|
|
|
(pid, deps, ivyXML, confs, defaultConf, ivyS, validate) => new InlineConfiguration(pid, deps, ivyXML, confs, defaultConf, ivyS, validate)
|
|
|
|
|
}
|
|
|
|
|
def deliverTask(config: TaskKey[DeliverConfiguration]): Initialize[Task[File]] =
|
|
|
|
|
(ivyModule, config, update, streams) map { (module, config, _, s) => IvyActions.deliver(module, config, s.log) }
|
2011-03-02 12:46:28 +01:00
|
|
|
def publishTask(config: TaskKey[PublishConfiguration], deliverKey: TaskKey[_]): Initialize[Task[Unit]] =
|
2011-04-14 13:32:42 +02:00
|
|
|
(ivyModule, config, streams) map { (module, config, s) =>
|
2011-04-06 00:44:47 +02:00
|
|
|
IvyActions.publish(module, config, s.log)
|
|
|
|
|
}
|
2011-02-03 13:17:47 +01:00
|
|
|
|
|
|
|
|
import Cache._
|
2011-04-14 13:32:42 +02:00
|
|
|
import CacheIvy.{classpathFormat, /*publishIC,*/ updateIC, updateReportF}
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-04-16 00:32:20 +02:00
|
|
|
def cachedUpdate(cacheFile: File, module: IvySbt#Module, config: UpdateConfiguration, scalaInstance: Option[ScalaInstance], log: Logger): UpdateReport =
|
2011-02-03 13:17:47 +01:00
|
|
|
{
|
|
|
|
|
implicit val updateCache = updateIC
|
2011-03-14 02:40:49 +01:00
|
|
|
implicit val updateReport = updateReportF
|
2011-03-18 02:29:35 +01:00
|
|
|
type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil
|
|
|
|
|
def work = (_: In) match { case conf :+: settings :+: config :+: HNil =>
|
2011-02-03 13:17:47 +01:00
|
|
|
log.info("Updating...")
|
2011-03-22 23:19:48 +01:00
|
|
|
val r = IvyActions.update(module, config, log)
|
2011-02-03 13:17:47 +01:00
|
|
|
log.info("Done updating.")
|
2011-04-16 00:32:20 +02:00
|
|
|
scalaInstance match { case Some(si) => substituteScalaFiles(si, r); case None => r }
|
2011-02-03 13:17:47 +01:00
|
|
|
}
|
2011-03-18 02:29:35 +01:00
|
|
|
|
|
|
|
|
val f =
|
|
|
|
|
Tracked.inputChanged(cacheFile / "inputs") { (inChanged: Boolean, in: In) =>
|
|
|
|
|
val outCache = Tracked.lastOutput[In, UpdateReport](cacheFile / "output") {
|
2011-04-16 01:55:22 +02:00
|
|
|
case (_, Some(out)) if !inChanged && out.allFiles.forall(_.exists) && out.cachedDescriptor.exists => out
|
2011-03-18 02:29:35 +01:00
|
|
|
case _ => work(in)
|
|
|
|
|
}
|
|
|
|
|
outCache(in)
|
|
|
|
|
}
|
2011-02-03 13:17:47 +01:00
|
|
|
f(module.owner.configuration :+: module.moduleSettings :+: config :+: HNil)
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
// can't cache deliver/publish easily since files involved are hidden behind patterns. publish will be difficult to verify target-side anyway
|
|
|
|
|
def cachedPublish(cacheFile: File)(g: (IvySbt#Module, PublishConfiguration) => Unit, module: IvySbt#Module, config: PublishConfiguration) => Unit =
|
|
|
|
|
{ case module :+: config :+: HNil =>
|
|
|
|
|
/* implicit val publishCache = publishIC
|
|
|
|
|
val f = cached(cacheFile) { (conf: IvyConfiguration, settings: ModuleSettings, config: PublishConfiguration) =>*/
|
|
|
|
|
g(module, config)
|
|
|
|
|
/*}
|
|
|
|
|
f(module.owner.configuration :+: module.moduleSettings :+: config :+: HNil)*/
|
|
|
|
|
}*/
|
|
|
|
|
|
2011-04-16 20:40:13 +02:00
|
|
|
def defaultRepositoryFilter = (repo: MavenRepository) => !repo.root.startsWith("file:")
|
2011-02-03 13:17:47 +01:00
|
|
|
def getPublishTo(repo: Option[Resolver]): Resolver = repo getOrElse error("Repository for publishing is not specified.")
|
|
|
|
|
|
2011-04-14 13:32:42 +02:00
|
|
|
def deliverConfig(outputDirectory: File, status: String = "release", logging: UpdateLogging.Value = UpdateLogging.DownloadOnly) =
|
|
|
|
|
new DeliverConfiguration(deliverPattern(outputDirectory), status, None, logging)
|
|
|
|
|
def publishConfig(artifacts: Map[Artifact, File], ivyFile: Option[File], resolverName: String = "local", logging: UpdateLogging.Value = UpdateLogging.DownloadOnly) =
|
|
|
|
|
new PublishConfiguration(ivyFile, resolverName, artifacts, logging)
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-04-14 13:32:42 +02:00
|
|
|
def deliverPattern(outputPath: Path): String = (outputPath / "[artifact]-[revision](-[classifier]).[ext]").absolutePath
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def projectDependenciesTask =
|
|
|
|
|
(thisProject, settings) map { (p, data) =>
|
|
|
|
|
p.dependencies flatMap { dep => (projectID in dep.project) get data map { _.copy(configurations = dep.configuration) } }
|
2011-02-03 13:17:47 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-12 02:22:17 +01:00
|
|
|
def depMap: Initialize[Task[Map[ModuleRevisionId, ModuleDescriptor]]] =
|
2011-03-22 23:19:48 +01:00
|
|
|
(thisProject, thisProjectRef, settings, streams) flatMap { (root, rootRef, data, s) =>
|
2011-03-03 12:44:19 +01:00
|
|
|
val dependencies = (p: (ProjectRef, ResolvedProject)) => p._2.dependencies.flatMap(pr => thisProject in pr.project get data map { (pr.project, _) })
|
2011-03-22 23:19:48 +01:00
|
|
|
depMap(Dag.topologicalSort((rootRef,root))(dependencies).dropRight(1), data, s.log)
|
2011-02-03 13:17:47 +01:00
|
|
|
}
|
|
|
|
|
|
2011-03-22 23:19:48 +01:00
|
|
|
def depMap(projects: Seq[(ProjectRef,ResolvedProject)], data: Settings[Scope], log: Logger): Task[Map[ModuleRevisionId, ModuleDescriptor]] =
|
2011-03-02 12:46:28 +01:00
|
|
|
projects.flatMap { case (p,_) => ivyModule in p get data }.join.map { mods =>
|
2011-02-03 13:17:47 +01:00
|
|
|
(mods.map{ mod =>
|
2011-03-22 23:19:48 +01:00
|
|
|
val md = mod.moduleDescriptor(log)
|
2011-02-03 13:17:47 +01:00
|
|
|
(md.getModuleRevisionId, md)
|
|
|
|
|
}).toMap
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def projectResolverTask: Initialize[Task[Resolver]] =
|
|
|
|
|
projectDescriptors map { m =>
|
2011-02-03 13:17:47 +01:00
|
|
|
new RawRepository(new ProjectResolver("inter-project", m))
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-02 12:46:28 +01:00
|
|
|
def analyzed[T](data: T, analysis: inc.Analysis) = Attributed.blank(data).put(Keys.analysis, analysis)
|
2011-02-12 02:22:17 +01:00
|
|
|
def makeProducts: Initialize[Task[Classpath]] =
|
2011-03-02 12:46:28 +01:00
|
|
|
(compile, compileInputs, copyResources) map { (analysis, i, _) => analyzed(i.config.classesDirectory, analysis) :: Nil }
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-02-12 02:22:17 +01:00
|
|
|
def internalDependencies: Initialize[Task[Classpath]] =
|
2011-03-02 12:46:28 +01:00
|
|
|
(thisProjectRef, thisProject, configuration, settings) flatMap internalDependencies0
|
2011-02-20 05:25:30 +01:00
|
|
|
def unmanagedDependencies: Initialize[Task[Classpath]] =
|
2011-03-02 12:46:28 +01:00
|
|
|
(thisProjectRef, thisProject, configuration, settings) flatMap unmanagedDependencies0
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-02-20 05:25:30 +01:00
|
|
|
import java.util.LinkedHashSet
|
|
|
|
|
import collection.JavaConversions.asScalaSet
|
2011-03-03 12:44:19 +01:00
|
|
|
def interSort(projectRef: ProjectRef, project: ResolvedProject, conf: Configuration, data: Settings[Scope]): Seq[(ProjectRef,String)] =
|
2011-02-03 13:17:47 +01:00
|
|
|
{
|
|
|
|
|
val visited = asScalaSet(new LinkedHashSet[(ProjectRef,String)])
|
2011-03-03 12:44:19 +01:00
|
|
|
def visit(p: ProjectRef, project: ResolvedProject, c: Configuration)
|
2011-02-03 13:17:47 +01:00
|
|
|
{
|
|
|
|
|
val applicableConfigs = allConfigs(c)
|
|
|
|
|
for(ac <- applicableConfigs) // add all configurations in this project
|
|
|
|
|
visited add (p, ac.name)
|
|
|
|
|
val masterConfs = configurationNames(project)
|
|
|
|
|
|
2011-04-08 04:48:01 +02:00
|
|
|
for( ResolvedClasspathDependency(dep, confMapping) <- project.dependencies)
|
2011-02-03 13:17:47 +01:00
|
|
|
{
|
2011-03-02 12:46:28 +01:00
|
|
|
val depProject = thisProject in dep get data getOrElse error("Invalid project: " + dep)
|
2011-02-03 13:17:47 +01:00
|
|
|
val mapping = mapped(confMapping, masterConfs, configurationNames(depProject), "compile", "*->compile")
|
|
|
|
|
// map master configuration 'c' and all extended configurations to the appropriate dependency configuration
|
|
|
|
|
for(ac <- applicableConfigs; depConfName <- mapping(ac.name))
|
|
|
|
|
{
|
2011-03-02 12:46:28 +01:00
|
|
|
val depConf = getConfiguration(dep, depProject, depConfName)
|
2011-02-03 13:17:47 +01:00
|
|
|
if( ! visited( (dep, depConfName) ) )
|
|
|
|
|
visit(dep, depProject, depConf)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
visit(projectRef, project, conf)
|
2011-02-20 05:25:30 +01:00
|
|
|
visited.toSeq
|
|
|
|
|
}
|
2011-03-03 12:44:19 +01:00
|
|
|
def unmanagedDependencies0(projectRef: ProjectRef, project: ResolvedProject, conf: Configuration, data: Settings[Scope]): Task[Classpath] =
|
2011-02-20 21:40:29 +01:00
|
|
|
interDependencies(projectRef, project, conf, data, true, unmanagedLibs)
|
2011-03-03 12:44:19 +01:00
|
|
|
def internalDependencies0(projectRef: ProjectRef, project: ResolvedProject, conf: Configuration, data: Settings[Scope]): Task[Classpath] =
|
2011-03-02 12:46:28 +01:00
|
|
|
interDependencies(projectRef, project, conf, data, false, productsTask)
|
2011-03-03 12:44:19 +01:00
|
|
|
def interDependencies(projectRef: ProjectRef, project: ResolvedProject, conf: Configuration, data: Settings[Scope], includeSelf: Boolean,
|
2011-02-20 05:25:30 +01:00
|
|
|
f: (ProjectRef, String, Settings[Scope]) => Task[Classpath]): Task[Classpath] =
|
|
|
|
|
{
|
|
|
|
|
val visited = interSort(projectRef, project, conf, data)
|
2011-02-20 21:40:29 +01:00
|
|
|
val tasks = asScalaSet(new LinkedHashSet[Task[Classpath]])
|
2011-02-03 13:17:47 +01:00
|
|
|
for( (dep, c) <- visited )
|
2011-03-03 12:44:19 +01:00
|
|
|
if(includeSelf || (dep != projectRef) || conf.name != c )
|
2011-02-20 21:40:29 +01:00
|
|
|
tasks += f(dep, c, data)
|
2011-02-03 13:17:47 +01:00
|
|
|
|
2011-02-20 21:40:29 +01:00
|
|
|
(tasks.toSeq.join).map(_.flatten.distinct)
|
2011-02-03 13:17:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def mapped(confString: Option[String], masterConfs: Seq[String], depConfs: Seq[String], default: String, defaultMapping: String): String => Seq[String] =
|
|
|
|
|
{
|
|
|
|
|
lazy val defaultMap = parseMapping(defaultMapping, masterConfs, depConfs, _ :: Nil)
|
|
|
|
|
parseMapping(confString getOrElse default, masterConfs, depConfs, defaultMap)
|
|
|
|
|
}
|
|
|
|
|
def parseMapping(confString: String, masterConfs: Seq[String], depConfs: Seq[String], default: String => Seq[String]): String => Seq[String] =
|
|
|
|
|
union(confString.split(";") map parseSingleMapping(masterConfs, depConfs, default))
|
|
|
|
|
def parseSingleMapping( masterConfs: Seq[String], depConfs: Seq[String], default: String => Seq[String])(confString: String): String => Seq[String] =
|
|
|
|
|
{
|
|
|
|
|
val ms: Seq[(String,Seq[String])] =
|
|
|
|
|
trim(confString.split("->",2)) match {
|
|
|
|
|
case x :: Nil => for(a <- parseList(x, masterConfs)) yield (a,default(a))
|
|
|
|
|
case x :: y :: Nil => val target = parseList(y, depConfs); for(a <- parseList(x, masterConfs)) yield (a,target)
|
|
|
|
|
case _ => error("Invalid configuration '" + confString + "'") // shouldn't get here
|
|
|
|
|
}
|
|
|
|
|
val m = ms.toMap
|
|
|
|
|
s => m.getOrElse(s, Nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def union[A,B](maps: Seq[A => Seq[B]]): A => Seq[B] =
|
|
|
|
|
a => (Seq[B]() /: maps) { _ ++ _(a) } distinct;
|
|
|
|
|
|
2011-03-03 12:44:19 +01:00
|
|
|
def configurationNames(p: ResolvedProject): Seq[String] = p.configurations.map( _.name)
|
2011-02-03 13:17:47 +01:00
|
|
|
def parseList(s: String, allConfs: Seq[String]): Seq[String] = (trim(s split ",") flatMap replaceWildcard(allConfs)).distinct
|
|
|
|
|
def replaceWildcard(allConfs: Seq[String])(conf: String): Seq[String] =
|
|
|
|
|
if(conf == "") Nil else if(conf == "*") allConfs else conf :: Nil
|
|
|
|
|
|
|
|
|
|
private def trim(a: Array[String]): List[String] = a.toList.map(_.trim)
|
|
|
|
|
def missingConfiguration(in: String, conf: String) =
|
|
|
|
|
error("Configuration '" + conf + "' not defined in '" + in + "'")
|
|
|
|
|
def allConfigs(conf: Configuration): Seq[Configuration] =
|
|
|
|
|
Dag.topologicalSort(conf)(_.extendsConfigs)
|
|
|
|
|
|
2011-03-03 12:44:19 +01:00
|
|
|
def getConfiguration(ref: ProjectRef, dep: ResolvedProject, conf: String): Configuration =
|
2011-02-03 13:17:47 +01:00
|
|
|
dep.configurations.find(_.name == conf) getOrElse missingConfiguration(Project display ref, conf)
|
2011-03-03 12:44:19 +01:00
|
|
|
def productsTask(dep: ResolvedReference, conf: String, data: Settings[Scope]): Task[Classpath] =
|
2011-03-02 12:46:28 +01:00
|
|
|
getClasspath(products, dep, conf, data)
|
2011-03-03 12:44:19 +01:00
|
|
|
def unmanagedLibs(dep: ResolvedReference, conf: String, data: Settings[Scope]): Task[Classpath] =
|
2011-03-02 12:46:28 +01:00
|
|
|
getClasspath(unmanagedJars, dep, conf, data)
|
2011-03-03 12:44:19 +01:00
|
|
|
def getClasspath(key: TaskKey[Classpath], dep: ResolvedReference, conf: String, data: Settings[Scope]): Task[Classpath] =
|
2011-02-20 05:25:30 +01:00
|
|
|
( key in (dep, ConfigKey(conf)) ) get data getOrElse const(Nil)
|
2011-03-03 12:44:19 +01:00
|
|
|
def defaultConfigurationTask(p: ResolvedReference, data: Settings[Scope]): Configuration =
|
2011-03-02 12:46:28 +01:00
|
|
|
flatten(defaultConfiguration in p get data) getOrElse Configurations.Default
|
2011-04-16 17:24:58 +02:00
|
|
|
def flatten[T](o: Option[Option[T]]): Option[T] = o flatMap idFun
|
2011-03-14 02:40:49 +01:00
|
|
|
|
2011-03-17 01:09:59 +01:00
|
|
|
lazy val dbResolver = Resolver.url("sbt-db", new URL("http://databinder.net/repo/"))(Resolver.ivyStylePatterns)
|
2011-04-10 22:22:48 +02:00
|
|
|
|
|
|
|
|
import DependencyFilter._
|
|
|
|
|
def managedJars(config: Configuration, jarTypes: Set[String], up: UpdateReport): Classpath = up.select( configuration = configurationFilter(config.name), artifact = artifactFilter(`type` = jarTypes) )
|
2011-04-12 04:12:03 +02:00
|
|
|
|
|
|
|
|
def autoPlugins(report: UpdateReport): Seq[String] =
|
|
|
|
|
{
|
|
|
|
|
val pluginClasspath = report matching configurationFilter(CompilerPlugin.name)
|
|
|
|
|
classpath.ClasspathUtilities.compilerPlugins(pluginClasspath).map("-Xplugin:" + _.getAbsolutePath).toSeq
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lazy val compilerPluginConfig = Seq(
|
2011-04-13 04:58:32 +02:00
|
|
|
scalacOptions <<= (scalacOptions, autoCompilerPlugins, update) map { (options, auto, report) =>
|
|
|
|
|
if(auto) options ++ autoPlugins(report) else options
|
2011-04-12 04:12:03 +02:00
|
|
|
}
|
|
|
|
|
)
|
2011-04-16 00:32:20 +02:00
|
|
|
def substituteScalaFiles(scalaInstance: ScalaInstance, report: UpdateReport): UpdateReport =
|
|
|
|
|
report.substitute { (configuration, module, arts) =>
|
|
|
|
|
import ScalaArtifacts._
|
|
|
|
|
(module.organization, module.name) match
|
|
|
|
|
{
|
|
|
|
|
case (Organization, LibraryID) => (Artifact(LibraryID), scalaInstance.libraryJar) :: Nil
|
|
|
|
|
case (Organization, CompilerID) => (Artifact(CompilerID), scalaInstance.compilerJar) :: Nil
|
|
|
|
|
case _ => arts
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-04-23 21:58:59 +02:00
|
|
|
|
|
|
|
|
// support earlier launchers
|
|
|
|
|
def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
|
|
|
|
|
try { Option(app.provider.scalaProvider.launcher.ivyHome) }
|
|
|
|
|
catch { case _: NoSuchMethodError => None }
|
2011-03-17 01:09:59 +01:00
|
|
|
}
|
2011-04-12 04:12:03 +02:00
|
|
|
|
2011-04-16 01:55:22 +02:00
|
|
|
trait BuildExtra
|
2011-04-12 04:12:03 +02:00
|
|
|
{
|
2011-04-16 19:16:54 +02:00
|
|
|
import Defaults._
|
|
|
|
|
|
2011-04-12 04:12:03 +02:00
|
|
|
def compilerPlugin(dependency: ModuleID): ModuleID =
|
|
|
|
|
dependency.copy(configurations = Some("plugin->default(compile)"))
|
|
|
|
|
|
|
|
|
|
def addCompilerPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
|
|
|
|
|
libraryDependencies += compilerPlugin(dependency)
|
2011-04-16 01:55:22 +02:00
|
|
|
|
|
|
|
|
def addArtifact(a: Artifact, taskDef: ScopedTask[File]): SettingsDefinition =
|
|
|
|
|
{
|
|
|
|
|
val pkgd = packagedArtifacts <<= (packagedArtifacts, taskDef) map ( (pas,file) => pas updated (a, file) )
|
|
|
|
|
seq( artifacts += a, pkgd )
|
|
|
|
|
}
|
|
|
|
|
def addArtifact(artifact: ScopedSetting[Artifact], taskDef: ScopedTask[File]): SettingsDefinition =
|
|
|
|
|
{
|
|
|
|
|
val art = artifacts <<= (artifact, artifacts)( _ +: _ )
|
|
|
|
|
val pkgd = packagedArtifacts <<= (packagedArtifacts, artifact, taskDef) map ( (pas,a,file) => pas updated (a, file))
|
|
|
|
|
seq( art, pkgd )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
implicit def globFilter(expression: String): NameFilter = GlobFilter(expression)
|
|
|
|
|
implicit def richAttributed(s: Seq[Attributed[File]]): RichAttributed = new RichAttributed(s)
|
|
|
|
|
final class RichAttributed private[sbt](s: Seq[Attributed[File]])
|
|
|
|
|
{
|
|
|
|
|
def files: Seq[File] = Build data s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def seq(settings: Setting[_]*): SettingsDefinition = new Project.SettingList(settings)
|
|
|
|
|
implicit def settingsDefinitionToSeq(sd: SettingsDefinition): Seq[Setting[_]] = sd.settings
|
2011-04-16 19:16:54 +02:00
|
|
|
|
|
|
|
|
def externalIvySettings(file: Initialize[File] = baseDirectory / "ivysettings.xml"): Setting[Task[IvyConfiguration]] =
|
|
|
|
|
{
|
|
|
|
|
val other = (baseDirectory, appConfiguration, streams).identityMap
|
|
|
|
|
ivyConfiguration <<= (file zipWith other) { case (f, otherTask) =>
|
|
|
|
|
otherTask map { case (base, app, s) => new ExternalIvyConfiguration(base, f, Some(lock(app)), s.log) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
def externalIvyFile(file: Initialize[File] = baseDirectory / "ivy.xml", iScala: Initialize[Option[IvyScala]] = ivyScala.identity): Setting[Task[ModuleSettings]] =
|
|
|
|
|
external(file, iScala)( (f, is, v) => new IvyFileConfiguration(f, is, v) )
|
|
|
|
|
def externalPom(file: Initialize[File] = baseDirectory / "pom.xml", iScala: Initialize[Option[IvyScala]] = ivyScala.identity): Setting[Task[ModuleSettings]] =
|
|
|
|
|
external(file, iScala)( (f, is, v) => new PomConfiguration(f, is, v) )
|
|
|
|
|
|
|
|
|
|
private[this] def external(file: Initialize[File], iScala: Initialize[Option[IvyScala]])(make: (File, Option[IvyScala], Boolean) => ModuleSettings): Setting[Task[ModuleSettings]] =
|
|
|
|
|
moduleSettings <<= ((file zip iScala) zipWith ivyValidate.identity) { case ((f, is), v) => task { make(f, is, v) } }
|
2011-04-12 04:12:03 +02:00
|
|
|
}
|