work on products+configurations

This commit is contained in:
Mark Harrah 2010-11-13 20:21:06 -05:00
parent de3ad8c860
commit 54ba5d75be
3 changed files with 45 additions and 25 deletions

View File

@ -292,11 +292,11 @@ object Configurations
lazy val Default = config("default")
lazy val Compile = config("compile")
lazy val IntegrationTest = config("it") hide
lazy val IntegrationTest = config("it") extend(Runtime) hide;
lazy val Provided = config("provided")
lazy val Javadoc = config("javadoc")
lazy val Runtime = config("runtime")
lazy val Test = config("test") hide
lazy val Runtime = config("runtime") extend(Compile)
lazy val Test = config("test") extend(Runtime) hide;
lazy val Sources = config("sources")
lazy val System = config("system")
lazy val Optional = config("optional")
@ -310,7 +310,7 @@ object Configurations
private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*)
}
/** Represents an Ivy configuration. */
final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) extends NotNull
final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean)
{
require(name != null && !name.isEmpty)
require(description != null)
@ -323,7 +323,7 @@ final case class Configuration(name: String, description: String, isPublic: Bool
override def toString = name
}
final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) extends NotNull
final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String])
{
def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes))
}

View File

@ -183,6 +183,12 @@ object ClasspathProject
analyzed(i.config.classesDirectory, analysis)
}
def makeProducts(compile: Task[Analysis], inputs: Task[Compile.Inputs], name: String, prefix: String) =
{
def mkName(postfix: String) = name + "/" + prefix + postfix
analyzed(compile, inputs) named(mkName("analyzed")) map { _ :: Nil } named(mkName("products"))
}
def concat[A]: (Seq[A], Seq[A]) => Seq[A] = _ ++ _
def extractAnalysis[T](a: Attributed[T]): (T, Analysis) =
@ -222,19 +228,26 @@ object ClasspathProject
val visited = new LinkedHashSet[(Project,String)]
def visit(p: Project, c: String)
{
for( (dep, confMapping) <- ClasspathProject.resolvedDependencies(p))
val applicableConfigs = allConfigs(p, c)
for(ac <- applicableConfigs)
visited add (p, ac)
for( (dep, confMapping) <- resolvedDependencies(p))
{
val depConf = mapped(c, confMapping, defaultConfiguration(dep).toString) { missingMapping(p.name, dep.name, c) }
val unvisited = visited.add( (dep, depConf) )
if(unvisited) visit(dep, depConf)
if( ! visited( (dep, depConf) ) )
visit(dep, depConf)
}
}
visit(project, conf.toString)
visit(project, conf.name)
val productsTasks = new LinkedHashSet[Task[Seq[Attributed[File]]]]
for( (dep: ClasspathProject, conf) <- visited )
if(dep ne project) productsTasks += products(dep, conf)
(productsTasks.toSeq.join) named(project.name + "/join") map(_.flatten)
for( (dep: ClasspathProject, c) <- visited )
if( (dep ne project) || conf.name != c )
productsTasks += products(dep, c)
def name(action: String) = project.name + "/" + conf + "/" + action + "-products"
(productsTasks.toSeq.join) named(name("join")) map(_.flatten) named(name("flatten"))
}
def parseSimpleConfigurations(confString: String): Map[String, String] =
@ -253,8 +266,15 @@ object ClasspathProject
error("No configuration mapping defined from '" + from + "' to '" + to + "' for '" + conf + "'")
def missingConfiguration(in: String, conf: String) =
error("Configuration '" + conf + "' not defined in '" + in)
def allConfigs(dep: Project, conf: String): Seq[String] =
dep match {
case cp: ClasspathProject => Dag.topologicalSort(configuration(cp, conf))(_.extendsConfigs).map(_.name)
case _ => Nil
}
def configuration(dep: ClasspathProject, conf: String): Configuration =
dep.configurationMap.getOrElse(conf,missingConfiguration(dep.name, conf))
def products(dep: ClasspathProject, conf: String) =
dep.products(dep.configurationMap.getOrElse(conf,missingConfiguration(dep.name, conf)))
dep.products(configuration(dep, conf))
def defaultConfiguration(p: Project): Configuration =
p match
{

View File

@ -7,7 +7,7 @@ package sbt
import compile.{Discovered,Discovery}
import inc.Analysis
import TaskExtra._
import Configurations.{Compile => CompileConfig, Test => TestConfig, Runtime => RunConfig}
import Configurations.{Compile => CompileConfig, Test => TestConfig, Runtime => RunConfig, Default => DefaultConfig}
import ClasspathProject._
import Types._
import xsbti.api.Definition
@ -38,13 +38,14 @@ abstract class BasicProject extends TestProject with MultiClasspathProject with
case x => outputDirectory / (x.toString + "-classes")
}
// TODO: resources, jars, test classes
lazy val products: Classpath =
TaskMap { (conf: Configuration) =>
conf match {
case CompileConfig | RunConfig => analyzed(compile, compileInputs) named(name + "/analyzed") map { _ :: Nil } named(name + "/products")
case x => error("Unknown compilation configuration: " + x)
}
lazy val products: Classpath = TaskMap(productsTask)
// TODO: it config, include resources, perhaps handle jars v. directories
def productsTask(conf: Configuration) =
conf match {
case CompileConfig | DefaultConfig => makeProducts(compile, compileInputs, name, "")
case TestConfig => makeProducts(testCompile, testCompileInputs, name, "test-")
case x => task { Nil }
}
lazy val buildScalaInstance: Task[ScalaInstance] = task {
@ -88,8 +89,7 @@ abstract class BasicProject extends TestProject with MultiClasspathProject with
def compileInputsTask(configuration: Configuration, base: PathFinder, scalaInstance: Task[ScalaInstance]): Task[Compile.Inputs] =
{
val dep = dependencyClasspath(configuration)
val prod: Task[Seq[Attributed[File]]] = (configuration.extendsConfigs map products).join.map(_.flatten)
(dep, prod, scalaInstance) map { case (cp :+: prodcp :+: si :+: HNil) =>
(dep, scalaInstance) map { case (cp :+: si :+: HNil) =>
val log = ConsoleLogger()
val compilers = Compile.compilers(si)(info.configuration, log)
val javaSrc = base / "java"
@ -98,8 +98,8 @@ abstract class BasicProject extends TestProject with MultiClasspathProject with
import Path._
val sources = descendents((javaSrc +++ scalaSrc), sourceFilter) +++ (if(configuration == CompileConfig) info.projectDirectory * (sourceFilter -- defaultExcludes) else Path.emptyPathFinder)
val classes = classesDirectory(configuration)
val classpath = (classes +: data(prodcp)) ++ data(cp)
val analysis = analysisMap(prodcp ++ cp)
val classpath = classes +: data(cp)
val analysis = analysisMap(cp)
val cache = cacheDirectory / "compile" / configuration.toString
Compile.inputs(classpath, sources.getFiles.toSeq, classes, scalacOptions, javacOptions, javaSrc.getFiles.toSeq, analysis, cache, 100)(compilers, log)
}