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-05-24 03:06:33 +02:00
import Scope. { fillTaskAxis , GlobalScope , ThisScope }
2011-10-06 00:09:27 +02:00
import xsbt.api.Discovery
2011-04-14 13:32:42 +02:00
import Project. { inConfig , Initialize , inScope , inTask , ScopedKey , Setting , SettingsDefinition }
2011-10-06 00:14:32 +02:00
import Load.LoadedBuild
2011-06-15 01:32:36 +02:00
import Artifact. { DocClassifier , SourceClassifier }
2011-07-03 21:44:53 +02:00
import Configurations. { Compile , CompilerPlugin , IntegrationTest , names , Provided , Runtime , Test }
2012-01-23 04:06:53 +01:00
import CrossVersion. { binarySbtVersion , binaryScalaVersion , isStable , selectVersion }
2011-02-12 02:22:17 +01:00
import complete._
2011-02-03 13:17:47 +01:00
import std.TaskExtra._
2011-06-23 01:17:10 +02:00
import inc. { FileValueCache , Locate }
2011-05-08 04:02:06 +02:00
import org.scalatools.testing. { AnnotatedFingerprint , SubclassFingerprint }
2011-03-14 02:34:17 +01:00
2011-10-16 23:27:36 +02:00
import sys.error
2011-11-10 10:21:31 +01:00
import scala.xml.NodeSeq
2011-02-03 13:17:47 +01:00
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-06-20 03:01:29 +02:00
import java.util.concurrent.Callable
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 Keys._
2011-03-14 02:34:17 +01:00
2011-05-13 04:33:45 +02:00
object Defaults extends BuildCommon
2011-03-14 02:34:17 +01:00
{
2012-01-15 18:29:53 +01:00
final val CacheDirectoryName = "cache"
2011-10-16 23:27:36 +02:00
def configSrcSub ( key : SettingKey [ File ] ) : Initialize [ File ] = ( key in ThisScope . copy ( config = Global ) , 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-12-12 14:40:47 +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-08-27 17:54:16 +02:00
( for ( a <- cp ; an <- a . metadata get Keys . analysis ) yield ( a . data , an ) ) . toMap
2011-02-03 13:17:47 +01:00
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 (
2012-01-23 04:06:53 +01:00
crossVersion : = = CrossVersion . Disabled ,
2011-10-27 01:35:29 +02:00
buildDependencies <<= buildDependencies or Classpaths . constructBuildDependencies ,
2011-08-06 03:56:32 +02:00
taskTemporaryDirectory : = IO . createTemporaryDirectory ,
onComplete <<= taskTemporaryDirectory { dir => ( ) => IO . delete ( dir ) ; IO . createDirectory ( dir ) } ,
2011-11-20 05:56:30 +01:00
concurrentRestrictions <<= concurrentRestrictions or defaultRestrictions ,
2011-05-21 19:51:13 +02:00
parallelExecution : = = true ,
2011-12-13 01:24:58 +01:00
sbtVersion <<= appConfiguration { _ . provider . id . version } ,
2012-01-23 04:06:53 +01:00
sbtBinaryVersion <<= sbtVersion apply binarySbtVersion ,
2011-12-13 01:24:58 +01:00
sbtResolver <<= sbtVersion { sbtV => if ( sbtV endsWith "-SNAPSHOT" ) Classpaths . typesafeSnapshots else Classpaths . typesafeResolver } ,
2011-03-10 00:04:53 +01:00
pollInterval : = = 500 ,
2011-05-08 04:02:06 +02:00
logBuffered : = = false ,
2011-10-19 04:43:25 +02:00
connectInput : = = false ,
cancelable : = = false ,
2011-11-20 05:56:30 +01:00
cancelable : = = false ,
2011-05-26 04:44:22 +02:00
autoScalaLibrary : = = true ,
2011-09-17 04:04:51 +02:00
onLoad <<= onLoad ?? idFun [ State ] ,
2011-11-20 05:56:30 +01:00
tags in test : = Seq ( Tags . Test -> 1 ) ,
tags in testOnly <<= tags in test ,
2011-10-30 23:39:18 +01:00
onUnload <<= ( onUnload ?? idFun [ State ] ) ,
onUnload <<= ( onUnload , taskTemporaryDirectory ) { ( f , dir ) => s => { try f ( s ) finally IO . delete ( dir ) } } ,
2011-09-17 04:04:51 +02:00
watchingMessage <<= watchingMessage ?? Watched . defaultWatchingMessage ,
triggeredMessage <<= triggeredMessage ?? Watched . defaultTriggeredMessage ,
2011-07-14 00:08:29 +02:00
definesClass : = = FileValueCache ( Locate . definesClass _ ) . get ,
2011-05-16 03:01:03 +02:00
trapExit : = = false ,
trapExit in run : = = true ,
2011-08-27 05:27:03 +02:00
traceLevel in run : = = 0 ,
traceLevel in runMain : = = 0 ,
2011-05-08 04:02:06 +02:00
logBuffered in testOnly : = = true ,
logBuffered in test : = = true ,
2011-05-15 00:21:41 +02:00
traceLevel in console : = = Int . MaxValue ,
traceLevel in consoleProject : = = Int . MaxValue ,
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 ,
2011-06-23 01:17:10 +02:00
extraLoggers : = = { _ => Nil } ,
2011-07-26 16:57:20 +02:00
skip : = = false ,
2011-08-27 05:27:03 +02:00
watchSources : = = Nil ,
2011-10-20 06:51:29 +02:00
version : = = "0.1-SNAPSHOT" ,
2011-03-02 12:46:28 +01:00
outputStrategy : = = None ,
2011-06-13 03:32:51 +02:00
exportJars : = = false ,
2011-03-02 12:46:28 +01:00
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-07-14 00:08:29 +02:00
classpathTypes : = = Set ( "jar" , "bundle" ) ,
2012-01-09 14:00:29 +01:00
aggregate : = = true ,
2011-03-02 12:46:28 +01:00
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-11-04 17:19:45 +01:00
checksums <<= appConfiguration ( Classpaths . bootChecksums ) ,
2011-06-13 03:32:51 +02:00
pomExtra : = = NodeSeq . Empty ,
pomPostProcess : = = idFun ,
pomAllRepositories : = = false ,
2011-09-03 20:59:34 +02:00
includeFilter : = = NothingFilter ,
includeFilter in unmanagedSources : = = "*.java" | "*.scala" ,
includeFilter in unmanagedJars : = = "*.jar" | "*.so" | "*.dll" ,
includeFilter in unmanagedResources : = = AllPassFilter ,
excludeFilter : = = ( ".*" - "." ) || HiddenFileFilter ,
2011-06-13 03:32:51 +02:00
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 ) ,
2011-06-23 01:17:10 +02:00
logManager <<= extraLoggers ( LogManager . defaults ) ,
2011-09-03 23:30:37 +02:00
onLoadMessage <<= onLoadMessage or ( name , thisProjectRef ) ( "Set current project to " + _ + " (in build " + _ . build + ")" ) ,
2011-07-26 16:57:20 +02:00
runnerTask
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" ,
historyPath <<= target ( t => Some ( t / ".history" ) ) ,
sourceDirectory <<= baseDirectory / "src" ,
2011-04-27 03:07:53 +02:00
sourceManaged <<= crossTarget / "src_managed" ,
2011-05-17 04:56:07 +02:00
resourceManaged <<= crossTarget / "resource_managed" ,
2012-01-15 18:29:53 +01:00
cacheDirectory <<= ( crossTarget , thisProject ) ( _ / CacheDirectoryName / _ . id / "global" )
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-11-09 13:19:54 +01:00
sourceDirectory <<= configSrcSub ( sourceDirectory ) ,
2011-03-02 12:46:28 +01:00
sourceManaged <<= configSrcSub ( sourceManaged ) ,
scalaSource <<= sourceDirectory / "scala" ,
javaSource <<= sourceDirectory / "java" ,
2011-04-27 03:07:53 +02:00
unmanagedSourceDirectories <<= Seq ( scalaSource , javaSource ) . join ,
2011-09-03 20:59:34 +02:00
// remove when sourceFilter, defaultExcludes are removed
includeFilter in unmanagedSources <<= ( sourceFilter in unmanagedSources ) or ( includeFilter in unmanagedSources ) ,
excludeFilter in unmanagedSources <<= ( defaultExcludes in unmanagedSources ) or ( excludeFilter in unmanagedSources ) ,
2011-09-02 22:39:25 +02:00
unmanagedSources <<= collectFiles ( unmanagedSourceDirectories , includeFilter in unmanagedSources , excludeFilter in unmanagedSources ) ,
2011-08-27 05:27:03 +02:00
watchSources in ConfigGlobal <++= unmanagedSources ,
2011-05-13 04:33:45 +02:00
managedSourceDirectories <<= Seq ( sourceManaged ) . join ,
managedSources <<= generate ( sourceGenerators ) ,
2011-05-17 04:56:07 +02:00
sourceGenerators : = = Nil ,
2011-05-13 04:33:45 +02:00
sourceDirectories <<= Classpaths . concatSettings ( unmanagedSourceDirectories , managedSourceDirectories ) ,
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-05-17 04:56:07 +02:00
resourceManaged <<= configSrcSub ( resourceManaged ) ,
2011-04-27 03:07:53 +02:00
unmanagedResourceDirectories <<= Seq ( resourceDirectory ) . join ,
managedResourceDirectories <<= Seq ( resourceManaged ) . join ,
resourceDirectories <<= Classpaths . concatSettings ( unmanagedResourceDirectories , managedResourceDirectories ) ,
2011-09-03 20:59:34 +02:00
// remove when defaultExcludes are removed
excludeFilter in unmanagedResources <<= ( defaultExcludes in unmanagedResources ) or ( excludeFilter in unmanagedResources ) ,
2011-09-02 22:39:25 +02:00
unmanagedResources <<= collectFiles ( unmanagedResourceDirectories , includeFilter in unmanagedResources , excludeFilter in unmanagedResources ) ,
2011-08-27 05:27:03 +02:00
watchSources in ConfigGlobal <++= unmanagedResources ,
2011-05-17 04:56:07 +02:00
resourceGenerators : = = Nil ,
2011-05-13 04:33:45 +02:00
resourceGenerators <+= ( definedSbtPlugins , resourceManaged ) map writePluginsDescriptor ,
managedResources <<= generate ( resourceGenerators ) ,
2011-04-27 03:07:53 +02:00
resources <<= Classpaths . concat ( managedResources , unmanagedResources )
)
lazy val outputConfigPaths = Seq (
2012-01-15 18:29:53 +01:00
cacheDirectory <<= ( crossTarget , thisProject , configuration ) { _ / CacheDirectoryName / _ . id / _ . name } ,
2011-04-27 03:07:53 +02:00
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-09-02 22:39:25 +02:00
unmanagedSources <<= ( unmanagedSources , baseDirectory , includeFilter in unmanagedSources , excludeFilter in unmanagedSources ) map {
2011-12-12 14:40:47 +01:00
( srcs , b , f , excl ) => ( srcs +++ b * ( f -- excl ) ) . get
2011-04-27 03:07:53 +02:00
}
2011-02-03 13:17:47 +01:00
)
2011-05-13 04:33:45 +02:00
2011-05-26 04:44:22 +02:00
def compileBase = inTask ( console ) ( compilersSetting : : Nil ) ++ Seq (
classpathOptions in GlobalScope : = = ClasspathOptions . boot ,
classpathOptions in GlobalScope in console : = = ClasspathOptions . repl ,
2011-04-04 03:15:35 +02:00
compileOrder in GlobalScope : = = CompileOrder . Mixed ,
2011-05-26 04:44:22 +02:00
compilersSetting ,
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 ) ,
2012-01-23 04:06:53 +01:00
scalaBinaryVersion in GlobalScope <<= scalaVersion apply binaryScalaVersion ,
crossVersion <<= ( crossPaths , scalaVersion ) { ( enabled , sv ) =>
if ( enabled )
if ( isStable ( sv ) ) CrossVersion . binary else CrossVersion . full
else
CrossVersion . Disabled
} ,
2011-05-17 04:56:07 +02:00
crossScalaVersions in GlobalScope <<= Seq ( scalaVersion ) . join ,
2012-01-15 18:29:53 +01:00
crossTarget <<= ( target , scalaBinaryVersion , sbtBinaryVersion , sbtPlugin , crossPaths ) ( makeCrossTarget )
2011-02-06 03:40:10 +01:00
)
2011-08-06 03:59:49 +02:00
def makeCrossTarget ( t : File , sv : String , sbtv : String , plugin : Boolean , cross : Boolean ) : File =
{
val scalaBase = if ( cross ) t / ( "scala-" + sv ) else t
if ( plugin ) scalaBase / ( "sbt-" + sbtv ) else scalaBase
}
2011-05-26 04:44:22 +02:00
def compilersSetting = compilers <<= ( scalaInstance , appConfiguration , streams , classpathOptions , javaHome ) map { ( si , app , s , co , jh ) => Compiler . compilers ( si , co , jh ) ( app , s . log ) }
2011-02-06 03:40:10 +01:00
2011-11-10 10:21:31 +01:00
lazy val configTasks = docSetting ( doc ) ++ compileInputsSettings ++ Seq (
2011-03-02 12:46:28 +01:00
initialCommands in GlobalScope : = = "" ,
2011-10-16 23:27:36 +02:00
cleanupCommands in GlobalScope : = = "" ,
2011-11-20 05:56:30 +01:00
compile <<= compileTask tag ( Tags . Compile , Tags . CPU ) ,
2011-06-23 01:17:10 +02:00
compileIncSetup <<= compileIncSetupTask ,
2011-03-02 12:46:28 +01:00
console <<= consoleTask ,
consoleQuick <<= consoleQuickTask ,
2011-09-22 04:54:46 +02:00
discoveredMainClasses <<= compile map discoverMainClasses storeAs discoveredMainClasses triggeredBy compile ,
2011-03-14 02:34:17 +01:00
definedSbtPlugins <<= discoverPlugins ,
2011-07-26 16:57:20 +02:00
inTask ( run ) ( runnerTask : : Nil ) . head ,
2012-01-25 23:29:51 +01:00
selectMainClass <<= ( discoveredMainClasses , mainClass ) map { ( classes , explicit ) => explicit orElse selectRunMain ( classes ) } ,
2011-10-16 23:27:36 +02:00
mainClass in run <<= selectMainClass in run ,
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-03-02 12:46:28 +01:00
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 ,
watchTransitiveSources <<= watchTransitiveSourcesTask ,
watch <<= watchSetting
2011-02-06 17:33:29 +01:00
)
2011-10-16 23:27:36 +02:00
def generate ( generators : SettingKey [ Seq [ Task [ Seq [ File ] ] ] ] ) : Initialize [ Task [ Seq [ File ] ] ] = generators { _ . join . map ( _ . flatten ) }
2011-05-13 04:33:45 +02:00
2011-10-16 23:27:36 +02:00
def inAllConfigurations [ T ] ( key : TaskKey [ 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-09-27 00:23:16 +02:00
inDependencies [ Task [ Seq [ File ] ] ] ( watchSources . task , const ( std . TaskExtra . constant ( Nil ) ) , aggregate = true , includeRoot = true ) apply { _ . join . map ( _ . flatten ) }
2011-03-01 14:54:06 +01:00
2011-10-30 23:38:37 +01:00
def transitiveUpdateTask : Initialize [ Task [ Seq [ UpdateReport ] ] ] =
forDependencies ( ref => ( update . task in ref ) . ? , aggregate = false , includeRoot = false ) apply ( _ . flatten . join )
2011-09-17 04:04:51 +02:00
def watchSetting : Initialize [ Watched ] = ( pollInterval , thisProjectRef , watchingMessage , triggeredMessage ) { ( interval , base , msg , trigMsg ) =>
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-09-17 04:04:51 +02:00
override def watchingMessage ( s : WatchState ) = msg ( s )
override def triggeredMessage ( s : WatchState ) = trigMsg ( s )
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
2011-08-04 13:20:25 +02:00
case None => error ( "key not found: " + Project . displayFull ( key ) )
2011-04-27 03:07:53 +02:00
}
2011-03-01 14:54:06 +01:00
}
}
2011-07-26 16:57:20 +02:00
def scalaInstanceSetting = ( appConfiguration , scalaVersion , scalaHome ) map { ( app , version , home ) =>
2011-03-10 00:04:53 +01:00
val launcher = app . provider . scalaProvider . launcher
home match {
case None => ScalaInstance ( version , launcher )
case Some ( h ) => ScalaInstance ( h , launcher )
}
}
2011-03-01 14:54:06 +01:00
2011-12-12 14:40:47 +01:00
lazy val testTasks : Seq [ Setting [ _ ] ] = testTaskOptions ( test ) ++ testTaskOptions ( testOnly ) ++ Seq (
2011-08-06 03:56:32 +02:00
testLoader <<= ( fullClasspath , scalaInstance , taskTemporaryDirectory ) map { ( cp , si , temp ) => TestFramework . createTestLoader ( data ( cp ) , si , IO . createUniqueDirectory ( temp ) ) } ,
2011-03-02 12:46:28 +01:00
testFrameworks in GlobalScope : = = {
2011-02-06 17:33:29 +01:00
import sbt.TestFrameworks._
2012-02-08 03:56:37 +01:00
Seq ( ScalaCheck , Specs2 , Specs , ScalaTest , JUnit )
2011-02-06 17:33:29 +01:00
} ,
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-09-22 04:54:46 +02:00
definedTests <<= detectTests ,
definedTestNames <<= definedTests map ( _ . map ( _ . name ) . distinct ) storeAs definedTestNames triggeredBy compile ,
2011-05-25 06:02:43 +02:00
testListeners in GlobalScope : = = Nil ,
testOptions in GlobalScope : = = Nil ,
2011-11-20 05:56:30 +01:00
testExecution in test <<= testExecutionTask ( test ) ,
testExecution in testOnly <<= testExecutionTask ( testOnly ) ,
executeTests <<= ( streams in test , loadedTestFrameworks , testExecution in test , testLoader , definedTests , resolvedScoped , state ) flatMap {
( s , frameworkMap , config , loader , discovered , scoped , st ) =>
2011-08-04 13:20:25 +02:00
implicit val display = Project . showContextKey ( st )
2011-11-20 05:56:30 +01:00
Tests ( frameworkMap , loader , discovered , config , noTestsMessage ( ScopedKey ( scoped . scope , test . key ) ) , 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-08-04 13:20:25 +02:00
private [ this ] def noTestsMessage ( scoped : ScopedKey [ _ ] ) ( implicit display : Show [ ScopedKey [ _ ] ] ) : String =
"No tests to run for " + display ( scoped )
2011-02-06 03:40:10 +01:00
2011-06-25 15:37:55 +02:00
lazy val TaskGlobal : Scope = ThisScope . copy ( task = Global )
2011-08-27 05:27:03 +02:00
lazy val ConfigGlobal : Scope = ThisScope . copy ( config = Global )
2011-04-07 02:55:30 +02:00
def testTaskOptions ( key : Scoped ) : Seq [ Setting [ _ ] ] = inTask ( key ) ( Seq (
2011-06-25 15:37:55 +02:00
testListeners <<= ( streams , resolvedScoped , streamsManager , logBuffered , testListeners in TaskGlobal ) map { ( s , sco , sm , buff , ls ) =>
2011-05-08 04:02:06 +02:00
TestLogger ( s . log , testLogger ( sm , test in sco . scope ) , buff ) +: ls
} ,
2011-06-25 15:37:55 +02:00
testOptions <<= ( testOptions in TaskGlobal , testListeners ) map { ( options , ls ) => Tests . Listeners ( ls ) +: options }
2011-04-07 02:55:30 +02:00
) )
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-11-20 05:56:30 +01:00
def testExecutionTask ( task : Scoped ) : Initialize [ Task [ Tests . Execution ] ] =
( testOptions in task , parallelExecution in task , tags in task ) map { ( opts , par , ts ) => new Tests . Execution ( opts , par , ts ) }
2011-12-12 14:40:47 +01:00
def testOnlyTask =
2011-11-20 05:56:30 +01:00
InputTask ( loadForParser ( definedTestNames ) ( ( s , i ) => testOnlyParser ( s , i getOrElse Nil ) ) ) { result =>
( streams , loadedTestFrameworks , testExecution in testOnly , testLoader , definedTests , resolvedScoped , result , state ) flatMap {
case ( s , frameworks , config , loader , discovered , scoped , ( tests , frameworkOptions ) , st ) =>
2011-05-30 23:49:39 +02:00
val filter = selectedFilter ( tests )
2011-11-20 05:56:30 +01:00
val modifiedOpts = Tests . Filter ( filter ) +: Tests . Argument ( frameworkOptions : _ * ) +: config . options
val newConfig = new Tests . Execution ( modifiedOpts , config . parallel , config . tags )
2011-08-04 13:20:25 +02:00
implicit val display = Project . showContextKey ( st )
2011-11-20 05:56:30 +01:00
Tests ( frameworks , loader , discovered , newConfig , noTestsMessage ( scoped ) , s . log ) map { results =>
2011-03-05 14:25:17 +01:00
Tests . showResults ( s . log , results )
2011-02-12 02:22:17 +01:00
}
}
2011-04-23 02:13:24 +02:00
}
2011-05-30 23:49:39 +02:00
def selectedFilter ( args : Seq [ String ] ) : String => Boolean =
{
val filters = args map GlobFilter . apply
2011-06-01 00:37:07 +02:00
s => filters . isEmpty || filters . exists { _ accept s }
2011-05-30 23:49:39 +02: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-11-20 05:56:30 +01:00
def defaultRestrictions : Initialize [ Seq [ Tags . Rule ] ] = parallelExecution { par =>
val max = EvaluateTask . SystemProcessors
Tags . limitAll ( if ( par ) max else 1 ) : : Nil
}
2011-03-14 02:34:17 +01:00
2011-06-19 03:02:13 +02:00
lazy val packageBase : Seq [ Setting [ _ ] ] = Seq (
2011-07-31 22:50:18 +02:00
artifact <<= moduleName ( 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
)
2012-02-27 19:53:21 +01:00
lazy val packageConfig : Seq [ Setting [ _ ] ] =
inTask ( packageBin ) ( Seq (
packageOptions <<= ( name , version , homepage , organization , organizationName , mainClass , packageOptions ) map { ( name , ver , h , org , orgName , main , p ) => Package . addSpecManifestAttributes ( name , ver , orgName ) +: Package . addImplManifestAttributes ( name , ver , h , org , orgName ) +: main . map ( Package . MainClass . apply ) ++: p } ) ) ++
inTask ( packageSrc ) ( Seq (
packageOptions <<= ( name , version , organizationName , packageOptions ) map { Package . addSpecManifestAttributes ( _ , _ , _ ) +: _ } ) ) ++
2012-03-06 06:00:29 +01:00
packageTaskSettings ( packageBin , packageBinMappings ) ++
packageTaskSettings ( packageSrc , packageSrcMappings ) ++
packageTaskSettings ( packageDoc , packageDocMappings ) ++
2012-02-27 19:53:21 +01:00
Seq ( `package` <<= packageBin )
2011-04-14 13:32:42 +02:00
2012-02-05 16:58:16 +01:00
def packageBinMappings = products map { _ flatMap Path . allSubpaths }
def packageDocMappings = doc map { Path . allSubpaths ( _ ) . toSeq }
def packageSrcMappings = concatMappings ( resourceMappings , sourceMappings )
@deprecated ( "Use `packageBinMappings` instead" , "0.12.0" )
def packageBinTask = packageBinMappings
@deprecated ( "Use `packageDocMappings` instead" , "0.12.0" )
def packageDocTask = packageDocMappings
@deprecated ( "Use `packageSrcMappings` instead" , "0.12.0" )
def packageSrcTask = packageSrcMappings
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-06-01 00:37:07 +02:00
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 ) =>
2012-01-27 03:28:19 +01:00
( ( srcs --- sdirs --- base ) pair ( relativeTo ( sdirs ) | relativeTo ( base ) | flat ) ) toSeq
2011-02-24 01:19:44 +01:00
}
2011-06-01 00:37:07 +02:00
def resourceMappings = relativeMappings ( unmanagedResources , unmanagedResourceDirectories )
def relativeMappings ( files : ScopedTaskable [ Seq [ File ] ] , dirs : ScopedTaskable [ Seq [ File ] ] ) : Initialize [ Task [ Seq [ ( File , String ) ] ] ] =
( files , dirs ) map { ( rs , rdirs ) =>
2012-01-27 03:28:19 +01:00
( rs --- rdirs ) pair ( relativeTo ( rdirs ) | flat ) toSeq
2011-06-01 00:37:07 +02:00
}
2011-12-12 14:40:47 +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 ] ] ] =
2011-12-12 14:40:47 +01:00
( dirs , filter , excludes ) map { ( d , f , excl ) => d . descendantsExcept ( f , excl ) . get }
2011-04-27 03:07:53 +02:00
2012-01-23 04:06:53 +01:00
def artifactPathSetting ( art : SettingKey [ Artifact ] ) = ( crossTarget , projectID , art , scalaVersion in artifactName , scalaBinaryVersion in artifactName , artifactName ) {
( t , module , a , sv , sbv , toString ) =>
t / toString ( ScalaVersion ( sv , sbv ) , module , a ) asFile
}
2011-08-01 20:23:42 +02:00
def artifactSetting = ( ( artifact , artifactClassifier ) . identity zipWith configuration . ? ) { case ( ( a , classifier ) , cOpt ) =>
val cPart = cOpt flatMap { c => if ( c == Compile ) None else Some ( c . name ) }
val combined = cPart . toList ++ classifier . toList
if ( combined . isEmpty ) a . copy ( classifier = None , configurations = cOpt . toList ) else {
2011-07-30 05:33:10 +02:00
val classifierString = combined mkString "-"
2011-12-12 14:40:47 +01:00
val confs = cOpt . toList flatMap { c => artifactConfigurations ( a , c , classifier ) }
2011-07-30 05:33:10 +02:00
a . copy ( classifier = Some ( classifierString ) , `type` = Artifact . classifierType ( classifierString ) , configurations = confs )
}
}
def artifactConfigurations ( base : Artifact , scope : Configuration , classifier : Option [ String ] ) : Iterable [ Configuration ] =
if ( base . configurations . isEmpty )
classifier match {
case Some ( c ) => Artifact . classifierConf ( c ) : : Nil
case None => scope : : Nil
}
else
base . configurations
2012-03-06 06:00:29 +01:00
@deprecated ( "Use `Pair.apply` instead" , "0.12.0" )
2011-04-14 13:32:42 +02:00
def pairID [ A ,B ] = ( a : A , b : B ) => ( a , b )
2012-01-15 18:29:53 +01:00
def perTaskCache ( key : TaskKey [ _ ] ) : Setting [ File ] =
cacheDirectory ~= { _ / ( "for_" + key . key . label ) }
2012-03-06 06:00:29 +01:00
@deprecated ( "Use `packageTaskSettings` instead." , "0.12.0" )
def packageTasks ( key : TaskKey [ File ] , mappingsTask : Initialize [ Task [ Seq [ ( File ,String ) ] ] ] ) = packageTaskSettings ( key , mappingsTask )
def packageTaskSettings ( key : TaskKey [ File ] , mappingsTask : Initialize [ Task [ Seq [ ( File ,String ) ] ] ] ) =
2011-02-10 14:16:07 +01:00
inTask ( key ) ( Seq (
2011-06-25 15:37:55 +02:00
key in TaskGlobal <<= packageTask ,
2011-04-14 13:32:42 +02:00
packageConfiguration <<= packageConfigurationTask ,
2011-03-02 12:46:28 +01:00
mappings <<= mappingsTask ,
2012-03-06 05:37:18 +01:00
packagedArtifact <<= ( artifact , key ) map Pair . apply ,
2011-07-30 05:33:10 +02:00
artifact <<= artifactSetting ,
2012-01-15 18:29:53 +01:00
perTaskCache ( key ) ,
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-10-16 23:27:36 +02:00
def runMainTask ( classpath : TaskKey [ Classpath ] , scalaRun : TaskKey [ ScalaRun ] ) : Initialize [ InputTask [ Unit ] ] =
2011-03-28 00:09:40 +02:00
{
2012-03-06 05:37:18 +01:00
import DefaultParsers._
2011-09-22 04:54:46 +02:00
InputTask ( loadForParser ( discoveredMainClasses ) ( ( s , names ) => runMainParser ( s , names getOrElse Nil ) ) ) { result =>
2011-03-28 00:09:40 +02:00
( classpath , scalaRun , streams , result ) map { case ( cp , runner , s , ( mainClass , args ) ) =>
2011-05-13 04:33:45 +02:00
toError ( runner . run ( mainClass , data ( cp ) , args , s . log ) )
2011-03-28 00:09:40 +02:00
}
}
}
2011-05-13 04:33:45 +02:00
2011-10-16 23:27:36 +02:00
def runTask ( classpath : TaskKey [ Classpath ] , mainClassTask : TaskKey [ Option [ String ] ] , scalaRun : TaskKey [ ScalaRun ] ) : Initialize [ InputTask [ Unit ] ] =
2011-05-13 04:33:45 +02:00
inputTask { 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." )
2011-05-13 04:33:45 +02:00
toError ( runner . run ( mainClass , data ( cp ) , args , s . log ) )
2011-02-06 03:40:10 +01:00
}
}
2011-07-26 16:57:20 +02:00
def runnerTask = runner <<= runnerInit
2011-12-12 14:40:47 +01:00
def runnerInit : Initialize [ Task [ ScalaRun ] ] =
2011-10-19 04:43:25 +02:00
( taskTemporaryDirectory , scalaInstance , baseDirectory , javaOptions , outputStrategy , fork , javaHome , trapExit , connectInput ) map {
( tmp , si , base , options , strategy , forkRun , javaHomeDir , trap , connectIn ) =>
2011-03-02 12:46:28 +01:00
if ( forkRun ) {
2011-10-19 04:43:25 +02:00
new ForkRun ( ForkOptions ( scalaJars = si . jars , javaHome = javaHomeDir , connectInput = connectIn , outputStrategy = strategy ,
2011-02-26 00:35:52 +01:00
runJVMOptions = options , workingDirectory = Some ( base ) ) )
} else
2011-08-06 03:56:32 +02:00
new Run ( si , trap , tmp )
2011-02-26 00:35:52 +01:00
}
2011-11-10 10:21:31 +01:00
def docSetting ( key : TaskKey [ File ] ) : Seq [ Setting [ _ ] ] = inTask ( key ) ( compileInputsSettings ++ Seq (
2012-01-15 18:29:53 +01:00
perTaskCache ( key ) ,
2011-09-13 00:09:48 +02:00
target <<= docDirectory , // deprecate docDirectory in favor of 'target in doc'; remove when docDirectory is removed
2011-11-09 13:19:54 +01:00
scalacOptions <<= scaladocOptions or scalacOptions , // deprecate scaladocOptions in favor of 'scalacOptions in doc'; remove when scaladocOptions is removed
key in TaskGlobal <<= ( cacheDirectory , compileInputs , target , configuration , streams ) map { ( cache , in , out , config , s ) =>
2011-12-12 14:40:47 +01:00
// For Scala/Java hybrid projects, the output docs are rebased to `scala` or `java` sub-directory accordingly. We do hybrid
2011-11-09 13:19:54 +01:00
// mode iff both *.scala and *.java files exist -- other doc resources (package.html, *.jpg etc.) don't influence the decision.
val srcs = in . config . sources
val hybrid = srcs . exists ( _ . name . endsWith ( ".scala" ) ) && srcs . exists ( _ . name . endsWith ( ".java" ) )
val ( scalaOut , javaOut ) = if ( hybrid ) ( out / "scala" , out / "java" ) else ( out , out )
val cp = in . config . classpath . toList - in . config . classesDirectory
Doc ( in . config . maxErrors , in . compilers . scalac ) . cached ( cache / "scala" , nameForSrc ( config . name ) , srcs , cp , scalaOut , in . config . options , s . log )
Doc ( in . config . maxErrors , in . compilers . javac ) . cached ( cache / "java" , nameForSrc ( config . name ) , srcs , cp , javaOut , in . config . javacOptions , s . log )
2011-08-23 04:45:05 +02:00
out
}
) )
2011-11-09 13:19:54 +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 )
2011-12-16 14:21:54 +01:00
def consoleTask ( classpath : TaskKey [ Classpath ] , task : TaskKey [ _ ] ) : Initialize [ Task [ Unit ] ] =
( compilers in task , classpath in task , scalacOptions in task , initialCommands in task , cleanupCommands in task , taskTemporaryDirectory in task , scalaInstance in task , streams ) map {
( cs , cp , options , initCommands , cleanup , temp , si , s ) =>
val loader = sbt . classpath . ClasspathUtilities . makeLoader ( data ( cp ) , si . loader , si , IO . createUniqueDirectory ( temp ) )
( new Console ( cs . scalac ) ) ( data ( cp ) , options , loader , initCommands , cleanup ) ( ) ( s . log ) . foreach ( msg => error ( msg ) )
println ( )
}
2011-12-12 14:40:47 +01:00
2011-03-05 14:25:17 +01:00
def compileTask = ( compileInputs , streams ) map { ( i , s ) => Compiler ( i , s . log ) }
2011-12-12 14:40:47 +01:00
def compileIncSetupTask =
2011-07-26 16:57:20 +02:00
( dependencyClasspath , cacheDirectory , skip in compile , definesClass ) map { ( cp , cacheDir , skip , definesC ) =>
2012-01-15 18:29:53 +01:00
Compiler . IncSetup ( analysisMap ( cp ) , definesC , skip , cacheDir / "inc_compile" )
2011-06-23 01:17:10 +02:00
}
2011-11-10 10:21:31 +01:00
def compileInputsSettings : Seq [ Setting [ _ ] ] = {
val optionsPair = TaskKey . local [ ( Seq [ String ] , Seq [ String ] ) ]
Seq ( optionsPair <<= ( scalacOptions , javacOptions ) map Pair . apply ,
compileInputs <<= ( dependencyClasspath , sources , compilers , optionsPair , classDirectory , compileOrder , compileIncSetup , maxErrors , streams ) map {
( cp , srcs , cs , optsPair , classes , order , incSetup , maxErr , s ) =>
Compiler . inputs ( classes +: data ( cp ) , srcs , classes , optsPair . _1 , optsPair . _2 , maxErr , order ) ( cs , incSetup , s . log )
} )
}
2012-01-23 04:06:53 +01:00
def sbtPluginExtra ( m : ModuleID , sbtV : String , scalaV : String ) : ModuleID =
m . extra ( CustomPomParser . SbtVersionKey -> sbtV , CustomPomParser . ScalaVersionKey -> scalaV ) . copy ( crossVersion = CrossVersion . Disabled )
2011-08-14 16:53:37 +02:00
def writePluginsDescriptor ( plugins : Set [ String ] , dir : File ) : Seq [ File ] =
2011-03-14 02:34:17 +01:00
{
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"
2012-01-27 03:28:19 +01:00
val mappings = ( resrcs --- dirs ) pair ( 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._
2011-05-30 23:49:39 +02:00
val selectTests = distinctParser ( tests . toSet , true )
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-05-30 23:49:39 +02:00
def distinctParser ( exs : Set [ String ] , raw : Boolean ) : Parser [ Seq [ String ] ] =
2011-05-25 05:54:49 +02:00
{
import DefaultParsers._
val base = token ( Space ) ~> token ( NotSpace - "--" examples exs )
val recurse = base flatMap { ex =>
val ( matching , notMatching ) = exs . partition ( GlobFilter ( ex ) . accept _ )
2011-05-30 23:49:39 +02:00
distinctParser ( notMatching , raw ) map { result => if ( raw ) ex +: result else matching . toSeq ++ result }
2011-05-25 05:54:49 +02:00
}
recurse ?? Nil
}
2011-10-16 23:27:36 +02:00
def inDependencies [ T ] ( key : SettingKey [ T ] , default : ProjectRef => T , includeRoot : Boolean = true , classpath : Boolean = true , aggregate : Boolean = false ) : Initialize [ Seq [ T ] ] =
2011-10-30 23:38:37 +01:00
forDependencies [ T ,T ] ( ref => ( key in ref ) ?? default ( ref ) , includeRoot , classpath , aggregate )
def forDependencies [ T ,V ] ( init : ProjectRef => Initialize [ V ] , includeRoot : Boolean = true , classpath : Boolean = true , aggregate : Boolean = false ) : Initialize [ Seq [ V ] ] =
2011-08-14 16:53:37 +02:00
Project . bind ( ( loadedBuild , thisProjectRef ) . identity ) { case ( lb , base ) =>
2011-10-30 23:38:37 +01:00
transitiveDependencies ( base , lb , includeRoot , classpath , aggregate ) map init join ;
2011-08-14 16:53:37 +02:00
}
2011-03-01 14:54:06 +01:00
2011-10-06 00:14:32 +02:00
def transitiveDependencies ( base : ProjectRef , structure : LoadedBuild , includeRoot : Boolean , classpath : Boolean = true , aggregate : Boolean = false ) : Seq [ ProjectRef ] =
2011-08-14 16:53:37 +02:00
{
2011-12-12 14:40:47 +01:00
def tdeps ( enabled : Boolean , f : ProjectRef => Seq [ ProjectRef ] ) : Seq [ ProjectRef ] =
2011-11-27 23:48:01 +01:00
{
val full = if ( enabled ) Dag . topologicalSort ( base ) ( f ) else Nil
if ( includeRoot ) full else full dropRight 1
}
def fullCp = tdeps ( classpath , getDependencies ( structure , classpath = true , aggregate = false ) )
def fullAgg = tdeps ( aggregate , getDependencies ( structure , classpath = false , aggregate = true ) )
( classpath , aggregate ) match {
case ( true , true ) => ( fullCp ++ fullAgg ) . distinct
case ( true , false ) => fullCp
case _ => fullAgg
}
2011-03-01 14:54:06 +01:00
}
2011-10-06 00:14:32 +02:00
def getDependencies ( structure : LoadedBuild , classpath : Boolean = true , aggregate : Boolean = false ) : ProjectRef => Seq [ ProjectRef ] =
2011-08-14 16:53:37 +02:00
ref => Project . getProject ( ref , structure ) . toList flatMap { p =>
( if ( classpath ) p . dependencies . map ( _ . project ) else Nil ) ++
( if ( aggregate ) p . aggregate else Nil )
}
2011-03-01 14:54:06 +01:00
2011-02-12 02:22:17 +01:00
val CompletionsID = "completions"
2011-12-12 14:40:47 +01:00
2011-08-14 16:53:37 +02:00
def noAggregation : Seq [ Scoped ] = 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-12-12 14:40:47 +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-06-19 03:02:13 +02:00
lazy val baseClasspaths : Seq [ Setting [ _ ] ] = Classpaths . publishSettings ++ Classpaths . baseSettings
lazy val configSettings : Seq [ Setting [ _ ] ] = Classpaths . configSettings ++ configTasks ++ configPaths ++ packageConfig ++ Classpaths . compilerPluginConfig
2011-02-26 00:35:52 +01:00
2011-06-19 03:02:13 +02:00
lazy val compileSettings : Seq [ Setting [ _ ] ] = configSettings ++ ( mainRunMainTask +: mainRunTask +: addBaseSources )
lazy val testSettings : Seq [ Setting [ _ ] ] = configSettings ++ testTasks
2011-02-03 13:17:47 +01:00
2011-06-19 03:02:13 +02:00
lazy val itSettings : Seq [ Setting [ _ ] ] = inConfig ( IntegrationTest ) ( testSettings )
lazy val defaultConfigs : Seq [ Setting [ _ ] ] = inConfig ( Compile ) ( compileSettings ) ++ inConfig ( Test ) ( testSettings ) ++ inConfig ( Runtime ) ( Classpaths . configSettings )
2011-12-12 14:40:47 +01: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 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-06-15 01:32:36 +02:00
def concatDistinct [ T ] ( a : ScopedTaskable [ Seq [ T ] ] , b : ScopedTaskable [ Seq [ T ] ] ) : Initialize [ Task [ Seq [ T ] ] ] = ( a , b ) map { ( x , y ) => ( x ++ y ) . distinct }
def concat [ T ] ( a : ScopedTaskable [ Seq [ T ] ] , b : ScopedTaskable [ Seq [ T ] ] ) : Initialize [ Task [ Seq [ T ] ] ] = ( a , b ) map ( _ ++ _ )
2011-10-16 23:27:36 +02:00
def concatSettings [ T ] ( a : SettingKey [ Seq [ T ] ] , b : SettingKey [ 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 ) ,
2011-06-15 01:32:36 +02:00
fullClasspath <<= concatDistinct ( exportedProducts , dependencyClasspath ) ,
2011-03-02 12:46:28 +01:00
internalDependencyClasspath <<= internalDependencies ,
unmanagedClasspath <<= unmanagedDependencies ,
products <<= makeProducts ,
2011-06-01 00:37:07 +02:00
productDirectories <<= compileInputs map ( _ . config . classesDirectory : : Nil ) ,
exportedProducts <<= exportProductsTask ,
2011-10-06 00:14:32 +02:00
classpathConfiguration <<= ( internalConfigurationMap , configuration , classpathConfiguration . ? , update . task ) apply findClasspathConfig ,
2011-04-20 04:24:52 +02:00
managedClasspath <<= ( classpathConfiguration , classpathTypes , update ) map managedJars ,
2011-09-03 20:59:34 +02:00
// remove when defaultExcludes and classpathFilter are removed
excludeFilter in unmanagedJars <<= ( defaultExcludes in unmanagedJars ) or ( excludeFilter in unmanagedJars ) ,
2011-09-03 23:30:37 +02:00
includeFilter in unmanagedJars <<= classpathFilter or ( includeFilter in unmanagedJars ) ,
2011-09-03 20:59:34 +02:00
unmanagedJars <<= ( configuration , unmanagedBase , includeFilter in unmanagedJars , excludeFilter in unmanagedJars ) map { ( config , base , filter , excl ) =>
2011-12-12 14:40:47 +01:00
( base * ( filter -- excl ) +++ ( base / config . name ) . descendantsExcept ( filter , excl ) ) . classpath
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 )
2011-10-16 23:27:36 +02:00
lazy val defaultPackages : Seq [ TaskKey [ File ] ] =
2011-04-14 13:32:42 +02:00
for ( task <- defaultPackageKeys ; conf <- Seq ( Compile , Test ) ) yield ( task in conf )
2011-10-16 23:27:36 +02:00
lazy val defaultArtifactTasks : Seq [ TaskKey [ File ] ] = makePom +: defaultPackages
2011-04-14 13:32:42 +02:00
2011-10-06 00:14:32 +02:00
def findClasspathConfig ( map : Configuration => Configuration , thisConfig : Configuration , delegate : Task [ Option [ Configuration ] ] , up : Task [ UpdateReport ] ) : Task [ Configuration ] =
( delegate : ^: up :^: KNil ) map { case delegated : +: report :+: HNil =>
val defined = report . allConfigurations . toSet
val search = map ( thisConfig ) +: ( delegated . toList ++ Seq ( Compile , Configurations . Default ) )
def notFound = error ( "Configuration to use for managed classpath must be explicitly defined when default configurations are not present." )
search find { defined contains _ . name } getOrElse notFound
}
2011-10-16 23:27:36 +02:00
def packaged ( pkgTasks : Seq [ TaskKey [ File ] ] ) : Initialize [ Task [ Map [ Artifact , File ] ] ] =
2011-08-14 16:53:37 +02:00
enabledOnly ( packagedArtifact . task , pkgTasks ) apply ( _ . join . map ( _ . toMap ) )
2011-10-16 23:27:36 +02:00
def artifactDefs ( pkgTasks : Seq [ TaskKey [ File ] ] ) : Initialize [ Seq [ Artifact ] ] =
2011-04-14 13:32:42 +02:00
enabledOnly ( artifact , pkgTasks )
2011-10-16 23:27:36 +02:00
def enabledOnly [ T ] ( key : SettingKey [ T ] , pkgTasks : Seq [ TaskKey [ File ] ] ) : Initialize [ Seq [ T ] ] =
2011-04-14 13:32:42 +02:00
( forallIn ( key , pkgTasks ) zipWith forallIn ( publishArtifact , pkgTasks ) ) ( _ zip _ collect { case ( a , true ) => a } )
2011-10-16 23:27:36 +02:00
def forallIn [ T ] ( key : SettingKey [ T ] , pkgTasks : Seq [ TaskKey [ _ ] ] ) : Initialize [ Seq [ T ] ] =
2011-04-14 13:32:42 +02:00
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 } ,
2012-03-06 05:37:18 +01:00
packagedArtifact in makePom <<= ( artifact in makePom , makePom ) map Pair . apply ,
2011-04-14 13:32:42 +02:00
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-07-20 03:29:05 +02:00
val baseSettings : Seq [ Setting [ _ ] ] = sbtClassifiersTasks ++ Seq (
2011-07-16 18:53:29 +02:00
conflictWarning in GlobalScope : = = ConflictWarning . default ( "global" ) ,
conflictWarning <<= ( thisProjectRef , conflictWarning ) { ( ref , cw ) => cw . copy ( label = Project . display ( ref ) ) } ,
2011-03-02 12:46:28 +01:00
unmanagedBase <<= baseDirectory / "lib" ,
normalizedName <<= name ( StringUtilities . normalize ) ,
2011-09-09 15:05:38 +02:00
isSnapshot <<= isSnapshot or version ( _ endsWith "-SNAPSHOT" ) ,
2011-10-16 23:27:36 +02:00
description <<= description or name ,
2011-07-31 19:47:35 +02:00
homepage in GlobalScope : = = None ,
2011-09-02 20:46:00 +02:00
startYear in GlobalScope : = = None ,
2011-07-31 19:47:35 +02:00
licenses in GlobalScope : = = Nil ,
2011-10-16 23:27:36 +02:00
organization <<= organization or normalizedName ,
organizationName <<= organizationName or organization ,
organizationHomepage <<= organizationHomepage or homepage ,
2012-02-28 10:48:46 +01:00
scmInfo in GlobalScope : = = None ,
projectInfo <<= ( name , description , homepage , startYear , licenses , organizationName , organizationHomepage , scmInfo ) apply ModuleInfo ,
2011-08-14 16:53:37 +02:00
externalResolvers <<= ( externalResolvers . task . ? , resolvers ) {
2011-06-19 02:17:50 +02:00
case ( Some ( delegated ) , Seq ( ) ) => delegated
case ( _ , rs ) => task { Resolver . withDefaultResolvers ( rs ) }
} ,
2011-12-13 01:24:58 +01:00
fullResolvers <<= ( projectResolver , externalResolvers , sbtPlugin , sbtResolver ) map { ( proj , rs , isPlugin , sbtr ) =>
val base = if ( isPlugin ) sbtr +: rs else rs
proj +: base
2011-03-17 01:09:59 +01:00
} ,
2011-03-02 12:46:28 +01:00
offline in GlobalScope : = = false ,
2011-10-16 23:27:36 +02:00
moduleName <<= normalizedName ,
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 ,
2012-02-15 03:59:12 +01:00
dependencyOverrides in GlobalScope : = = Set . empty ,
2011-03-02 12:46:28 +01:00
libraryDependencies in GlobalScope : = = Nil ,
2011-07-09 22:54:41 +02:00
libraryDependencies <++= ( autoScalaLibrary , sbtPlugin , scalaVersion ) apply autoLibraryDependency ,
2011-03-17 01:09:59 +01:00
allDependencies <<= ( projectDependencies , libraryDependencies , sbtPlugin , sbtDependency ) map { ( projDeps , libDeps , isPlugin , sbtDep ) =>
val base = projDeps ++ libDeps
2011-07-03 21:44:53 +02:00
if ( isPlugin ) sbtDep . copy ( configurations = Some ( Provided . name ) ) +: base else base
2011-03-17 01:09:59 +01:00
} ,
2011-11-04 17:19:45 +01:00
ivyLoggingLevel in GlobalScope : = = UpdateLogging . DownloadOnly ,
2011-03-02 12:46:28 +01:00
ivyXML in GlobalScope : = = NodeSeq . Empty ,
ivyValidate in GlobalScope : = = false ,
2012-01-23 04:06:53 +01:00
ivyScala <<= ivyScala or ( scalaHome , scalaVersion in update , scalaBinaryVersion in update ) { ( sh , fv , bv ) =>
Some ( new IvyScala ( fv , bv , Nil , filterImplicit = true , checkExplicit = true , overrideScalaVersion = sh . isEmpty ) )
2011-07-17 17:26:27 +02:00
} ,
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-10-16 23:27:36 +02:00
publishArtifact in makePom <<= publishMavenStyle ,
2011-06-15 01:32:36 +02:00
artifact in makePom <<= moduleName ( Artifact . pom ) ,
2012-01-23 04:06:53 +01:00
projectID <<= ( organization , moduleName , version , artifacts , crossVersion in projectID ) { ( org , module , version , as , cross ) =>
ModuleID ( org , module , version ) . cross ( cross ) . artifacts ( as : _ * )
2011-02-21 16:22:39 +01:00
} ,
2011-07-24 05:07:54 +02:00
projectID <<= pluginProjectID ,
2011-03-10 00:04:53 +01:00
resolvers in GlobalScope : = = Nil ,
2011-03-02 12:46:28 +01:00
projectDescriptors <<= depMap ,
2011-07-24 05:07:54 +02:00
retrievePattern in GlobalScope : = = Resolver . defaultRetrievePattern ,
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-06-19 02:17:50 +02:00
ivyConfiguration <<= mkIvyConfiguration ,
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-06-15 01:32:36 +02:00
ivyConfigurations ++= Configurations . auxiliary ,
2011-04-14 13:32:42 +02:00
moduleSettings <<= moduleSettings0 ,
2011-07-31 19:47:35 +02:00
makePomConfiguration <<= ( artifactPath in makePom , projectInfo , pomExtra , pomPostProcess , pomIncludeRepository , pomAllRepositories ) {
( file , minfo , extra , process , include , all ) => new MakePomConfiguration ( file , minfo , None , extra , process , include , all )
2011-04-22 02:49:38 +02:00
} ,
2011-04-14 13:32:42 +02:00
deliverLocalConfiguration <<= ( crossTarget , ivyLoggingLevel ) map { ( outDir , level ) => deliverConfig ( outDir , logging = level ) } ,
2011-10-16 23:27:36 +02:00
deliverConfiguration <<= deliverLocalConfiguration ,
2012-02-10 10:26:06 +01:00
publishConfiguration <<= ( packagedArtifacts , publishTo , publishMavenStyle , deliver , checksums in publish , ivyLoggingLevel ) map { ( arts , publishTo , mavenStyle , ivyFile , checks , level ) =>
2011-07-22 04:03:56 +02:00
publishConfig ( arts , if ( mavenStyle ) None else Some ( ivyFile ) , resolverName = getPublishTo ( publishTo ) . name , checksums = checks , logging = level )
2011-04-14 13:32:42 +02:00
} ,
2011-07-22 04:03:56 +02:00
publishLocalConfiguration <<= ( packagedArtifacts , deliverLocal , checksums in publishLocal , ivyLoggingLevel ) map {
( arts , ivyFile , checks , level ) => publishConfig ( arts , Some ( ivyFile ) , checks , logging = level )
2011-02-05 04:02:39 +01:00
} ,
2011-07-20 03:29:05 +02:00
ivySbt <<= ivySbt0 ,
2011-03-02 12:46:28 +01:00
ivyModule <<= ( ivySbt , moduleSettings ) map { ( ivySbt , settings ) => new ivySbt . Module ( settings ) } ,
2011-10-30 23:38:37 +01:00
transitiveUpdate <<= transitiveUpdateTask ,
2011-11-22 04:40:10 +01:00
update <<= ( ivyModule , thisProjectRef , updateConfiguration , cacheDirectory , scalaInstance , transitiveUpdate , skip in update , streams ) map { ( module , ref , config , cacheDirectory , si , reports , skip , s ) =>
2011-10-30 23:38:37 +01:00
val depsUpdated = reports . exists ( ! _ . stats . cached )
2011-11-22 04:40:10 +01:00
cachedUpdate ( cacheDirectory / "update" , Project . display ( ref ) , module , config , Some ( si ) , skip , depsUpdated , s . log )
2011-11-20 05:56:30 +01:00
} tag ( Tags . Update , Tags . Network ) ,
2011-07-09 03:54:59 +02:00
update <<= ( conflictWarning , update , streams ) map { ( config , report , s ) => ConflictWarning ( config , report , s . log ) ; report } ,
2011-06-15 01:32:36 +02:00
transitiveClassifiers in GlobalScope : = = Seq ( SourceClassifier , DocClassifier ) ,
2011-08-01 04:17:50 +02:00
classifiersModule in updateClassifiers <<= ( projectID , update , transitiveClassifiers in updateClassifiers , ivyConfigurations in updateClassifiers ) map { ( pid , up , classifiers , confs ) =>
GetClassifiersModule ( pid , up . allModules , confs , classifiers )
} ,
updateClassifiers <<= ( ivySbt , classifiersModule in updateClassifiers , updateConfiguration , ivyScala , target in LocalRootProject , appConfiguration , streams ) map { ( is , mod , c , ivyScala , out , app , s ) =>
withExcludes ( out , mod . classifiers , lock ( app ) ) { excludes =>
IvyActions . updateClassifiers ( is , GetClassifiersConfiguration ( mod , excludes , c , ivyScala ) , s . log )
2011-06-20 03:01:29 +02:00
}
2011-11-20 05:56:30 +01:00
} tag ( Tags . Update , Tags . Network ) ,
2011-03-17 01:09:59 +01:00
sbtDependency in GlobalScope <<= appConfiguration { app =>
2011-03-16 01:35:43 +01:00
val id = app . provider . id
2012-01-23 04:06:53 +01:00
val scalaVersion = app . provider . scalaProvider . version
val binVersion = binaryScalaVersion ( scalaVersion )
val cross = if ( id . crossVersioned ) if ( isStable ( scalaVersion ) ) CrossVersion . binary else CrossVersion . full else CrossVersion . Disabled
val base = ModuleID ( id . groupID , id . name , id . version , crossVersion = cross )
CrossVersion ( scalaVersion , binVersion ) ( base ) . copy ( crossVersion = CrossVersion . Disabled )
2011-02-05 04:02:39 +01:00
}
2011-02-03 13:17:47 +01:00
)
2012-02-10 10:17:25 +01:00
def warnResolversConflict ( ress : Seq [ Resolver ] , log : Logger ) {
for ( ( name , r ) <- ress groupBy ( _ . name ) if r . size > 1 ) {
2012-02-28 12:03:20 +01:00
log . warn ( "Multiple resolvers configured with the name '" + name + "'. To avoid conflict, Remove duplicate project resolvers (`resolvers`) or rename publishing resolver (`publishTo`)." )
2012-02-10 10:17:25 +01:00
}
}
2012-01-23 04:06:53 +01:00
def pluginProjectID : Initialize [ ModuleID ] = ( sbtVersion in update , sbtBinaryVersion in update , scalaVersion in update , scalaBinaryVersion in update , projectID , sbtPlugin ) {
( sbtV , sbtBV , scalaV , scalaBV , pid , isPlugin ) =>
if ( isPlugin )
sbtPluginExtra ( pid , selectVersion ( sbtV , sbtBV ) , selectVersion ( scalaV , scalaBV ) )
else
pid
2011-07-24 05:07:54 +02:00
}
2011-07-20 03:29:05 +02:00
def ivySbt0 : Initialize [ Task [ IvySbt ] ] =
( ivyConfiguration , credentials , streams ) map { ( conf , creds , s ) =>
Credentials . register ( creds , s . log )
new IvySbt ( conf )
}
2011-04-14 13:32:42 +02:00
def moduleSettings0 : Initialize [ Task [ ModuleSettings ] ] =
2012-02-15 03:59:12 +01:00
( projectID , allDependencies , dependencyOverrides , ivyXML , ivyConfigurations , defaultConfiguration , ivyScala , ivyValidate , projectInfo ) map {
( pid , deps , over , ivyXML , confs , defaultConf , ivyS , validate , pinfo ) => new InlineConfiguration ( pid , pinfo , deps , over , ivyXML , confs , defaultConf , ivyS , validate )
2011-04-14 13:32:42 +02:00
}
2011-12-12 14:40:47 +01:00
2011-07-20 03:29:05 +02:00
def sbtClassifiersTasks = inTask ( updateSbtClassifiers ) ( Seq (
transitiveClassifiers in GlobalScope in updateSbtClassifiers ~= ( _ . filter ( _ != DocClassifier ) ) ,
externalResolvers <<= ( externalResolvers , appConfiguration ) map { ( defaultRs , ac ) =>
bootRepositories ( ac ) getOrElse defaultRs
} ,
ivyConfiguration <<= ( externalResolvers , ivyPaths , offline , checksums , appConfiguration , streams ) map { ( rs , paths , off , check , app , s ) =>
new InlineIvyConfiguration ( paths , rs , Nil , Nil , off , Option ( lock ( app ) ) , check , s . log )
} ,
ivySbt <<= ivySbt0 ,
2011-10-16 23:27:36 +02:00
classifiersModule <<= ( projectID , sbtDependency , transitiveClassifiers , loadedBuild , thisProjectRef ) map { ( pid , sbtDep , classifiers , lb , ref ) =>
val pluginIDs : Seq [ ModuleID ] = lb . units ( ref . build ) . unit . plugins . fullClasspath . flatMap ( _ get moduleID . key )
GetClassifiersModule ( pid , sbtDep +: pluginIDs , Configurations . Default : : Nil , classifiers )
2011-08-01 04:17:50 +02:00
} ,
updateSbtClassifiers in TaskGlobal <<= ( ivySbt , classifiersModule , updateConfiguration , ivyScala , target in LocalRootProject , appConfiguration , streams ) map {
( is , mod , c , ivyScala , out , app , s ) =>
withExcludes ( out , mod . classifiers , lock ( app ) ) { excludes =>
IvyActions . transitiveScratch ( is , "sbt" , GetClassifiersConfiguration ( mod , excludes , c , ivyScala ) , s . log )
2011-07-20 03:29:05 +02:00
}
2011-11-20 05:56:30 +01:00
} tag ( Tags . Update , Tags . Network )
2011-07-20 03:29:05 +02:00
) )
2011-04-14 13:32:42 +02:00
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-11-20 05:56:30 +01:00
} tag ( Tags . Publish , Tags . Network )
2011-02-03 13:17:47 +01:00
import Cache._
2011-06-20 03:01:29 +02:00
import CacheIvy. { classpathFormat , /* publishIC, */ updateIC , updateReportF , excludeMap }
def withExcludes ( out : File , classifiers : Seq [ String ] , lock : xsbti . GlobalLock ) ( f : Map [ ModuleID , Set [ String ] ] => UpdateReport ) : UpdateReport =
{
val exclName = "exclude_classifiers"
val file = out / exclName
lock ( out / ( exclName + ".lock" ) , new Callable [ UpdateReport ] { def call = {
val excludes = CacheIO . fromFile [ Map [ ModuleID , Set [ String ] ] ] ( excludeMap , Map . empty [ ModuleID , Set [ String ] ] ) ( file )
val report = f ( excludes )
val allExcludes = excludes ++ IvyActions . extractExcludes ( report )
CacheIO . toFile ( excludeMap ) ( allExcludes ) ( file )
IvyActions . addExcluded ( report , classifiers , allExcludes )
} } )
}
2011-02-03 13:17:47 +01:00
2011-11-22 04:40:10 +01:00
def cachedUpdate ( cacheFile : File , label : String , module : IvySbt # Module , config : UpdateConfiguration , scalaInstance : Option [ ScalaInstance ] , skip : Boolean , depsUpdated : Boolean , 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-06-19 02:17:50 +02:00
log . info ( "Updating " + label + "..." )
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-10-30 23:38:37 +01:00
def uptodate ( inChanged : Boolean , out : UpdateReport ) : Boolean =
! depsUpdated &&
! inChanged &&
out . allFiles . forall ( _ . exists ) &&
out . cachedDescriptor . exists
2011-03-18 02:29:35 +01:00
2011-11-22 04:40:10 +01:00
val outCacheFile = cacheFile / "output"
2011-12-12 14:40:47 +01:00
def skipWork : In => UpdateReport =
2011-11-22 04:40:10 +01:00
Tracked . lastOutput [ In , UpdateReport ] ( outCacheFile ) {
case ( _ , Some ( out ) ) => out
case _ => error ( "Skipping update requested, but update has not previously run successfully." )
}
def doWork : In => UpdateReport =
2011-03-18 02:29:35 +01:00
Tracked . inputChanged ( cacheFile / "inputs" ) { ( inChanged : Boolean , in : In ) =>
2011-11-22 04:40:10 +01:00
val outCache = Tracked . lastOutput [ In , UpdateReport ] ( outCacheFile ) {
2011-10-30 23:38:37 +01:00
case ( _ , Some ( out ) ) if uptodate ( inChanged , out ) => out
2011-03-18 02:29:35 +01:00
case _ => work ( in )
}
outCache ( in )
}
2011-11-22 04:40:10 +01:00
val f = if ( skip ) skipWork else doWork
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 )
2011-07-22 04:03:56 +02:00
def publishConfig ( artifacts : Map [ Artifact , File ] , ivyFile : Option [ File ] , checksums : Seq [ String ] , resolverName : String = "local" , logging : UpdateLogging . Value = UpdateLogging . DownloadOnly ) =
new PublishConfiguration ( ivyFile , resolverName , artifacts , checksums , logging )
2011-02-03 13:17:47 +01:00
2011-05-15 00:21:41 +02:00
def deliverPattern ( outputPath : File ) : String = ( outputPath / "[artifact]-[revision](-[classifier]).[ext]" ) . absolutePath
2011-02-03 13:17:47 +01:00
2011-10-27 01:35:29 +02:00
def projectDependenciesTask : Initialize [ Task [ Seq [ ModuleID ] ] ] =
( thisProjectRef , settings , buildDependencies ) map { ( ref , data , deps ) =>
deps . classpath ( ref ) 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-10-27 01:35:29 +02:00
( thisProjectRef , settings , buildDependencies , streams ) flatMap { ( root , data , deps , s ) =>
depMap ( deps classpathTransitiveRefs root , data , s . log )
2011-02-03 13:17:47 +01:00
}
2011-10-27 01:35:29 +02:00
def depMap ( projects : Seq [ ProjectRef ] , data : Settings [ Scope ] , log : Logger ) : Task [ Map [ ModuleRevisionId , ModuleDescriptor ] ] =
projects . flatMap ( ivyModule in _ get data ) . join . map { mod =>
mod map { _ . dependencyMapping ( log ) } toMap ;
2011-02-03 13:17:47 +01:00
}
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-12-12 14:40:47 +01:00
def makeProducts : Initialize [ Task [ Seq [ File ] ] ] =
2011-06-01 00:37:07 +02:00
( compile , compileInputs , copyResources ) map { ( _ , i , _ ) => i . config . classesDirectory : : Nil }
def exportProductsTask : Initialize [ Task [ Classpath ] ] =
( products . task , packageBin . task , exportJars , compile ) flatMap { ( psTask , pkgTask , useJars , analysis ) =>
( if ( useJars ) Seq ( pkgTask ) . join else psTask ) map { _ map { f => analyzed ( f , analysis ) } }
}
2011-02-03 13:17:47 +01:00
2011-10-27 01:35:29 +02:00
def constructBuildDependencies : Initialize [ BuildDependencies ] =
loadedBuild { lb =>
import collection.mutable.HashMap
val agg = new HashMap [ ProjectRef , Seq [ ProjectRef ] ]
val cp = new HashMap [ ProjectRef , Seq [ ClasspathDep [ ProjectRef ] ] ]
for ( lbu <- lb . units . values ; rp <- lbu . defined . values )
{
val ref = ProjectRef ( lbu . unit . uri , rp . id )
cp ( ref ) = rp . dependencies
agg ( ref ) = rp . aggregate
}
BuildDependencies ( cp . toMap , agg . toMap )
}
2011-02-12 02:22:17 +01:00
def internalDependencies : Initialize [ Task [ Classpath ] ] =
2011-10-27 01:35:29 +02:00
( thisProjectRef , classpathConfiguration , configuration , settings , buildDependencies ) flatMap internalDependencies0
2011-02-20 05:25:30 +01:00
def unmanagedDependencies : Initialize [ Task [ Classpath ] ] =
2011-10-27 01:35:29 +02:00
( thisProjectRef , configuration , settings , buildDependencies ) flatMap unmanagedDependencies0
2011-05-23 14:14:39 +02:00
def mkIvyConfiguration : Initialize [ Task [ IvyConfiguration ] ] =
2012-02-11 09:32:40 +01:00
( fullResolvers , ivyPaths , otherResolvers , moduleConfigurations , offline , checksums in update , appConfiguration , streams ) map { ( rs , paths , other , moduleConfs , off , check , app , s ) =>
warnResolversConflict ( rs ++: other , s . log )
2011-05-23 14:14:39 +02:00
new InlineIvyConfiguration ( paths , rs , other , moduleConfs , off , Some ( lock ( app ) ) , check , s . log )
}
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-10-27 01:35:29 +02:00
def interSort ( projectRef : ProjectRef , conf : Configuration , data : Settings [ Scope ] , deps : BuildDependencies ) : Seq [ ( ProjectRef ,String ) ] =
2011-02-03 13:17:47 +01:00
{
val visited = asScalaSet ( new LinkedHashSet [ ( ProjectRef ,String ) ] )
2011-10-27 01:35:29 +02:00
def visit ( p : ProjectRef , 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 )
2011-06-23 01:17:10 +02:00
val masterConfs = names ( getConfigurations ( projectRef , data ) )
2011-02-03 13:17:47 +01:00
2011-10-27 01:35:29 +02:00
for ( ResolvedClasspathDependency ( dep , confMapping ) <- deps . classpath ( p ) )
2011-02-03 13:17:47 +01:00
{
2011-06-23 01:17:10 +02:00
val configurations = getConfigurations ( dep , data )
val mapping = mapped ( confMapping , masterConfs , names ( configurations ) , "compile" , "*->compile" )
2011-02-03 13:17:47 +01:00
// map master configuration 'c' and all extended configurations to the appropriate dependency configuration
for ( ac <- applicableConfigs ; depConfName <- mapping ( ac . name ) )
{
2011-06-23 01:17:10 +02:00
for ( depConf <- confOpt ( configurations , depConfName ) )
if ( ! visited ( ( dep , depConfName ) ) )
2011-10-27 01:35:29 +02:00
visit ( dep , depConf )
2011-02-03 13:17:47 +01:00
}
}
}
2011-10-27 01:35:29 +02:00
visit ( projectRef , conf )
2011-02-20 05:25:30 +01:00
visited . toSeq
}
2011-10-27 01:35:29 +02:00
def unmanagedDependencies0 ( projectRef : ProjectRef , conf : Configuration , data : Settings [ Scope ] , deps : BuildDependencies ) : Task [ Classpath ] =
interDependencies ( projectRef , deps , conf , conf , data , true , unmanagedLibs )
def internalDependencies0 ( projectRef : ProjectRef , conf : Configuration , self : Configuration , data : Settings [ Scope ] , deps : BuildDependencies ) : Task [ Classpath ] =
interDependencies ( projectRef , deps , conf , self , data , false , productsTask )
def interDependencies ( projectRef : ProjectRef , deps : BuildDependencies , conf : Configuration , self : Configuration , data : Settings [ Scope ] , includeSelf : Boolean ,
2011-02-20 05:25:30 +01:00
f : ( ProjectRef , String , Settings [ Scope ] ) => Task [ Classpath ] ) : Task [ Classpath ] =
{
2011-10-27 01:35:29 +02:00
val visited = interSort ( projectRef , conf , data , deps )
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-06-15 01:32:36 +02:00
if ( includeSelf || ( dep != projectRef ) || ( conf . name != c && self . 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
}
2011-12-12 14:40:47 +01:00
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 ;
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
2011-12-12 14:40:47 +01:00
2011-02-03 13:17:47 +01:00
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-06-23 01:17:10 +02:00
def getConfigurations ( p : ResolvedReference , data : Settings [ Scope ] ) : Seq [ Configuration ] =
ivyConfigurations in p get data getOrElse Nil
def confOpt ( configurations : Seq [ Configuration ] , conf : String ) : Option [ Configuration ] =
configurations . find ( _ . name == conf )
2011-03-03 12:44:19 +01:00
def productsTask ( dep : ResolvedReference , conf : String , data : Settings [ Scope ] ) : Task [ Classpath ] =
2011-06-01 00:37:07 +02:00
getClasspath ( exportedProducts , 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-07-09 22:54:41 +02:00
( key in ( dep , ConfigKey ( conf ) ) ) get data getOrElse constant ( 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-07-24 23:36:41 +02:00
lazy val typesafeSnapshots = typesafeRepo ( "snapshots" )
lazy val typesafeResolver = typesafeRepo ( "releases" )
def typesafeRepo ( status : String ) = Resolver . url ( "typesafe-ivy-" + status , new URL ( "http://repo.typesafe.com/typesafe/ivy-" + status + "/" ) ) ( Resolver . ivyStylePatterns )
2011-07-09 22:54:41 +02:00
def modifyForPlugin ( plugin : Boolean , dep : ModuleID ) : ModuleID =
if ( plugin ) dep . copy ( configurations = Some ( Provided . name ) ) else dep
def autoLibraryDependency ( auto : Boolean , plugin : Boolean , version : String ) : Seq [ ModuleID ] =
if ( auto )
modifyForPlugin ( plugin , ScalaArtifacts . libraryDependency ( version ) ) : : Nil
else
Nil
2011-04-10 22:22:48 +02:00
import DependencyFilter._
2011-06-01 00:37:07 +02:00
def managedJars ( config : Configuration , jarTypes : Set [ String ] , up : UpdateReport ) : Classpath =
2011-06-10 13:48:54 +02:00
up . filter ( configurationFilter ( config . name ) && artifactFilter ( `type` = jarTypes ) ) . toSeq . map { case ( conf , module , art , file ) =>
Attributed ( file ) ( AttributeMap . empty . put ( artifact . key , art ) . put ( moduleID . key , module ) . put ( configuration . key , config ) )
} distinct ;
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
2011-05-13 04:33:45 +02:00
// try/catch for supporting earlier launchers
2011-04-23 21:58:59 +02:00
def bootIvyHome ( app : xsbti . AppConfiguration ) : Option [ File ] =
try { Option ( app . provider . scalaProvider . launcher . ivyHome ) }
catch { case _ : NoSuchMethodError => None }
2011-07-20 03:29:05 +02:00
2011-11-04 17:19:45 +01:00
def bootChecksums ( app : xsbti . AppConfiguration ) : Seq [ String ] =
try { app . provider . scalaProvider . launcher . checksums . toSeq }
catch { case _ : NoSuchMethodError => IvySbt . DefaultChecksums }
2011-07-20 03:29:05 +02:00
def bootRepositories ( app : xsbti . AppConfiguration ) : Option [ Seq [ Resolver ] ] =
try { Some ( app . provider . scalaProvider . launcher . ivyRepositories . toSeq map bootRepository ) }
catch { case _ : NoSuchMethodError => None }
private [ this ] def bootRepository ( repo : xsbti . Repository ) : Resolver =
{
import xsbti.Predefined
repo match
{
case m : xsbti . MavenRepository => MavenRepository ( m . id , m . url . toString )
case i : xsbti . IvyRepository => Resolver . url ( i . id , i . url ) ( Patterns ( i . ivyPattern : : Nil , i . artifactPattern : : Nil , false ) )
case p : xsbti . PredefinedRepository => p . id match {
case Predefined . Local => Resolver . defaultLocal
case Predefined . MavenLocal => Resolver . mavenLocal
case Predefined . MavenCentral => DefaultMavenRepository
case Predefined . ScalaToolsReleases => ScalaToolsReleases
case Predefined . ScalaToolsSnapshots => ScalaToolsSnapshots
}
}
}
2011-03-17 01:09:59 +01:00
}
2011-04-12 04:12:03 +02:00
2011-05-13 04:33:45 +02:00
trait BuildExtra extends BuildCommon
2011-04-12 04:12:03 +02:00
{
2011-04-16 19:16:54 +02:00
import Defaults._
2012-03-05 19:40:17 +01:00
/* * Defines an alias given by `name` that expands to `value`.
* This alias is defined globally after projects are loaded .
* The alias is undefined when projects are unloaded .
* Names are restricted to be either alphanumeric or completely symbolic .
* As an exception , '-' and '_' are allowed within an alphanumeric name . */
def addCommandAlias ( name : String , value : String ) : Seq [ Setting [ State => State ] ] =
{
val add = ( s : State ) => BasicCommands . addAlias ( s , name , value )
val remove = ( s : State ) => BasicCommands . removeAlias ( s , name )
def compose ( setting : SettingKey [ State => State ] , f : State => State ) = setting in Global ~= ( _ compose f )
Seq ( compose ( onLoad , add ) , compose ( onUnload , remove ) )
}
2011-07-24 05:07:54 +02:00
def addSbtPlugin ( dependency : ModuleID ) : Setting [ Seq [ ModuleID ] ] =
2011-12-13 01:24:58 +01:00
libraryDependencies <+= ( sbtBinaryVersion in update , scalaBinaryVersion in update ) { ( sbtV , scalaV ) => sbtPluginExtra ( dependency , sbtV , scalaV ) }
2011-07-24 05:07:54 +02:00
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
2011-10-16 23:27:36 +02:00
def addArtifact ( a : Artifact , taskDef : TaskKey [ File ] ) : SettingsDefinition =
2011-04-16 01:55:22 +02:00
{
val pkgd = packagedArtifacts <<= ( packagedArtifacts , taskDef ) map ( ( pas , file ) => pas updated ( a , file ) )
seq ( artifacts += a , pkgd )
}
2011-10-01 20:39:40 +02:00
def addArtifact ( artifact : Initialize [ Artifact ] , taskDef : Initialize [ Task [ File ] ] ) : SettingsDefinition =
2011-04-16 01:55:22 +02:00
{
2011-10-01 20:39:40 +02:00
val artLocal = SettingKey . local [ Artifact ]
val taskLocal = TaskKey . local [ File ]
val art = artifacts <<= ( artLocal , artifacts ) ( _ +: _ )
val pkgd = packagedArtifacts <<= ( packagedArtifacts , artLocal , taskLocal ) map ( ( pas , a , file ) => pas updated ( a , file ) )
seq ( artLocal <<= artifact , taskLocal <<= taskDef , art , pkgd )
2011-04-16 01:55:22 +02:00
}
def seq ( settings : Setting [ _ ] * ) : SettingsDefinition = new Project . SettingList ( 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 ) }
}
}
2011-10-16 23:27:36 +02:00
def externalIvyFile ( file : Initialize [ File ] = baseDirectory / "ivy.xml" , iScala : Initialize [ Option [ IvyScala ] ] = ivyScala ) : Setting [ Task [ ModuleSettings ] ] =
2011-12-12 14:40:47 +01:00
external ( file , iScala ) ( ( f , is , v ) => new IvyFileConfiguration ( f , is , v ) )
2011-10-16 23:27:36 +02:00
def externalPom ( file : Initialize [ File ] = baseDirectory / "pom.xml" , iScala : Initialize [ Option [ IvyScala ] ] = ivyScala ) : Setting [ Task [ ModuleSettings ] ] =
2011-04-16 19:16:54 +02:00
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 ] ] =
2011-10-16 23:27:36 +02:00
moduleSettings <<= ( ( file zip iScala ) zipWith ivyValidate ) { case ( ( f , is ) , v ) => task { make ( f , is , v ) } }
2011-05-13 04:33:45 +02:00
def runInputTask ( config : Configuration , mainClass : String , baseArguments : String * ) : Initialize [ InputTask [ Unit ] ] =
inputTask { result =>
( fullClasspath in config , runner in ( config , run ) , streams , result ) map { ( cp , r , s , args ) =>
toError ( r . run ( mainClass , data ( cp ) , baseArguments ++ args , s . log ) )
}
}
def runTask ( config : Configuration , mainClass : String , arguments : String * ) : Initialize [ Task [ Unit ] ] =
( fullClasspath in config , runner in ( config , run ) , streams ) map { ( cp , r , s ) =>
toError ( r . run ( mainClass , data ( cp ) , arguments , s . log ) )
}
2011-12-12 14:40:47 +01:00
2011-10-16 23:27:36 +02:00
def fullRunInputTask ( scoped : InputKey [ Unit ] , config : Configuration , mainClass : String , baseArguments : String * ) : Setting [ InputTask [ Unit ] ] =
2011-05-24 03:06:33 +02:00
scoped <<= inputTask { result =>
2011-08-14 16:53:37 +02:00
( initScoped ( scoped . scopedKey , runnerInit ) zipWith ( fullClasspath in config , streams , result ) . identityMap ) { ( rTask , t ) =>
2011-07-31 00:11:20 +02:00
( t : ^: rTask :^: KNil ) map { case ( cp , s , args ) : +: r :+: HNil =>
2011-05-24 03:06:33 +02:00
toError ( r . run ( mainClass , data ( cp ) , baseArguments ++ args , s . log ) )
2011-07-31 00:11:20 +02:00
}
2011-05-24 03:06:33 +02:00
}
}
2011-10-16 23:27:36 +02:00
def fullRunTask ( scoped : TaskKey [ Unit ] , config : Configuration , mainClass : String , arguments : String * ) : Setting [ Task [ Unit ] ] =
2011-08-14 16:53:37 +02:00
scoped <<= ( initScoped ( scoped . scopedKey , runnerInit ) zipWith ( fullClasspath in config , streams ) . identityMap ) { case ( rTask , t ) =>
2011-07-31 00:11:20 +02:00
( t : ^: rTask :^: KNil ) map { case ( cp , s ) : +: r :+: HNil =>
2011-05-24 03:06:33 +02:00
toError ( r . run ( mainClass , data ( cp ) , arguments , s . log ) )
2011-07-31 00:11:20 +02:00
}
2011-05-24 03:06:33 +02:00
}
2011-07-20 03:29:05 +02:00
def initScoped [ T ] ( sk : ScopedKey [ _ ] , i : Initialize [ T ] ) : Initialize [ T ] = initScope ( fillTaskAxis ( sk . scope , sk . key ) , i )
def initScope [ T ] ( s : Scope , i : Initialize [ T ] ) : Initialize [ T ] = i mapReferenced Project . mapScope ( Scope . replaceThis ( s ) )
2011-12-12 14:40:47 +01:00
2011-06-24 02:37:56 +02:00
/* * Disables post-compilation hook for determining tests for tab-completion (such as for 'test-only').
* This is useful for reducing test : compile time when not running test . */
def noTestCompletion ( config : Configuration = Test ) : Setting [ _ ] = inConfig ( config ) ( Seq ( definedTests <<= Defaults . detectTests ) ) . head
2011-07-30 05:33:10 +02:00
def filterKeys ( ss : Seq [ Setting [ _ ] ] , transitive : Boolean = false ) ( f : ScopedKey [ _ ] => Boolean ) : Seq [ Setting [ _ ] ] =
2011-08-27 05:27:03 +02:00
ss filter ( s => f ( s . key ) && ( ! transitive || s . dependencies . forall ( f ) ) )
2011-05-13 04:33:45 +02:00
}
trait BuildCommon
{
def inputTask [ T ] ( f : TaskKey [ Seq [ String ] ] => Initialize [ Task [ T ] ] ) : Initialize [ InputTask [ T ] ] = InputTask ( _ => complete . Parsers . spaceDelimited ( "<arg>" ) ) ( f )
implicit def globFilter ( expression : String ) : NameFilter = GlobFilter ( expression )
implicit def richAttributed ( s : Seq [ Attributed [ File ] ] ) : RichAttributed = new RichAttributed ( s )
2011-06-01 00:37:07 +02:00
implicit def richFiles ( s : Seq [ File ] ) : RichFiles = new RichFiles ( s )
implicit def richPathFinder ( s : PathFinder ) : RichPathFinder = new RichPathFinder ( s )
final class RichPathFinder private [ sbt ] ( s : PathFinder )
{
def classpath : Classpath = Attributed blankSeq s . get
}
2011-05-13 04:33:45 +02:00
final class RichAttributed private [ sbt ] ( s : Seq [ Attributed [ File ] ] )
{
def files : Seq [ File ] = Build data s
}
2011-06-01 00:37:07 +02:00
final class RichFiles private [ sbt ] ( s : Seq [ File ] )
{
def classpath : Classpath = Attributed blankSeq s
}
2011-05-13 04:33:45 +02:00
def toError ( o : Option [ String ] ) : Unit = o foreach error
2011-07-09 22:54:41 +02:00
def overrideConfigs ( cs : Configuration * ) ( configurations : Seq [ Configuration ] ) : Seq [ Configuration ] =
{
val existingName = configurations . map ( _ . name ) . toSet
val newByName = cs . map ( c => ( c . name , c ) ) . toMap
val overridden = configurations map { conf => newByName . getOrElse ( conf . name , conf ) }
val newConfigs = cs filter { c => ! existingName ( c . name ) }
overridden ++ newConfigs
}
2011-09-22 04:54:46 +02:00
// these are intended for use in input tasks for creating parsers
2011-10-16 23:27:36 +02:00
def getFromContext [ T ] ( task : TaskKey [ T ] , context : ScopedKey [ _ ] , s : State ) : Option [ T ] =
2011-09-22 04:54:46 +02:00
SessionVar . get ( SessionVar . resolveContext ( task . scopedKey , context . scope , s ) , s )
2011-10-16 23:27:36 +02:00
def loadFromContext [ T ] ( task : TaskKey [ T ] , context : ScopedKey [ _ ] , s : State ) ( implicit f : sbinary.Format [ T ] ) : Option [ T ] =
2011-09-22 04:54:46 +02:00
SessionVar . load ( SessionVar . resolveContext ( task . scopedKey , context . scope , s ) , s )
2011-09-22 04:54:46 +02:00
// intended for use in constructing InputTasks
2011-10-16 23:27:36 +02:00
def loadForParser [ P ,T ] ( task : TaskKey [ T ] ) ( f : ( State , Option [ T ] ) => Parser [ P ] ) ( implicit format : sbinary.Format [ T ] ) : Initialize [ State => Parser [ P ] ] =
2011-09-22 04:54:46 +02:00
loadForParserI ( task ) ( Project value f ) ( format )
2011-10-16 23:27:36 +02:00
def loadForParserI [ P ,T ] ( task : TaskKey [ T ] ) ( init : Initialize [ ( State , Option [ T ] ) => Parser [ P ] ] ) ( implicit format : sbinary.Format [ T ] ) : Initialize [ State => Parser [ P ] ] =
2011-09-22 04:54:46 +02:00
( resolvedScoped , init ) ( ( ctx , f ) => ( s : State ) => f ( s , loadFromContext ( task , ctx , s ) ( format ) ) )
2011-10-16 23:27:36 +02:00
def getForParser [ P ,T ] ( task : TaskKey [ T ] ) ( init : ( State , Option [ T ] ) => Parser [ P ] ) : Initialize [ State => Parser [ P ] ] =
2011-09-22 04:54:46 +02:00
getForParserI ( task ) ( Project value init )
2011-10-16 23:27:36 +02:00
def getForParserI [ P ,T ] ( task : TaskKey [ T ] ) ( init : Initialize [ ( State , Option [ T ] ) => Parser [ P ] ] ) : Initialize [ State => Parser [ P ] ] =
2011-09-22 04:54:46 +02:00
( resolvedScoped , init ) ( ( ctx , f ) => ( s : State ) => f ( s , getFromContext ( task , ctx , s ) ) )
// these are for use for constructing Tasks
2011-10-16 23:27:36 +02:00
def loadPrevious [ T ] ( task : TaskKey [ T ] ) ( implicit f : sbinary.Format [ T ] ) : Initialize [ Task [ Option [ T ] ] ] =
2011-09-22 04:54:46 +02:00
( state , resolvedScoped ) map { ( s , ctx ) => loadFromContext ( task , ctx , s ) ( f ) }
2011-10-16 23:27:36 +02:00
def getPrevious [ T ] ( task : TaskKey [ T ] ) : Initialize [ Task [ Option [ T ] ] ] =
2011-09-22 04:54:46 +02:00
( state , resolvedScoped ) map { ( s , ctx ) => getFromContext ( task , ctx , s ) }
2011-11-10 10:21:31 +01:00
}