mirror of https://github.com/sbt/sbt.git
reorganization of main/
* split several source files * move base settings sources (Scope, Structure, ...) into main/settings/ * breaks cycles. In particular, setting system moved from Project to Def
This commit is contained in:
parent
87e406fcbd
commit
eecaeafbdf
|
|
@ -3,9 +3,9 @@
|
||||||
*/
|
*/
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import Project.{ScopedKey, showContextKey}
|
import Def.{showRelativeKey, ScopedKey}
|
||||||
|
import Project.showContextKey
|
||||||
import Keys.{sessionSettings, thisProject}
|
import Keys.{sessionSettings, thisProject}
|
||||||
import Load.BuildStructure
|
|
||||||
import complete.{DefaultParsers, Parser}
|
import complete.{DefaultParsers, Parser}
|
||||||
import Aggregation.{KeyValue,Values}
|
import Aggregation.{KeyValue,Values}
|
||||||
import DefaultParsers._
|
import DefaultParsers._
|
||||||
|
|
@ -31,7 +31,7 @@ object Act
|
||||||
def scopedKeySelected(index: KeyIndex, current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String],
|
def scopedKeySelected(index: KeyIndex, current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String],
|
||||||
keyMap: Map[String, AttributeKey[_]], data: Settings[Scope]): Parser[ParsedKey] =
|
keyMap: Map[String, AttributeKey[_]], data: Settings[Scope]): Parser[ParsedKey] =
|
||||||
scopedKeyFull(index, current, defaultConfigs, keyMap) flatMap { choices =>
|
scopedKeyFull(index, current, defaultConfigs, keyMap) flatMap { choices =>
|
||||||
select(choices, data)( Project.showRelativeKey(current, index.buildURIs.size > 1) )
|
select(choices, data)( showRelativeKey(current, index.buildURIs.size > 1) )
|
||||||
}
|
}
|
||||||
|
|
||||||
def scopedKeyFull(index: KeyIndex, current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String], keyMap: Map[String, AttributeKey[_]]): Parser[Seq[Parser[ParsedKey]]] =
|
def scopedKeyFull(index: KeyIndex, current: ProjectRef, defaultConfigs: Option[ResolvedReference] => Seq[String], keyMap: Map[String, AttributeKey[_]]): Parser[Seq[Parser[ParsedKey]]] =
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
*/
|
*/
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import Project.ScopedKey
|
import Def.ScopedKey
|
||||||
import Load.{BuildStructure,LoadedBuildUnit}
|
|
||||||
import Keys.{aggregate, showSuccess, showTiming, timingFormat}
|
import Keys.{aggregate, showSuccess, showTiming, timingFormat}
|
||||||
import sbt.complete.Parser
|
import sbt.complete.Parser
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
@ -30,7 +29,7 @@ final object Aggregation
|
||||||
Command.applyEffect(seqParser(ps)) { ts =>
|
Command.applyEffect(seqParser(ps)) { ts =>
|
||||||
runTasks(s, structure, ts, Dummies(KNil, HNil), show)
|
runTasks(s, structure, ts, Dummies(KNil, HNil), show)
|
||||||
}
|
}
|
||||||
def runTasksWithResult[HL <: HList, T](s: State, structure: Load.BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) =
|
def runTasksWithResult[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) =
|
||||||
{
|
{
|
||||||
import EvaluateTask._
|
import EvaluateTask._
|
||||||
import std.TaskExtra._
|
import std.TaskExtra._
|
||||||
|
|
@ -55,7 +54,7 @@ final object Aggregation
|
||||||
(newS, result)
|
(newS, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
def runTasks[HL <: HList, T](s: State, structure: Load.BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): State = {
|
def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): State = {
|
||||||
runTasksWithResult(s, structure, ts, extra, show)._1
|
runTasksWithResult(s, structure, ts, extra, show)._1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,16 +156,7 @@ final object Aggregation
|
||||||
def aggregationEnabled(key: ScopedKey[_], data: Settings[Scope]): Boolean =
|
def aggregationEnabled(key: ScopedKey[_], data: Settings[Scope]): Boolean =
|
||||||
Keys.aggregate in Scope.fillTaskAxis(key.scope, key.key) get data getOrElse true
|
Keys.aggregate in Scope.fillTaskAxis(key.scope, key.key) get data getOrElse true
|
||||||
|
|
||||||
|
@deprecated("Use BuildUtil.aggregationRelation", "0.13.0")
|
||||||
def relation(units: Map[URI, LoadedBuildUnit]): Relation[ProjectRef, ProjectRef] =
|
def relation(units: Map[URI, LoadedBuildUnit]): Relation[ProjectRef, ProjectRef] =
|
||||||
{
|
BuildUtil.aggregationRelation(units)
|
||||||
val depPairs =
|
|
||||||
for {
|
|
||||||
(uri, unit) <- units.toIterable
|
|
||||||
project <- unit.defined.values
|
|
||||||
ref = ProjectRef(uri, project.id)
|
|
||||||
agg <- project.aggregate
|
|
||||||
} yield
|
|
||||||
(ref, agg)
|
|
||||||
Relation.empty ++ depPairs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
298
main/Build.scala
298
main/Build.scala
|
|
@ -4,16 +4,8 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
|
||||||
import BuildLoader.ResolveInfo
|
|
||||||
import compiler.{Eval, EvalImports}
|
|
||||||
import complete.DefaultParsers.validID
|
|
||||||
import Compiler.Compilers
|
|
||||||
import Keys.{globalBaseDirectory, globalPluginsDirectory, globalSettingsDirectory, stagingDirectory, Streams}
|
|
||||||
import Keys.{name, organization, thisProject}
|
import Keys.{name, organization, thisProject}
|
||||||
import Project.{ScopedKey, Setting}
|
import Def.{ScopedKey, Setting}
|
||||||
import Scope.GlobalScope
|
|
||||||
import scala.annotation.tailrec
|
|
||||||
|
|
||||||
// name is more like BuildDefinition, but that is too long
|
// name is more like BuildDefinition, but that is too long
|
||||||
trait Build
|
trait Build
|
||||||
|
|
@ -26,16 +18,16 @@ trait Build
|
||||||
trait Plugin
|
trait Plugin
|
||||||
{
|
{
|
||||||
@deprecated("Override projectSettings or buildSettings instead.", "0.12.0")
|
@deprecated("Override projectSettings or buildSettings instead.", "0.12.0")
|
||||||
def settings: Seq[Project.Setting[_]] = Nil
|
def settings: Seq[Setting[_]] = Nil
|
||||||
|
|
||||||
/** Settings to be appended to all projects in a build. */
|
/** Settings to be appended to all projects in a build. */
|
||||||
def projectSettings: Seq[Project.Setting[_]] = Nil
|
def projectSettings: Seq[Setting[_]] = Nil
|
||||||
|
|
||||||
/** Settings to be appended at the build scope. */
|
/** Settings to be appended at the build scope. */
|
||||||
def buildSettings: Seq[Project.Setting[_]] = Nil
|
def buildSettings: Seq[Setting[_]] = Nil
|
||||||
|
|
||||||
/** Settings to be appended at the global scope. */
|
/** Settings to be appended at the global scope. */
|
||||||
def globalSettings: Seq[Project.Setting[_]] = Nil
|
def globalSettings: Seq[Setting[_]] = Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
object Build
|
object Build
|
||||||
|
|
@ -47,283 +39,7 @@ object Build
|
||||||
organization <<= (thisProject, organization, name) { (p, o, n) => if(p.id == n) "default" else o }
|
organization <<= (thisProject, organization, name) { (p, o, n) => if(p.id == n) "default" else o }
|
||||||
)
|
)
|
||||||
|
|
||||||
def data[T](in: Seq[Attributed[T]]): Seq[T] = in.map(_.data)
|
@deprecated("Use Attributed.data", "0.13.0")
|
||||||
|
def data[T](in: Seq[Attributed[T]]): Seq[T] = Attributed.data(in)
|
||||||
def analyzed(in: Seq[Attributed[_]]): Seq[inc.Analysis] = in.flatMap{ _.metadata.get(Keys.analysis) }
|
def analyzed(in: Seq[Attributed[_]]): Seq[inc.Analysis] = in.flatMap{ _.metadata.get(Keys.analysis) }
|
||||||
}
|
}
|
||||||
object RetrieveUnit
|
|
||||||
{
|
|
||||||
def apply(info: ResolveInfo): Option[() => File] =
|
|
||||||
{
|
|
||||||
info.uri match {
|
|
||||||
case Scheme("svn") | Scheme("svn+ssh") => Resolvers.subversion(info)
|
|
||||||
case Scheme("hg") => Resolvers.mercurial(info)
|
|
||||||
case Scheme("git") => Resolvers.git(info)
|
|
||||||
case Path(path) if path.endsWith(".git") => Resolvers.git(info)
|
|
||||||
case Scheme("http") | Scheme("https") | Scheme("ftp") => Resolvers.remote(info)
|
|
||||||
case Scheme("file") => Resolvers.local(info)
|
|
||||||
case _ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object Scheme
|
|
||||||
{
|
|
||||||
def unapply(uri: URI) = Option(uri.getScheme)
|
|
||||||
}
|
|
||||||
|
|
||||||
object Path
|
|
||||||
{
|
|
||||||
import RichURI.fromURI
|
|
||||||
|
|
||||||
def unapply(uri: URI) = Option(uri.withoutMarkerScheme.getPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object EvaluateConfigurations
|
|
||||||
{
|
|
||||||
private[this] final class ParsedFile(val imports: Seq[(String,Int)], val definitions: Seq[(String,LineRange)], val settings: Seq[(String,LineRange)])
|
|
||||||
private[this] final class Definitions(val loader: ClassLoader => ClassLoader, val moduleNames: Seq[String])
|
|
||||||
|
|
||||||
private[this] val DefinitionKeywords = Seq("lazy val ", "def ", "val ")
|
|
||||||
|
|
||||||
def apply(eval: Eval, srcs: Seq[File], imports: Seq[String]): ClassLoader => Seq[Setting[_]] =
|
|
||||||
flatten(srcs.sortBy(_.getName) map { src => evaluateConfiguration(eval, src, imports) })
|
|
||||||
def evaluateConfiguration(eval: Eval, src: File, imports: Seq[String]): ClassLoader => Seq[Setting[_]] =
|
|
||||||
evaluateConfiguration(eval, src.getPath, IO.readLines(src), imports, 0)
|
|
||||||
|
|
||||||
private[this] def parseConfiguration(lines: Seq[String], builtinImports: Seq[String], offset: Int): ParsedFile =
|
|
||||||
{
|
|
||||||
val (importStatements, settingsAndDefinitions) = splitExpressions(lines)
|
|
||||||
val allImports = builtinImports.map(s => (s, -1)) ++ addOffset(offset, importStatements)
|
|
||||||
val (definitions, settings) = splitSettingsDefinitions(addOffsetToRange(offset, settingsAndDefinitions))
|
|
||||||
new ParsedFile(allImports, definitions, settings)
|
|
||||||
}
|
|
||||||
|
|
||||||
def evaluateConfiguration(eval: Eval, name: String, lines: Seq[String], imports: Seq[String], offset: Int): ClassLoader => Seq[Setting[_]] =
|
|
||||||
{
|
|
||||||
val parsed = parseConfiguration(lines, imports, offset)
|
|
||||||
val importDefs = if(parsed.definitions.isEmpty) Nil else {
|
|
||||||
val definitions = evaluateDefinitions(eval, name, parsed.imports, parsed.definitions)
|
|
||||||
Load.importAllRoot(definitions.moduleNames).map(s => (s, -1))
|
|
||||||
}
|
|
||||||
val allImports = importDefs ++ parsed.imports
|
|
||||||
val settings = parsed.settings map { case (settingExpression,range) =>
|
|
||||||
evaluateSetting(eval, name, allImports, settingExpression, range)
|
|
||||||
}
|
|
||||||
eval.unlinkDeferred()
|
|
||||||
flatten(settings)
|
|
||||||
}
|
|
||||||
def flatten(mksettings: Seq[ClassLoader => Seq[Setting[_]]]): ClassLoader => Seq[Setting[_]] =
|
|
||||||
loader => mksettings.flatMap(_ apply loader)
|
|
||||||
def addOffset(offset: Int, lines: Seq[(String,Int)]): Seq[(String,Int)] =
|
|
||||||
lines.map { case (s, i) => (s, i + offset) }
|
|
||||||
def addOffsetToRange(offset: Int, ranges: Seq[(String,LineRange)]): Seq[(String,LineRange)] =
|
|
||||||
ranges.map { case (s, r) => (s, r shift offset) }
|
|
||||||
|
|
||||||
def evaluateSetting(eval: Eval, name: String, imports: Seq[(String,Int)], expression: String, range: LineRange): ClassLoader => Seq[Setting[_]] =
|
|
||||||
{
|
|
||||||
val result = try {
|
|
||||||
eval.eval(expression, imports = new EvalImports(imports, name), srcName = name, tpeName = Some("sbt.Project.SettingsDefinition"), line = range.start)
|
|
||||||
} catch {
|
|
||||||
case e: sbt.compiler.EvalException => throw new MessageOnlyException(e.getMessage)
|
|
||||||
}
|
|
||||||
loader => {
|
|
||||||
val pos = RangePosition(name, range shift 1)
|
|
||||||
result.getValue(loader).asInstanceOf[Project.SettingsDefinition].settings map (_ withPos pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private[this] def isSpace = (c: Char) => Character isWhitespace c
|
|
||||||
private[this] def fstS(f: String => Boolean): ((String,Int)) => Boolean = { case (s,i) => f(s) }
|
|
||||||
private[this] def firstNonSpaceIs(lit: String) = (_: String).view.dropWhile(isSpace).startsWith(lit)
|
|
||||||
private[this] def or[A](a: A => Boolean, b: A => Boolean): A => Boolean = in => a(in) || b(in)
|
|
||||||
def splitExpressions(lines: Seq[String]): (Seq[(String,Int)], Seq[(String,LineRange)]) =
|
|
||||||
{
|
|
||||||
val blank = (_: String).forall(isSpace)
|
|
||||||
val isImport = firstNonSpaceIs("import ")
|
|
||||||
val comment = firstNonSpaceIs("//")
|
|
||||||
val blankOrComment = or(blank, comment)
|
|
||||||
val importOrBlank = fstS(or(blankOrComment, isImport))
|
|
||||||
|
|
||||||
val (imports, settings) = lines.zipWithIndex span importOrBlank
|
|
||||||
(imports filterNot fstS( blankOrComment ), groupedLines(settings, blank, blankOrComment))
|
|
||||||
}
|
|
||||||
def groupedLines(lines: Seq[(String,Int)], delimiter: String => Boolean, skipInitial: String => Boolean): Seq[(String,LineRange)] =
|
|
||||||
{
|
|
||||||
val fdelim = fstS(delimiter)
|
|
||||||
@tailrec def group0(lines: Seq[(String,Int)], accum: Seq[(String,LineRange)]): Seq[(String,LineRange)] =
|
|
||||||
if(lines.isEmpty) accum.reverse
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val start = lines dropWhile fstS( skipInitial )
|
|
||||||
val (next, tail) = start.span { case (s,_) => !delimiter(s) }
|
|
||||||
val grouped = if(next.isEmpty) accum else (next.map(_._1).mkString("\n"), LineRange(next.head._2, next.last._2 + 1)) +: accum
|
|
||||||
group0(tail, grouped)
|
|
||||||
}
|
|
||||||
group0(lines, Nil)
|
|
||||||
}
|
|
||||||
private[this] def splitSettingsDefinitions(lines: Seq[(String,LineRange)]): (Seq[(String,LineRange)], Seq[(String,LineRange)]) =
|
|
||||||
lines partition { case (line, range) => isDefinition(line) }
|
|
||||||
private[this] def isDefinition(line: String): Boolean =
|
|
||||||
{
|
|
||||||
val trimmed = line.trim
|
|
||||||
DefinitionKeywords.exists(trimmed startsWith _)
|
|
||||||
}
|
|
||||||
private[this] def evaluateDefinitions(eval: Eval, name: String, imports: Seq[(String,Int)], definitions: Seq[(String,LineRange)]): Definitions =
|
|
||||||
{
|
|
||||||
val convertedRanges = definitions.map { case (s, r) => (s, r.start to r.end) }
|
|
||||||
val res = eval.evalDefinitions(convertedRanges, new EvalImports(imports, name), name)
|
|
||||||
new Definitions(loader => res.getValue(loader).getClass.getClassLoader, res.enclosingModule :: Nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
object Index
|
|
||||||
{
|
|
||||||
def taskToKeyMap(data: Settings[Scope]): Map[Task[_], ScopedKey[Task[_]]] =
|
|
||||||
{
|
|
||||||
// AttributeEntry + the checked type test 'value: Task[_]' ensures that the cast is correct.
|
|
||||||
// (scalac couldn't determine that 'key' is of type AttributeKey[Task[_]] on its own and a type match still required the cast)
|
|
||||||
val pairs = for( scope <- data.scopes; AttributeEntry(key, value: Task[_]) <- data.data(scope).entries ) yield
|
|
||||||
(value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]])) // unclear why this cast is needed even with a type test in the above filter
|
|
||||||
pairs.toMap[Task[_], ScopedKey[Task[_]]]
|
|
||||||
}
|
|
||||||
def allKeys(settings: Seq[Setting[_]]): Set[ScopedKey[_]] =
|
|
||||||
settings.flatMap(s => if(s.key.key.isLocal) Nil else s.key +: s.dependencies).filter(!_.key.isLocal).toSet
|
|
||||||
def attributeKeys(settings: Settings[Scope]): Set[AttributeKey[_]] =
|
|
||||||
settings.data.values.flatMap(_.keys).toSet[AttributeKey[_]]
|
|
||||||
def stringToKeyMap(settings: Set[AttributeKey[_]]): Map[String, AttributeKey[_]] =
|
|
||||||
{
|
|
||||||
val multiMap = settings.groupBy(_.label)
|
|
||||||
val duplicates = multiMap collect { case (k, xs) if xs.size > 1 => (k, xs.map(_.manifest)) } collect { case (k, xs) if xs.size > 1 => (k, xs) }
|
|
||||||
if(duplicates.isEmpty)
|
|
||||||
multiMap.collect { case (k, v) if validID(k) => (k, v.head) } toMap;
|
|
||||||
else
|
|
||||||
error(duplicates map { case (k, tps) => "'" + k + "' (" + tps.mkString(", ") + ")" } mkString("AttributeKey ID collisions detected for: ", ", ", ""))
|
|
||||||
}
|
|
||||||
private[this] type TriggerMap = collection.mutable.HashMap[Task[_], Seq[Task[_]]]
|
|
||||||
def triggers(ss: Settings[Scope]): Triggers[Task] =
|
|
||||||
{
|
|
||||||
val runBefore = new TriggerMap
|
|
||||||
val triggeredBy = new TriggerMap
|
|
||||||
for( (_, amap) <- ss.data; AttributeEntry(_, value: Task[_]) <- amap.entries)
|
|
||||||
{
|
|
||||||
val as = value.info.attributes
|
|
||||||
update(runBefore, value, as get Keys.runBefore)
|
|
||||||
update(triggeredBy, value, as get Keys.triggeredBy)
|
|
||||||
}
|
|
||||||
val onComplete = Keys.onComplete in GlobalScope get ss getOrElse { () => () }
|
|
||||||
new Triggers[Task](runBefore, triggeredBy, map => { onComplete(); map } )
|
|
||||||
}
|
|
||||||
private[this] def update(map: TriggerMap, base: Task[_], tasksOpt: Option[Seq[Task[_]]]): Unit =
|
|
||||||
for( tasks <- tasksOpt; task <- tasks )
|
|
||||||
map(task) = base +: map.getOrElse(task, Nil)
|
|
||||||
}
|
|
||||||
object BuildStreams
|
|
||||||
{
|
|
||||||
import Load.{BuildStructure, LoadedBuildUnit}
|
|
||||||
import Project.displayFull
|
|
||||||
import std.{TaskExtra,Transform}
|
|
||||||
import Path._
|
|
||||||
import BuildPaths.outputDirectory
|
|
||||||
|
|
||||||
final val GlobalPath = "$global"
|
|
||||||
final val BuildUnitPath = "$build"
|
|
||||||
final val StreamsDirectory = "streams"
|
|
||||||
|
|
||||||
def mkStreams(units: Map[URI, LoadedBuildUnit], root: URI, data: Settings[Scope]): State => Streams = s =>
|
|
||||||
std.Streams( path(units, root, data), displayFull, LogManager.construct(data, s) )
|
|
||||||
|
|
||||||
def path(units: Map[URI, LoadedBuildUnit], root: URI, data: Settings[Scope])(scoped: ScopedKey[_]): File =
|
|
||||||
resolvePath( projectPath(units, root, scoped, data), nonProjectPath(scoped) )
|
|
||||||
|
|
||||||
def resolvePath(base: File, components: Seq[String]): File =
|
|
||||||
(base /: components)( (b,p) => new File(b,p) )
|
|
||||||
|
|
||||||
def pathComponent[T](axis: ScopeAxis[T], scoped: ScopedKey[_], label: String)(show: T => String): String =
|
|
||||||
axis match
|
|
||||||
{
|
|
||||||
case Global => GlobalPath
|
|
||||||
case This => error("Unresolved This reference for " + label + " in " + Project.displayFull(scoped))
|
|
||||||
case Select(t) => show(t)
|
|
||||||
}
|
|
||||||
def nonProjectPath[T](scoped: ScopedKey[T]): Seq[String] =
|
|
||||||
{
|
|
||||||
val scope = scoped.scope
|
|
||||||
pathComponent(scope.config, scoped, "config")(_.name) ::
|
|
||||||
pathComponent(scope.task, scoped, "task")(_.label) ::
|
|
||||||
pathComponent(scope.extra, scoped, "extra")(showAMap) ::
|
|
||||||
Nil
|
|
||||||
}
|
|
||||||
def showAMap(a: AttributeMap): String =
|
|
||||||
a.entries.toSeq.sortBy(_.key.label).map { case AttributeEntry(key, value) => key.label + "=" + value.toString } mkString(" ")
|
|
||||||
def projectPath(units: Map[URI, LoadedBuildUnit], root: URI, scoped: ScopedKey[_], data: Settings[Scope]): File =
|
|
||||||
scoped.scope.project match
|
|
||||||
{
|
|
||||||
case Global => refTarget(GlobalScope, units(root).localBase, data) / GlobalPath
|
|
||||||
case Select(br @ BuildRef(uri)) => refTarget(br, units(uri).localBase, data) / BuildUnitPath
|
|
||||||
case Select(pr @ ProjectRef(uri, id)) => refTarget(pr, units(uri).defined(id).base, data)
|
|
||||||
case Select(pr) => error("Unresolved project reference (" + pr + ") in " + displayFull(scoped))
|
|
||||||
case This => error("Unresolved project reference (This) in " + displayFull(scoped))
|
|
||||||
}
|
|
||||||
|
|
||||||
def refTarget(ref: ResolvedReference, fallbackBase: File, data: Settings[Scope]): File =
|
|
||||||
refTarget(GlobalScope.copy(project = Select(ref)), fallbackBase, data)
|
|
||||||
def refTarget(scope: Scope, fallbackBase: File, data: Settings[Scope]): File =
|
|
||||||
(Keys.target in scope get data getOrElse outputDirectory(fallbackBase).asFile ) / StreamsDirectory
|
|
||||||
}
|
|
||||||
object BuildPaths
|
|
||||||
{
|
|
||||||
import Path._
|
|
||||||
|
|
||||||
def getGlobalBase(state: State): File =
|
|
||||||
getFileSetting(globalBaseDirectory, GlobalBaseProperty, defaultGlobalBase)(state)
|
|
||||||
|
|
||||||
def getStagingDirectory(state: State, globalBase: File): File =
|
|
||||||
getFileSetting(stagingDirectory, StagingProperty, defaultStaging(globalBase))(state)
|
|
||||||
|
|
||||||
def getGlobalPluginsDirectory(state: State, globalBase: File): File =
|
|
||||||
getFileSetting(globalPluginsDirectory, GlobalPluginsProperty, defaultGlobalPlugins(globalBase))(state)
|
|
||||||
|
|
||||||
def getGlobalSettingsDirectory(state: State, globalBase: File): File =
|
|
||||||
getFileSetting(globalSettingsDirectory, GlobalSettingsProperty, globalBase)(state)
|
|
||||||
|
|
||||||
def getFileSetting(stateKey: AttributeKey[File], property: String, default: File)(state: State): File =
|
|
||||||
state get stateKey orElse getFileProperty(property) getOrElse default
|
|
||||||
|
|
||||||
def getFileProperty(name: String): Option[File] = Option(System.getProperty(name)) flatMap { path =>
|
|
||||||
if(path.isEmpty) None else Some(new File(path))
|
|
||||||
}
|
|
||||||
|
|
||||||
def defaultGlobalBase = Path.userHome / ConfigDirectoryName
|
|
||||||
private[this] def defaultStaging(globalBase: File) = globalBase / "staging"
|
|
||||||
private[this] def defaultGlobalPlugins(globalBase: File) = globalBase / PluginsDirectoryName
|
|
||||||
|
|
||||||
def definitionSources(base: File): Seq[File] = (base * "*.scala").get
|
|
||||||
def configurationSources(base: File): Seq[File] = (base * (GlobFilter("*.sbt") - ".sbt")).get
|
|
||||||
def pluginDirectory(definitionBase: File) = definitionBase / PluginsDirectoryName
|
|
||||||
|
|
||||||
def evalOutputDirectory(base: File) = outputDirectory(base) / "config-classes"
|
|
||||||
def outputDirectory(base: File) = base / DefaultTargetName
|
|
||||||
def buildOutputDirectory(base: File, compilers: Compilers) = crossPath(outputDirectory(base), compilers.scalac.scalaInstance)
|
|
||||||
|
|
||||||
def projectStandard(base: File) = base / "project"
|
|
||||||
def projectHidden(base: File) = base / ConfigDirectoryName
|
|
||||||
def selectProjectDir(base: File, log: Logger) =
|
|
||||||
{
|
|
||||||
val a = projectHidden(base)
|
|
||||||
val b = projectStandard(base)
|
|
||||||
if(a.exists)
|
|
||||||
{
|
|
||||||
log.warn("Alternative project directory " + ConfigDirectoryName + " (" + a + ") has been deprecated since sbt 0.12.0.\n Please use the standard location: " + b)
|
|
||||||
a
|
|
||||||
}
|
|
||||||
else b
|
|
||||||
}
|
|
||||||
|
|
||||||
final val PluginsDirectoryName = "plugins"
|
|
||||||
final val DefaultTargetName = "target"
|
|
||||||
final val ConfigDirectoryName = ".sbt"
|
|
||||||
final val GlobalBaseProperty = "sbt.global.base"
|
|
||||||
final val StagingProperty = "sbt.global.staging"
|
|
||||||
final val GlobalPluginsProperty = "sbt.global.plugins"
|
|
||||||
final val GlobalSettingsProperty = "sbt.global.settings"
|
|
||||||
|
|
||||||
def crossPath(base: File, instance: xsbti.compile.ScalaInstance): File = base / ("scala_" + instance.version)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import Load.{BuildUnit, LoadBuildConfiguration, PartBuild}
|
|
||||||
import BuildLoader._
|
import BuildLoader._
|
||||||
import Alternatives._
|
import Alternatives._
|
||||||
import Types.{const,idFun}
|
import Types.{const,idFun}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2011 Mark Harrah
|
||||||
|
*/
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URI
|
||||||
|
import KeyRanks.DSetting
|
||||||
|
|
||||||
|
object BuildPaths
|
||||||
|
{
|
||||||
|
val globalBaseDirectory = AttributeKey[File]("global-base-directory", "The base directory for global sbt configuration and staging.", DSetting)
|
||||||
|
val globalPluginsDirectory = AttributeKey[File]("global-plugins-directory", "The base directory for global sbt plugins.", DSetting)
|
||||||
|
val globalSettingsDirectory = AttributeKey[File]("global-settings-directory", "The base directory for global sbt settings.", DSetting)
|
||||||
|
val stagingDirectory = AttributeKey[File]("staging-directory", "The directory for staging remote projects.", DSetting)
|
||||||
|
|
||||||
|
import Path._
|
||||||
|
|
||||||
|
def getGlobalBase(state: State): File =
|
||||||
|
getFileSetting(globalBaseDirectory, GlobalBaseProperty, defaultGlobalBase)(state)
|
||||||
|
|
||||||
|
def getStagingDirectory(state: State, globalBase: File): File =
|
||||||
|
getFileSetting(stagingDirectory, StagingProperty, defaultStaging(globalBase))(state)
|
||||||
|
|
||||||
|
def getGlobalPluginsDirectory(state: State, globalBase: File): File =
|
||||||
|
getFileSetting(globalPluginsDirectory, GlobalPluginsProperty, defaultGlobalPlugins(globalBase))(state)
|
||||||
|
|
||||||
|
def getGlobalSettingsDirectory(state: State, globalBase: File): File =
|
||||||
|
getFileSetting(globalSettingsDirectory, GlobalSettingsProperty, globalBase)(state)
|
||||||
|
|
||||||
|
def getFileSetting(stateKey: AttributeKey[File], property: String, default: File)(state: State): File =
|
||||||
|
state get stateKey orElse getFileProperty(property) getOrElse default
|
||||||
|
|
||||||
|
def getFileProperty(name: String): Option[File] = Option(System.getProperty(name)) flatMap { path =>
|
||||||
|
if(path.isEmpty) None else Some(new File(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
def defaultGlobalBase = Path.userHome / ConfigDirectoryName
|
||||||
|
private[this] def defaultStaging(globalBase: File) = globalBase / "staging"
|
||||||
|
private[this] def defaultGlobalPlugins(globalBase: File) = globalBase / PluginsDirectoryName
|
||||||
|
|
||||||
|
def definitionSources(base: File): Seq[File] = (base * "*.scala").get
|
||||||
|
def configurationSources(base: File): Seq[File] = (base * (GlobFilter("*.sbt") - ".sbt")).get
|
||||||
|
def pluginDirectory(definitionBase: File) = definitionBase / PluginsDirectoryName
|
||||||
|
|
||||||
|
def evalOutputDirectory(base: File) = outputDirectory(base) / "config-classes"
|
||||||
|
def outputDirectory(base: File) = base / DefaultTargetName
|
||||||
|
def buildOutputDirectory(base: File, scalaInstance: xsbti.compile.ScalaInstance) = crossPath(outputDirectory(base), scalaInstance)
|
||||||
|
|
||||||
|
def projectStandard(base: File) = base / "project"
|
||||||
|
def projectHidden(base: File) = base / ConfigDirectoryName
|
||||||
|
def selectProjectDir(base: File, log: Logger) =
|
||||||
|
{
|
||||||
|
val a = projectHidden(base)
|
||||||
|
val b = projectStandard(base)
|
||||||
|
if(a.exists)
|
||||||
|
{
|
||||||
|
log.warn("Alternative project directory " + ConfigDirectoryName + " (" + a + ") has been deprecated since sbt 0.12.0.\n Please use the standard location: " + b)
|
||||||
|
a
|
||||||
|
}
|
||||||
|
else b
|
||||||
|
}
|
||||||
|
|
||||||
|
final val PluginsDirectoryName = "plugins"
|
||||||
|
final val DefaultTargetName = "target"
|
||||||
|
final val ConfigDirectoryName = ".sbt"
|
||||||
|
final val GlobalBaseProperty = "sbt.global.base"
|
||||||
|
final val StagingProperty = "sbt.global.staging"
|
||||||
|
final val GlobalPluginsProperty = "sbt.global.plugins"
|
||||||
|
final val GlobalSettingsProperty = "sbt.global.settings"
|
||||||
|
|
||||||
|
def crossPath(base: File, instance: xsbti.compile.ScalaInstance): File = base / ("scala_" + instance.version)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2011 Mark Harrah
|
||||||
|
*/
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URI
|
||||||
|
import compiler.Eval
|
||||||
|
import inc.Locate
|
||||||
|
import Def.{displayFull, ScopedKey, ScopeLocal, Setting}
|
||||||
|
import Attributed.data
|
||||||
|
import BuildPaths.outputDirectory
|
||||||
|
import Scope.GlobalScope
|
||||||
|
import BuildStreams.Streams
|
||||||
|
import Path._
|
||||||
|
|
||||||
|
final class BuildStructure(val units: Map[URI, LoadedBuildUnit], val root: URI, val settings: Seq[Setting[_]], val data: Settings[Scope], val index: StructureIndex, val streams: State => Streams, val delegates: Scope => Seq[Scope], val scopeLocal: ScopeLocal)
|
||||||
|
{
|
||||||
|
val rootProject: URI => String = Load getRootProject units
|
||||||
|
def allProjects: Seq[ResolvedProject] = units.values.flatMap(_.defined.values).toSeq
|
||||||
|
def allProjects(build: URI): Seq[ResolvedProject] = units.get(build).toList.flatMap(_.defined.values)
|
||||||
|
def allProjectRefs: Seq[ProjectRef] = units.toSeq flatMap { case (build, unit) => refs(build, unit.defined.values.toSeq) }
|
||||||
|
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
|
||||||
|
val extra: BuildUtil[ResolvedProject] = BuildUtil(root, units, index.keyIndex, data)
|
||||||
|
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] = projects.map { p => ProjectRef(build, p.id) }
|
||||||
|
}
|
||||||
|
// information that is not original, but can be reconstructed from the rest of BuildStructure
|
||||||
|
final class StructureIndex(
|
||||||
|
val keyMap: Map[String, AttributeKey[_]],
|
||||||
|
val taskToKey: Map[Task[_], ScopedKey[Task[_]]],
|
||||||
|
val triggers: Triggers[Task],
|
||||||
|
val keyIndex: KeyIndex,
|
||||||
|
val aggregateKeyIndex: KeyIndex
|
||||||
|
)
|
||||||
|
final class LoadedBuildUnit(val unit: BuildUnit, val defined: Map[String, ResolvedProject], val rootProjects: Seq[String], val buildSettings: Seq[Setting[_]]) extends BuildUnitBase
|
||||||
|
{
|
||||||
|
assert(!rootProjects.isEmpty, "No root projects defined for build unit " + unit)
|
||||||
|
val root = rootProjects.head
|
||||||
|
def localBase = unit.localBase
|
||||||
|
def classpath: Seq[File] = unit.definitions.target ++ unit.plugins.classpath
|
||||||
|
def loader = unit.definitions.loader
|
||||||
|
def imports = BuildUtil.getImports(unit)
|
||||||
|
override def toString = unit.toString
|
||||||
|
}
|
||||||
|
|
||||||
|
final class LoadedDefinitions(val base: File, val target: Seq[File], val loader: ClassLoader, val builds: Seq[Build], val buildNames: Seq[String])
|
||||||
|
final class LoadedPlugins(val base: File, val pluginData: PluginData, val loader: ClassLoader, val plugins: Seq[Plugin], val pluginNames: Seq[String])
|
||||||
|
{
|
||||||
|
def fullClasspath: Seq[Attributed[File]] = pluginData.classpath
|
||||||
|
def classpath = data(fullClasspath)
|
||||||
|
}
|
||||||
|
final class BuildUnit(val uri: URI, val localBase: File, val definitions: LoadedDefinitions, val plugins: LoadedPlugins)
|
||||||
|
{
|
||||||
|
override def toString = if(uri.getScheme == "file") localBase.toString else (uri + " (locally: " + localBase +")")
|
||||||
|
}
|
||||||
|
|
||||||
|
final class LoadedBuild(val root: URI, val units: Map[URI, LoadedBuildUnit])
|
||||||
|
{
|
||||||
|
BuildUtil.checkCycles(units)
|
||||||
|
def allProjectRefs: Seq[(ProjectRef, ResolvedProject)] = for( (uri, unit) <- units.toSeq; (id, proj) <- unit.defined ) yield ProjectRef(uri, id) -> proj
|
||||||
|
def extra(data: Settings[Scope])(keyIndex: KeyIndex): BuildUtil[ResolvedProject] = BuildUtil(root, units, keyIndex, data)
|
||||||
|
}
|
||||||
|
final class PartBuild(val root: URI, val units: Map[URI, PartBuildUnit])
|
||||||
|
sealed trait BuildUnitBase { def rootProjects: Seq[String]; def buildSettings: Seq[Setting[_]] }
|
||||||
|
final class PartBuildUnit(val unit: BuildUnit, val defined: Map[String, Project], val rootProjects: Seq[String], val buildSettings: Seq[Setting[_]]) extends BuildUnitBase
|
||||||
|
{
|
||||||
|
def resolve(f: Project => ResolvedProject): LoadedBuildUnit = new LoadedBuildUnit(unit, defined mapValues f toMap, rootProjects, buildSettings)
|
||||||
|
def resolveRefs(f: ProjectReference => ProjectRef): LoadedBuildUnit = resolve(_ resolve f)
|
||||||
|
}
|
||||||
|
|
||||||
|
object BuildStreams
|
||||||
|
{
|
||||||
|
type Streams = std.Streams[ScopedKey[_]]
|
||||||
|
|
||||||
|
final val GlobalPath = "$global"
|
||||||
|
final val BuildUnitPath = "$build"
|
||||||
|
final val StreamsDirectory = "streams"
|
||||||
|
|
||||||
|
def mkStreams(units: Map[URI, LoadedBuildUnit], root: URI, data: Settings[Scope]): State => Streams = s =>
|
||||||
|
std.Streams( path(units, root, data), displayFull, LogManager.construct(data, s) )
|
||||||
|
|
||||||
|
def path(units: Map[URI, LoadedBuildUnit], root: URI, data: Settings[Scope])(scoped: ScopedKey[_]): File =
|
||||||
|
resolvePath( projectPath(units, root, scoped, data), nonProjectPath(scoped) )
|
||||||
|
|
||||||
|
def resolvePath(base: File, components: Seq[String]): File =
|
||||||
|
(base /: components)( (b,p) => new File(b,p) )
|
||||||
|
|
||||||
|
def pathComponent[T](axis: ScopeAxis[T], scoped: ScopedKey[_], label: String)(show: T => String): String =
|
||||||
|
axis match
|
||||||
|
{
|
||||||
|
case Global => GlobalPath
|
||||||
|
case This => error("Unresolved This reference for " + label + " in " + displayFull(scoped))
|
||||||
|
case Select(t) => show(t)
|
||||||
|
}
|
||||||
|
def nonProjectPath[T](scoped: ScopedKey[T]): Seq[String] =
|
||||||
|
{
|
||||||
|
val scope = scoped.scope
|
||||||
|
pathComponent(scope.config, scoped, "config")(_.name) ::
|
||||||
|
pathComponent(scope.task, scoped, "task")(_.label) ::
|
||||||
|
pathComponent(scope.extra, scoped, "extra")(showAMap) ::
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
def showAMap(a: AttributeMap): String =
|
||||||
|
a.entries.toSeq.sortBy(_.key.label).map { case AttributeEntry(key, value) => key.label + "=" + value.toString } mkString(" ")
|
||||||
|
def projectPath(units: Map[URI, LoadedBuildUnit], root: URI, scoped: ScopedKey[_], data: Settings[Scope]): File =
|
||||||
|
scoped.scope.project match
|
||||||
|
{
|
||||||
|
case Global => refTarget(GlobalScope, units(root).localBase, data) / GlobalPath
|
||||||
|
case Select(br @ BuildRef(uri)) => refTarget(br, units(uri).localBase, data) / BuildUnitPath
|
||||||
|
case Select(pr @ ProjectRef(uri, id)) => refTarget(pr, units(uri).defined(id).base, data)
|
||||||
|
case Select(pr) => error("Unresolved project reference (" + pr + ") in " + displayFull(scoped))
|
||||||
|
case This => error("Unresolved project reference (This) in " + displayFull(scoped))
|
||||||
|
}
|
||||||
|
|
||||||
|
def refTarget(ref: ResolvedReference, fallbackBase: File, data: Settings[Scope]): File =
|
||||||
|
refTarget(GlobalScope.copy(project = Select(ref)), fallbackBase, data)
|
||||||
|
def refTarget(scope: Scope, fallbackBase: File, data: Settings[Scope]): File =
|
||||||
|
(Keys.target in scope get data getOrElse outputDirectory(fallbackBase).asFile ) / StreamsDirectory
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
final class BuildUtil[Proj](
|
final class BuildUtil[Proj](
|
||||||
val keyIndex: KeyIndex,
|
val keyIndex: KeyIndex,
|
||||||
|
|
@ -37,4 +37,44 @@ final class BuildUtil[Proj](
|
||||||
|
|
||||||
val configurationsForAxis: Option[ResolvedReference] => Seq[String] =
|
val configurationsForAxis: Option[ResolvedReference] => Seq[String] =
|
||||||
refOpt => configurations(projectForAxis(refOpt)).map(_.name)
|
refOpt => configurations(projectForAxis(refOpt)).map(_.name)
|
||||||
|
}
|
||||||
|
object BuildUtil
|
||||||
|
{
|
||||||
|
def apply(root: URI, units: Map[URI, LoadedBuildUnit], keyIndex: KeyIndex, data: Settings[Scope]): BuildUtil[ResolvedProject] =
|
||||||
|
{
|
||||||
|
val getp = (build: URI, project: String) => Load.getProject(units, build, project)
|
||||||
|
val configs = (_: ResolvedProject).configurations.map(c => ConfigKey(c.name))
|
||||||
|
val aggregates = aggregationRelation(units)
|
||||||
|
new BuildUtil(keyIndex, data, root, Load getRootProject units, getp, configs, aggregates)
|
||||||
|
}
|
||||||
|
|
||||||
|
def checkCycles(units: Map[URI, LoadedBuildUnit])
|
||||||
|
{
|
||||||
|
def getRef(pref: ProjectRef) = units(pref.build).defined(pref.project)
|
||||||
|
def deps(proj: ResolvedProject)(base: ResolvedProject => Seq[ProjectRef]): Seq[ResolvedProject] = Dag.topologicalSort(proj)(p => base(p) map getRef)
|
||||||
|
// check for cycles
|
||||||
|
for( (_, lbu) <- units; proj <- lbu.defined.values) {
|
||||||
|
deps(proj)(_.dependencies.map(_.project))
|
||||||
|
deps(proj)(_.delegates)
|
||||||
|
deps(proj)(_.aggregate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def baseImports = "import sbt._, Process._, Keys._" :: Nil
|
||||||
|
def getImports(unit: BuildUnit) = baseImports ++ importAllRoot(unit.plugins.pluginNames ++ unit.definitions.buildNames)
|
||||||
|
def importAll(values: Seq[String]) = if(values.isEmpty) Nil else values.map( _ + "._" ).mkString("import ", ", ", "") :: Nil
|
||||||
|
def importAllRoot(values: Seq[String]) = importAll(values map rootedName)
|
||||||
|
def rootedName(s: String) = if(s contains '.') "_root_." + s else s
|
||||||
|
|
||||||
|
def aggregationRelation(units: Map[URI, LoadedBuildUnit]): Relation[ProjectRef, ProjectRef] =
|
||||||
|
{
|
||||||
|
val depPairs =
|
||||||
|
for {
|
||||||
|
(uri, unit) <- units.toIterable
|
||||||
|
project <- unit.defined.values
|
||||||
|
ref = ProjectRef(uri, project.id)
|
||||||
|
agg <- project.aggregate
|
||||||
|
} yield
|
||||||
|
(ref, agg)
|
||||||
|
Relation.empty ++ depPairs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ package sbt
|
||||||
import Keys._
|
import Keys._
|
||||||
import complete.{DefaultParsers, Parser}
|
import complete.{DefaultParsers, Parser}
|
||||||
import DefaultParsers._
|
import DefaultParsers._
|
||||||
import Project.{ScopedKey, Setting}
|
import Def.{ScopedKey, Setting}
|
||||||
import Scope.GlobalScope
|
import Scope.GlobalScope
|
||||||
|
|
||||||
object Cross
|
object Cross
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ package sbt
|
||||||
import Scope.{fillTaskAxis, GlobalScope, ThisScope}
|
import Scope.{fillTaskAxis, GlobalScope, ThisScope}
|
||||||
import xsbt.api.Discovery
|
import xsbt.api.Discovery
|
||||||
import xsbti.compile.CompileOrder
|
import xsbti.compile.CompileOrder
|
||||||
import Project.{inConfig, Initialize, inScope, inTask, ScopedKey, Setting, SettingsDefinition}
|
import Project.{inConfig, inScope, inTask, richInitialize, richInitializeTask, richTaskSessionVar}
|
||||||
import Load.LoadedBuild
|
import Def.{Initialize, ScopedKey, Setting, SettingsDefinition}
|
||||||
import Artifact.{DocClassifier, SourceClassifier}
|
import Artifact.{DocClassifier, SourceClassifier}
|
||||||
import Configurations.{Compile, CompilerPlugin, IntegrationTest, names, Provided, Runtime, Test}
|
import Configurations.{Compile, CompilerPlugin, IntegrationTest, names, Provided, Runtime, Test}
|
||||||
import CrossVersion.{binarySbtVersion, binaryScalaVersion}
|
import CrossVersion.{binarySbtVersion, binaryScalaVersion}
|
||||||
|
|
@ -263,7 +263,7 @@ object Defaults extends BuildCommon
|
||||||
override def watchPaths(s: State) = EvaluateTask.evaluateTask(Project structure s, key, s, base) match {
|
override def watchPaths(s: State) = EvaluateTask.evaluateTask(Project structure s, key, s, base) match {
|
||||||
case Some(Value(ps)) => ps
|
case Some(Value(ps)) => ps
|
||||||
case Some(Inc(i)) => throw i
|
case Some(Inc(i)) => throw i
|
||||||
case None => error("key not found: " + Project.displayFull(key))
|
case None => error("key not found: " + Def.displayFull(key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -657,7 +657,7 @@ object Defaults extends BuildCommon
|
||||||
forDependencies[T,T](ref => (key in ref) ?? default(ref), includeRoot, classpath, aggregate)
|
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]] =
|
def forDependencies[T,V](init: ProjectRef => Initialize[V], includeRoot: Boolean = true, classpath: Boolean = true, aggregate: Boolean = false): Initialize[Seq[V]] =
|
||||||
Project.bind( (loadedBuild, thisProjectRef).identity ) { case (lb, base) =>
|
Def.bind( (loadedBuild, thisProjectRef).identity ) { case (lb, base) =>
|
||||||
transitiveDependencies(base, lb, includeRoot, classpath, aggregate) map init join ;
|
transitiveDependencies(base, lb, includeRoot, classpath, aggregate) map init join ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -773,7 +773,7 @@ object Classpaths
|
||||||
)
|
)
|
||||||
val baseSettings: Seq[Setting[_]] = sbtClassifiersTasks ++ Seq(
|
val baseSettings: Seq[Setting[_]] = sbtClassifiersTasks ++ Seq(
|
||||||
conflictWarning in GlobalScope :== ConflictWarning.default("global"),
|
conflictWarning in GlobalScope :== ConflictWarning.default("global"),
|
||||||
conflictWarning <<= (thisProjectRef, conflictWarning) { (ref, cw) => cw.copy(label = Project.display(ref)) },
|
conflictWarning <<= (thisProjectRef, conflictWarning) { (ref, cw) => cw.copy(label = Reference.display(ref)) },
|
||||||
unmanagedBase <<= baseDirectory / "lib",
|
unmanagedBase <<= baseDirectory / "lib",
|
||||||
normalizedName <<= name(StringUtilities.normalize),
|
normalizedName <<= name(StringUtilities.normalize),
|
||||||
isSnapshot <<= isSnapshot or version(_ endsWith "-SNAPSHOT"),
|
isSnapshot <<= isSnapshot or version(_ endsWith "-SNAPSHOT"),
|
||||||
|
|
@ -859,7 +859,7 @@ object Classpaths
|
||||||
(module, ref, config, cacheDirectory, si, reports, roots, resolved, skip, s) =>
|
(module, ref, config, cacheDirectory, si, reports, roots, resolved, skip, s) =>
|
||||||
val depsUpdated = reports.exists(!_.stats.cached)
|
val depsUpdated = reports.exists(!_.stats.cached)
|
||||||
val isRoot = roots contains resolved
|
val isRoot = roots contains resolved
|
||||||
cachedUpdate(cacheDirectory / "update", Project.display(ref), module, config, Some(si), skip = skip, force = isRoot, depsUpdated = depsUpdated, log = s.log)
|
cachedUpdate(cacheDirectory / "update", Reference.display(ref), module, config, Some(si), skip = skip, force = isRoot, depsUpdated = depsUpdated, log = s.log)
|
||||||
} tag(Tags.Update, Tags.Network),
|
} tag(Tags.Update, Tags.Network),
|
||||||
update <<= (conflictWarning, update, streams) map { (config, report, s) => ConflictWarning(config, report, s.log); report },
|
update <<= (conflictWarning, update, streams) map { (config, report, s) => ConflictWarning(config, report, s.log); report },
|
||||||
transitiveClassifiers in GlobalScope :== Seq(SourceClassifier, DocClassifier),
|
transitiveClassifiers in GlobalScope :== Seq(SourceClassifier, DocClassifier),
|
||||||
|
|
@ -1277,12 +1277,12 @@ trait BuildExtra extends BuildCommon
|
||||||
seq( artLocal <<= artifact, taskLocal <<= taskDef, art, pkgd )
|
seq( artLocal <<= artifact, taskLocal <<= taskDef, art, pkgd )
|
||||||
}
|
}
|
||||||
|
|
||||||
def seq(settings: Setting[_]*): SettingsDefinition = new Project.SettingList(settings)
|
def seq(settings: Setting[_]*): SettingsDefinition = new Def.SettingList(settings)
|
||||||
|
|
||||||
def externalIvySettings(file: Initialize[File] = baseDirectory / "ivysettings.xml", addMultiResolver: Boolean = true): Setting[Task[IvyConfiguration]] =
|
def externalIvySettings(file: Initialize[File] = baseDirectory / "ivysettings.xml", addMultiResolver: Boolean = true): Setting[Task[IvyConfiguration]] =
|
||||||
externalIvySettingsURI(file(_.toURI), addMultiResolver)
|
externalIvySettingsURI(file(_.toURI), addMultiResolver)
|
||||||
def externalIvySettingsURL(url: URL, addMultiResolver: Boolean = true): Setting[Task[IvyConfiguration]] =
|
def externalIvySettingsURL(url: URL, addMultiResolver: Boolean = true): Setting[Task[IvyConfiguration]] =
|
||||||
externalIvySettingsURI(Project.value(url.toURI), addMultiResolver)
|
externalIvySettingsURI(Def.value(url.toURI), addMultiResolver)
|
||||||
def externalIvySettingsURI(uri: Initialize[URI], addMultiResolver: Boolean = true): Setting[Task[IvyConfiguration]] =
|
def externalIvySettingsURI(uri: Initialize[URI], addMultiResolver: Boolean = true): Setting[Task[IvyConfiguration]] =
|
||||||
{
|
{
|
||||||
val other = (baseDirectory, appConfiguration, projectResolver, streams).identityMap
|
val other = (baseDirectory, appConfiguration, projectResolver, streams).identityMap
|
||||||
|
|
@ -1375,12 +1375,12 @@ trait BuildCommon
|
||||||
|
|
||||||
// intended for use in constructing InputTasks
|
// intended for use in constructing InputTasks
|
||||||
def loadForParser[P,T](task: TaskKey[T])(f: (State, Option[T]) => Parser[P])(implicit format: sbinary.Format[T]): Initialize[State => Parser[P]] =
|
def loadForParser[P,T](task: TaskKey[T])(f: (State, Option[T]) => Parser[P])(implicit format: sbinary.Format[T]): Initialize[State => Parser[P]] =
|
||||||
loadForParserI(task)(Project value f)(format)
|
loadForParserI(task)(Def value f)(format)
|
||||||
def loadForParserI[P,T](task: TaskKey[T])(init: Initialize[(State, Option[T]) => Parser[P]])(implicit format: sbinary.Format[T]): Initialize[State => Parser[P]] =
|
def loadForParserI[P,T](task: TaskKey[T])(init: Initialize[(State, Option[T]) => Parser[P]])(implicit format: sbinary.Format[T]): Initialize[State => Parser[P]] =
|
||||||
(resolvedScoped, init)( (ctx, f) => (s: State) => f( s, loadFromContext(task, ctx, s)(format)) )
|
(resolvedScoped, init)( (ctx, f) => (s: State) => f( s, loadFromContext(task, ctx, s)(format)) )
|
||||||
|
|
||||||
def getForParser[P,T](task: TaskKey[T])(init: (State, Option[T]) => Parser[P]): Initialize[State => Parser[P]] =
|
def getForParser[P,T](task: TaskKey[T])(init: (State, Option[T]) => Parser[P]): Initialize[State => Parser[P]] =
|
||||||
getForParserI(task)(Project value init)
|
getForParserI(task)(Def value init)
|
||||||
def getForParserI[P,T](task: TaskKey[T])(init: Initialize[(State, Option[T]) => Parser[P]]): Initialize[State => Parser[P]] =
|
def getForParserI[P,T](task: TaskKey[T])(init: Initialize[(State, Option[T]) => Parser[P]]): Initialize[State => Parser[P]] =
|
||||||
(resolvedScoped, init)( (ctx, f) => (s: State) => f(s, getFromContext(task, ctx, s)) )
|
(resolvedScoped, init)( (ctx, f) => (s: State) => f(s, getFromContext(task, ctx, s)) )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2011 Mark Harrah
|
||||||
|
*/
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URI
|
||||||
|
import compiler.{Eval, EvalImports}
|
||||||
|
import complete.DefaultParsers.validID
|
||||||
|
import Def.{ScopedKey, Setting, SettingsDefinition}
|
||||||
|
import Scope.GlobalScope
|
||||||
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
|
object EvaluateConfigurations
|
||||||
|
{
|
||||||
|
private[this] final class ParsedFile(val imports: Seq[(String,Int)], val definitions: Seq[(String,LineRange)], val settings: Seq[(String,LineRange)])
|
||||||
|
private[this] final class Definitions(val loader: ClassLoader => ClassLoader, val moduleNames: Seq[String])
|
||||||
|
|
||||||
|
private[this] val DefinitionKeywords = Seq("lazy val ", "def ", "val ")
|
||||||
|
|
||||||
|
def apply(eval: Eval, srcs: Seq[File], imports: Seq[String]): ClassLoader => Seq[Setting[_]] =
|
||||||
|
flatten(srcs.sortBy(_.getName) map { src => evaluateConfiguration(eval, src, imports) })
|
||||||
|
def evaluateConfiguration(eval: Eval, src: File, imports: Seq[String]): ClassLoader => Seq[Setting[_]] =
|
||||||
|
evaluateConfiguration(eval, src.getPath, IO.readLines(src), imports, 0)
|
||||||
|
|
||||||
|
private[this] def parseConfiguration(lines: Seq[String], builtinImports: Seq[String], offset: Int): ParsedFile =
|
||||||
|
{
|
||||||
|
val (importStatements, settingsAndDefinitions) = splitExpressions(lines)
|
||||||
|
val allImports = builtinImports.map(s => (s, -1)) ++ addOffset(offset, importStatements)
|
||||||
|
val (definitions, settings) = splitSettingsDefinitions(addOffsetToRange(offset, settingsAndDefinitions))
|
||||||
|
new ParsedFile(allImports, definitions, settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
def evaluateConfiguration(eval: Eval, name: String, lines: Seq[String], imports: Seq[String], offset: Int): ClassLoader => Seq[Setting[_]] =
|
||||||
|
{
|
||||||
|
val parsed = parseConfiguration(lines, imports, offset)
|
||||||
|
val importDefs = if(parsed.definitions.isEmpty) Nil else {
|
||||||
|
val definitions = evaluateDefinitions(eval, name, parsed.imports, parsed.definitions)
|
||||||
|
Load.importAllRoot(definitions.moduleNames).map(s => (s, -1))
|
||||||
|
}
|
||||||
|
val allImports = importDefs ++ parsed.imports
|
||||||
|
val settings = parsed.settings map { case (settingExpression,range) =>
|
||||||
|
evaluateSetting(eval, name, allImports, settingExpression, range)
|
||||||
|
}
|
||||||
|
eval.unlinkDeferred()
|
||||||
|
flatten(settings)
|
||||||
|
}
|
||||||
|
def flatten(mksettings: Seq[ClassLoader => Seq[Setting[_]]]): ClassLoader => Seq[Setting[_]] =
|
||||||
|
loader => mksettings.flatMap(_ apply loader)
|
||||||
|
def addOffset(offset: Int, lines: Seq[(String,Int)]): Seq[(String,Int)] =
|
||||||
|
lines.map { case (s, i) => (s, i + offset) }
|
||||||
|
def addOffsetToRange(offset: Int, ranges: Seq[(String,LineRange)]): Seq[(String,LineRange)] =
|
||||||
|
ranges.map { case (s, r) => (s, r shift offset) }
|
||||||
|
|
||||||
|
val SettingsDefinitionName = classOf[SettingsDefinition].getName
|
||||||
|
def evaluateSetting(eval: Eval, name: String, imports: Seq[(String,Int)], expression: String, range: LineRange): ClassLoader => Seq[Setting[_]] =
|
||||||
|
{
|
||||||
|
val result = try {
|
||||||
|
eval.eval(expression, imports = new EvalImports(imports, name), srcName = name, tpeName = Some(SettingsDefinitionName), line = range.start)
|
||||||
|
} catch {
|
||||||
|
case e: sbt.compiler.EvalException => throw new MessageOnlyException(e.getMessage)
|
||||||
|
}
|
||||||
|
loader => {
|
||||||
|
val pos = RangePosition(name, range shift 1)
|
||||||
|
result.getValue(loader).asInstanceOf[SettingsDefinition].settings map (_ withPos pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private[this] def isSpace = (c: Char) => Character isWhitespace c
|
||||||
|
private[this] def fstS(f: String => Boolean): ((String,Int)) => Boolean = { case (s,i) => f(s) }
|
||||||
|
private[this] def firstNonSpaceIs(lit: String) = (_: String).view.dropWhile(isSpace).startsWith(lit)
|
||||||
|
private[this] def or[A](a: A => Boolean, b: A => Boolean): A => Boolean = in => a(in) || b(in)
|
||||||
|
def splitExpressions(lines: Seq[String]): (Seq[(String,Int)], Seq[(String,LineRange)]) =
|
||||||
|
{
|
||||||
|
val blank = (_: String).forall(isSpace)
|
||||||
|
val isImport = firstNonSpaceIs("import ")
|
||||||
|
val comment = firstNonSpaceIs("//")
|
||||||
|
val blankOrComment = or(blank, comment)
|
||||||
|
val importOrBlank = fstS(or(blankOrComment, isImport))
|
||||||
|
|
||||||
|
val (imports, settings) = lines.zipWithIndex span importOrBlank
|
||||||
|
(imports filterNot fstS( blankOrComment ), groupedLines(settings, blank, blankOrComment))
|
||||||
|
}
|
||||||
|
def groupedLines(lines: Seq[(String,Int)], delimiter: String => Boolean, skipInitial: String => Boolean): Seq[(String,LineRange)] =
|
||||||
|
{
|
||||||
|
val fdelim = fstS(delimiter)
|
||||||
|
@tailrec def group0(lines: Seq[(String,Int)], accum: Seq[(String,LineRange)]): Seq[(String,LineRange)] =
|
||||||
|
if(lines.isEmpty) accum.reverse
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val start = lines dropWhile fstS( skipInitial )
|
||||||
|
val (next, tail) = start.span { case (s,_) => !delimiter(s) }
|
||||||
|
val grouped = if(next.isEmpty) accum else (next.map(_._1).mkString("\n"), LineRange(next.head._2, next.last._2 + 1)) +: accum
|
||||||
|
group0(tail, grouped)
|
||||||
|
}
|
||||||
|
group0(lines, Nil)
|
||||||
|
}
|
||||||
|
private[this] def splitSettingsDefinitions(lines: Seq[(String,LineRange)]): (Seq[(String,LineRange)], Seq[(String,LineRange)]) =
|
||||||
|
lines partition { case (line, range) => isDefinition(line) }
|
||||||
|
private[this] def isDefinition(line: String): Boolean =
|
||||||
|
{
|
||||||
|
val trimmed = line.trim
|
||||||
|
DefinitionKeywords.exists(trimmed startsWith _)
|
||||||
|
}
|
||||||
|
private[this] def evaluateDefinitions(eval: Eval, name: String, imports: Seq[(String,Int)], definitions: Seq[(String,LineRange)]): Definitions =
|
||||||
|
{
|
||||||
|
val convertedRanges = definitions.map { case (s, r) => (s, r.start to r.end) }
|
||||||
|
val res = eval.evalDefinitions(convertedRanges, new EvalImports(imports, name), name)
|
||||||
|
new Definitions(loader => res.getValue(loader).getClass.getClassLoader, res.enclosingModule :: Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object Index
|
||||||
|
{
|
||||||
|
def taskToKeyMap(data: Settings[Scope]): Map[Task[_], ScopedKey[Task[_]]] =
|
||||||
|
{
|
||||||
|
// AttributeEntry + the checked type test 'value: Task[_]' ensures that the cast is correct.
|
||||||
|
// (scalac couldn't determine that 'key' is of type AttributeKey[Task[_]] on its own and a type match still required the cast)
|
||||||
|
val pairs = for( scope <- data.scopes; AttributeEntry(key, value: Task[_]) <- data.data(scope).entries ) yield
|
||||||
|
(value, ScopedKey(scope, key.asInstanceOf[AttributeKey[Task[_]]])) // unclear why this cast is needed even with a type test in the above filter
|
||||||
|
pairs.toMap[Task[_], ScopedKey[Task[_]]]
|
||||||
|
}
|
||||||
|
def allKeys(settings: Seq[Setting[_]]): Set[ScopedKey[_]] =
|
||||||
|
settings.flatMap(s => if(s.key.key.isLocal) Nil else s.key +: s.dependencies).filter(!_.key.isLocal).toSet
|
||||||
|
def attributeKeys(settings: Settings[Scope]): Set[AttributeKey[_]] =
|
||||||
|
settings.data.values.flatMap(_.keys).toSet[AttributeKey[_]]
|
||||||
|
def stringToKeyMap(settings: Set[AttributeKey[_]]): Map[String, AttributeKey[_]] =
|
||||||
|
{
|
||||||
|
val multiMap = settings.groupBy(_.label)
|
||||||
|
val duplicates = multiMap collect { case (k, xs) if xs.size > 1 => (k, xs.map(_.manifest)) } collect { case (k, xs) if xs.size > 1 => (k, xs) }
|
||||||
|
if(duplicates.isEmpty)
|
||||||
|
multiMap.collect { case (k, v) if validID(k) => (k, v.head) } toMap;
|
||||||
|
else
|
||||||
|
error(duplicates map { case (k, tps) => "'" + k + "' (" + tps.mkString(", ") + ")" } mkString("AttributeKey ID collisions detected for: ", ", ", ""))
|
||||||
|
}
|
||||||
|
private[this] type TriggerMap = collection.mutable.HashMap[Task[_], Seq[Task[_]]]
|
||||||
|
def triggers(ss: Settings[Scope]): Triggers[Task] =
|
||||||
|
{
|
||||||
|
val runBefore = new TriggerMap
|
||||||
|
val triggeredBy = new TriggerMap
|
||||||
|
for( (_, amap) <- ss.data; AttributeEntry(_, value: Task[_]) <- amap.entries)
|
||||||
|
{
|
||||||
|
val as = value.info.attributes
|
||||||
|
update(runBefore, value, as get Keys.runBefore)
|
||||||
|
update(triggeredBy, value, as get Keys.triggeredBy)
|
||||||
|
}
|
||||||
|
val onComplete = Keys.onComplete in GlobalScope get ss getOrElse { () => () }
|
||||||
|
new Triggers[Task](runBefore, triggeredBy, map => { onComplete(); map } )
|
||||||
|
}
|
||||||
|
private[this] def update(map: TriggerMap, base: Task[_], tasksOpt: Option[Seq[Task[_]]]): Unit =
|
||||||
|
for( tasks <- tasksOpt; task <- tasks )
|
||||||
|
map(task) = base +: map.getOrElse(task, Nil)
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,10 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Project.{ScopedKey, Setting}
|
import Def.{displayFull, ScopedKey, Setting}
|
||||||
import Keys.{streams, Streams, TaskStreams}
|
import Keys.{streams, Streams, TaskStreams}
|
||||||
import Keys.{dummyRoots, dummyState, dummyStreamsManager, executionRoots, pluginData, streamsManager, taskDefinitionKey, transformState}
|
import Keys.{dummyRoots, dummyState, dummyStreamsManager, executionRoots, pluginData, streamsManager, taskDefinitionKey, transformState}
|
||||||
|
import Project.richInitializeTask
|
||||||
import Scope.{GlobalScope, ThisScope}
|
import Scope.{GlobalScope, ThisScope}
|
||||||
import Types.const
|
import Types.const
|
||||||
import scala.Console.RED
|
import scala.Console.RED
|
||||||
|
|
@ -25,8 +26,6 @@ object PluginData
|
||||||
|
|
||||||
object EvaluateTask
|
object EvaluateTask
|
||||||
{
|
{
|
||||||
import Load.BuildStructure
|
|
||||||
import Project.display
|
|
||||||
import std.{TaskExtra,Transform}
|
import std.{TaskExtra,Transform}
|
||||||
import TaskExtra._
|
import TaskExtra._
|
||||||
import Keys.state
|
import Keys.state
|
||||||
|
|
@ -34,7 +33,7 @@ object EvaluateTask
|
||||||
val SystemProcessors = Runtime.getRuntime.availableProcessors
|
val SystemProcessors = Runtime.getRuntime.availableProcessors
|
||||||
def defaultConfig(state: State): EvaluateConfig =
|
def defaultConfig(state: State): EvaluateConfig =
|
||||||
EvaluateConfig(false, restrictions(state))
|
EvaluateConfig(false, restrictions(state))
|
||||||
def defaultConfig(extracted: Extracted, structure: Load.BuildStructure) =
|
def defaultConfig(extracted: Extracted, structure: BuildStructure) =
|
||||||
EvaluateConfig(false, restrictions(extracted, structure))
|
EvaluateConfig(false, restrictions(extracted, structure))
|
||||||
|
|
||||||
def extractedConfig(extracted: Extracted, structure: BuildStructure): EvaluateConfig =
|
def extractedConfig(extracted: Extracted, structure: BuildStructure): EvaluateConfig =
|
||||||
|
|
@ -45,7 +44,7 @@ object EvaluateTask
|
||||||
}
|
}
|
||||||
|
|
||||||
def defaultRestrictions(maxWorkers: Int) = Tags.limitAll(maxWorkers) :: Nil
|
def defaultRestrictions(maxWorkers: Int) = Tags.limitAll(maxWorkers) :: Nil
|
||||||
def defaultRestrictions(extracted: Extracted, structure: Load.BuildStructure): Seq[Tags.Rule] =
|
def defaultRestrictions(extracted: Extracted, structure: BuildStructure): Seq[Tags.Rule] =
|
||||||
Tags.limitAll(maxWorkers(extracted, structure)) :: Nil
|
Tags.limitAll(maxWorkers(extracted, structure)) :: Nil
|
||||||
|
|
||||||
def restrictions(state: State): Seq[Tags.Rule] =
|
def restrictions(state: State): Seq[Tags.Rule] =
|
||||||
|
|
@ -53,16 +52,16 @@ object EvaluateTask
|
||||||
val extracted = Project.extract(state)
|
val extracted = Project.extract(state)
|
||||||
restrictions(extracted, extracted.structure)
|
restrictions(extracted, extracted.structure)
|
||||||
}
|
}
|
||||||
def restrictions(extracted: Extracted, structure: Load.BuildStructure): Seq[Tags.Rule] =
|
def restrictions(extracted: Extracted, structure: BuildStructure): Seq[Tags.Rule] =
|
||||||
getSetting(Keys.concurrentRestrictions, defaultRestrictions(extracted, structure), extracted, structure)
|
getSetting(Keys.concurrentRestrictions, defaultRestrictions(extracted, structure), extracted, structure)
|
||||||
def maxWorkers(extracted: Extracted, structure: Load.BuildStructure): Int =
|
def maxWorkers(extracted: Extracted, structure: BuildStructure): Int =
|
||||||
if(getSetting(Keys.parallelExecution, true, extracted, structure))
|
if(getSetting(Keys.parallelExecution, true, extracted, structure))
|
||||||
SystemProcessors
|
SystemProcessors
|
||||||
else
|
else
|
||||||
1
|
1
|
||||||
def cancelable(extracted: Extracted, structure: Load.BuildStructure): Boolean =
|
def cancelable(extracted: Extracted, structure: BuildStructure): Boolean =
|
||||||
getSetting(Keys.cancelable, false, extracted, structure)
|
getSetting(Keys.cancelable, false, extracted, structure)
|
||||||
def getSetting[T](key: SettingKey[T], default: T, extracted: Extracted, structure: Load.BuildStructure): T =
|
def getSetting[T](key: SettingKey[T], default: T, extracted: Extracted, structure: BuildStructure): T =
|
||||||
key in extracted.currentRef get structure.data getOrElse default
|
key in extracted.currentRef get structure.data getOrElse default
|
||||||
|
|
||||||
def injectSettings: Seq[Setting[_]] = Seq(
|
def injectSettings: Seq[Setting[_]] = Seq(
|
||||||
|
|
@ -97,7 +96,7 @@ object EvaluateTask
|
||||||
def logIncomplete(result: Incomplete, state: State, streams: Streams)
|
def logIncomplete(result: Incomplete, state: State, streams: Streams)
|
||||||
{
|
{
|
||||||
val all = Incomplete linearize result
|
val all = Incomplete linearize result
|
||||||
val keyed = for(Incomplete(Some(key: Project.ScopedKey[_]), _, msg, _, ex) <- all) yield (key, msg, ex)
|
val keyed = for(Incomplete(Some(key: ScopedKey[_]), _, msg, _, ex) <- all) yield (key, msg, ex)
|
||||||
val un = all.filter { i => i.node.isEmpty || i.message.isEmpty }
|
val un = all.filter { i => i.node.isEmpty || i.message.isEmpty }
|
||||||
|
|
||||||
import ExceptionCategory._
|
import ExceptionCategory._
|
||||||
|
|
@ -199,7 +198,7 @@ object EvaluateTask
|
||||||
case _ => c.toString
|
case _ => c.toString
|
||||||
}
|
}
|
||||||
def name(node: Task[_]): String =
|
def name(node: Task[_]): String =
|
||||||
node.info.name orElse transformNode(node).map(Project.displayFull) getOrElse ("<anon-" + System.identityHashCode(node).toHexString + ">")
|
node.info.name orElse transformNode(node).map(displayFull) getOrElse ("<anon-" + System.identityHashCode(node).toHexString + ">")
|
||||||
def liftAnonymous: Incomplete => Incomplete = {
|
def liftAnonymous: Incomplete => Incomplete = {
|
||||||
case i @ Incomplete(node, tpe, None, causes, None) =>
|
case i @ Incomplete(node, tpe, None, causes, None) =>
|
||||||
causes.find( inc => !inc.node.isDefined && (inc.message.isDefined || inc.directCause.isDefined)) match {
|
causes.find( inc => !inc.node.isDefined && (inc.message.isDefined || inc.directCause.isDefined)) match {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import Project._
|
||||||
|
import Scope.GlobalScope
|
||||||
|
import Def.{ScopedKey, Setting}
|
||||||
|
|
||||||
|
final case class Extracted(structure: BuildStructure, session: SessionSettings, currentRef: ProjectRef)(implicit val showKey: Show[ScopedKey[_]])
|
||||||
|
{
|
||||||
|
def rootProject = structure.rootProject
|
||||||
|
lazy val currentUnit = structure units currentRef.build
|
||||||
|
lazy val currentProject = currentUnit defined currentRef.project
|
||||||
|
lazy val currentLoader: ClassLoader = currentUnit.loader
|
||||||
|
def get[T](key: TaskKey[T]): Task[T] = get(key.task)
|
||||||
|
def get[T](key: SettingKey[T]) = getOrError(inCurrent(key), key.key)
|
||||||
|
def getOpt[T](key: SettingKey[T]): Option[T] = structure.data.get(inCurrent(key), key.key)
|
||||||
|
private[this] def inCurrent[T](key: SettingKey[T]): Scope = if(key.scope.project == This) key.scope.copy(project = Select(currentRef)) else key.scope
|
||||||
|
@deprecated("This method does not apply state changes requested during task execution. Use 'runTask' instead, which does.", "0.11.1")
|
||||||
|
def evalTask[T](key: TaskKey[T], state: State): T = runTask(key, state)._2
|
||||||
|
def runTask[T](key: TaskKey[T], state: State): (State, T) =
|
||||||
|
{
|
||||||
|
import EvaluateTask._
|
||||||
|
val rkey = resolve(key.scopedKey)
|
||||||
|
val config = extractedConfig(this, structure)
|
||||||
|
val value: Option[(State, Result[T])] = apply(structure, key.task.scopedKey, state, currentRef, config)
|
||||||
|
val (newS, result) = getOrError(rkey.scope, rkey.key, value)
|
||||||
|
(newS, processResult(result, newS.log))
|
||||||
|
}
|
||||||
|
def runAggregated[T](key: TaskKey[T], state: State): State =
|
||||||
|
{
|
||||||
|
val rkey = resolve(key.scopedKey)
|
||||||
|
val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra)
|
||||||
|
val tasks = Act.keyValues(structure)(keys)
|
||||||
|
Aggregation.runTasks(state, structure, tasks, Aggregation.Dummies(KNil, HNil), show = false )(showKey)
|
||||||
|
}
|
||||||
|
private[this] def resolve[T](key: ScopedKey[T]): ScopedKey[T] =
|
||||||
|
Project.mapScope(Scope.resolveScope(GlobalScope, currentRef.build, rootProject) )( key.scopedKey )
|
||||||
|
private def getOrError[T](scope: Scope, key: AttributeKey[_], value: Option[T])(implicit display: Show[ScopedKey[_]]): T =
|
||||||
|
value getOrElse error(display(ScopedKey(scope, key)) + " is undefined.")
|
||||||
|
private def getOrError[T](scope: Scope, key: AttributeKey[T])(implicit display: Show[ScopedKey[_]]): T =
|
||||||
|
structure.data.get(scope, key) getOrElse error(display(ScopedKey(scope, key)) + " is undefined.")
|
||||||
|
|
||||||
|
def append(settings: Seq[Setting[_]], state: State): State =
|
||||||
|
{
|
||||||
|
val appendSettings = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
|
||||||
|
val newStructure = Load.reapply(session.original ++ appendSettings, structure)
|
||||||
|
Project.setProject(session, newStructure, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import Load._
|
import Load._
|
||||||
import Project._
|
import Def.{ScopedKey,Setting}
|
||||||
import Scoped._
|
import Scoped._
|
||||||
import Keys._
|
import Keys._
|
||||||
import Configurations.{Compile,Runtime}
|
import Configurations.{Compile,Runtime}
|
||||||
|
|
@ -64,7 +64,7 @@ object GlobalPlugin
|
||||||
(newS, processResult(result, newS.log))
|
(newS, processResult(result, newS.log))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val globalPluginSettings = inScope(Scope.GlobalScope in LocalRootProject)(Seq(
|
val globalPluginSettings = Project.inScope(Scope.GlobalScope in LocalRootProject)(Seq(
|
||||||
organization := SbtArtifacts.Organization,
|
organization := SbtArtifacts.Organization,
|
||||||
onLoadMessage <<= Keys.baseDirectory("Loading global plugins from " + _),
|
onLoadMessage <<= Keys.baseDirectory("Loading global plugins from " + _),
|
||||||
name := "global-plugin",
|
name := "global-plugin",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package sbt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Attributed.blankSeq
|
import Attributed.blankSeq
|
||||||
import Configurations.Compile
|
import Configurations.Compile
|
||||||
|
import Def.Setting
|
||||||
import Keys._
|
import Keys._
|
||||||
|
|
||||||
object IvyConsole
|
object IvyConsole
|
||||||
|
|
@ -22,7 +23,7 @@ object IvyConsole
|
||||||
val extracted = Project.extract(session, structure)
|
val extracted = Project.extract(session, structure)
|
||||||
import extracted._
|
import extracted._
|
||||||
|
|
||||||
val depSettings: Seq[Project.Setting[_]] = Seq(
|
val depSettings: Seq[Setting[_]] = Seq(
|
||||||
libraryDependencies ++= managed.reverse,
|
libraryDependencies ++= managed.reverse,
|
||||||
resolvers ++= repos.reverse,
|
resolvers ++= repos.reverse,
|
||||||
unmanagedJars in Compile ++= Attributed blankSeq unmanaged.reverse,
|
unmanagedJars in Compile ++= Attributed blankSeq unmanaged.reverse,
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import Project.ScopedKey
|
import Def.ScopedKey
|
||||||
import Load.BuildStructure
|
|
||||||
import complete.DefaultParsers.validID
|
import complete.DefaultParsers.validID
|
||||||
import Types.{idFun, some}
|
import Types.{idFun, some}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import Project.ScopedKey
|
import Def.ScopedKey
|
||||||
import complete._
|
import complete._
|
||||||
import inc.Analysis
|
import inc.Analysis
|
||||||
import inc.Locate.DefinesClass
|
import inc.Locate.DefinesClass
|
||||||
|
|
@ -38,9 +38,9 @@ object Keys
|
||||||
// Project keys
|
// Project keys
|
||||||
val projectCommand = AttributeKey[Boolean]("project-command", "Marks Commands that were registered for the current Project.", Invisible)
|
val projectCommand = AttributeKey[Boolean]("project-command", "Marks Commands that were registered for the current Project.", Invisible)
|
||||||
val sessionSettings = AttributeKey[SessionSettings]("session-settings", "Tracks current build, project, and setting modifications.", DSetting)
|
val sessionSettings = AttributeKey[SessionSettings]("session-settings", "Tracks current build, project, and setting modifications.", DSetting)
|
||||||
val stateBuildStructure = AttributeKey[Load.BuildStructure]("build-structure", "Data structure containing all information about the build definition.", BSetting)
|
val stateBuildStructure = AttributeKey[BuildStructure]("build-structure", "Data structure containing all information about the build definition.", BSetting)
|
||||||
val buildStructure = TaskKey[Load.BuildStructure]("build-structure", "Provides access to the build structure, settings, and streams manager.", DTask)
|
val buildStructure = TaskKey[BuildStructure]("build-structure", "Provides access to the build structure, settings, and streams manager.", DTask)
|
||||||
val loadedBuild = SettingKey[Load.LoadedBuild]("loaded-build", "Provides access to the loaded project structure. This is the information available before settings are evaluated.", DSetting)
|
val loadedBuild = SettingKey[LoadedBuild]("loaded-build", "Provides access to the loaded project structure. This is the information available before settings are evaluated.", DSetting)
|
||||||
val buildDependencies = SettingKey[BuildDependencies]("build-dependencies", "Definitive source of inter-project dependencies for compilation and dependency management.\n\tThis is populated by default by the dependencies declared on Project instances, but may be modified.\n\tThe main restriction is that new builds may not be introduced.", DSetting)
|
val buildDependencies = SettingKey[BuildDependencies]("build-dependencies", "Definitive source of inter-project dependencies for compilation and dependency management.\n\tThis is populated by default by the dependencies declared on Project instances, but may be modified.\n\tThe main restriction is that new builds may not be introduced.", DSetting)
|
||||||
val appConfiguration = SettingKey[xsbti.AppConfiguration]("app-configuration", "Provides access to the launched sbt configuration, including the ScalaProvider, Launcher, and GlobalLock.", DSetting)
|
val appConfiguration = SettingKey[xsbti.AppConfiguration]("app-configuration", "Provides access to the launched sbt configuration, including the ScalaProvider, Launcher, and GlobalLock.", DSetting)
|
||||||
val thisProject = SettingKey[ResolvedProject]("this-project", "Provides the current project for the referencing scope.", CSetting)
|
val thisProject = SettingKey[ResolvedProject]("this-project", "Provides the current project for the referencing scope.", CSetting)
|
||||||
|
|
@ -70,10 +70,6 @@ object Keys
|
||||||
|
|
||||||
// Path Keys
|
// Path Keys
|
||||||
val baseDirectory = SettingKey[File]("base-directory", "The base directory. Depending on the scope, this is the base directory for the build, project, configuration, or task.", AMinusSetting)
|
val baseDirectory = SettingKey[File]("base-directory", "The base directory. Depending on the scope, this is the base directory for the build, project, configuration, or task.", AMinusSetting)
|
||||||
val globalBaseDirectory = AttributeKey[File]("global-base-directory", "The base directory for global sbt configuration and staging.", DSetting)
|
|
||||||
val globalPluginsDirectory = AttributeKey[File]("global-plugins-directory", "The base directory for global sbt plugins.", DSetting)
|
|
||||||
val globalSettingsDirectory = AttributeKey[File]("global-settings-directory", "The base directory for global sbt settings.", DSetting)
|
|
||||||
val stagingDirectory = AttributeKey[File]("staging-directory", "The directory for staging remote projects.", DSetting)
|
|
||||||
val target = SettingKey[File]("target", "Main directory for files generated by the build.", AMinusSetting)
|
val target = SettingKey[File]("target", "Main directory for files generated by the build.", AMinusSetting)
|
||||||
val crossTarget = SettingKey[File]("cross-target", "Main directory for files generated by the build that are cross-built.", BSetting)
|
val crossTarget = SettingKey[File]("cross-target", "Main directory for files generated by the build that are cross-built.", BSetting)
|
||||||
|
|
||||||
|
|
@ -210,7 +206,7 @@ object Keys
|
||||||
val isModule = AttributeKey[Boolean]("is-module", "True if the target is a module.", DSetting)
|
val isModule = AttributeKey[Boolean]("is-module", "True if the target is a module.", DSetting)
|
||||||
|
|
||||||
// Classpath/Dependency Management Keys
|
// Classpath/Dependency Management Keys
|
||||||
type Classpath = Seq[Attributed[File]]
|
type Classpath = Def.Classpath
|
||||||
|
|
||||||
val name = SettingKey[String]("name", "Project name.", APlusSetting)
|
val name = SettingKey[String]("name", "Project name.", APlusSetting)
|
||||||
val normalizedName = SettingKey[String]("normalized-name", "Project name transformed from mixed case and spaces to lowercase and dash-separated.", BSetting)
|
val normalizedName = SettingKey[String]("normalized-name", "Project name transformed from mixed case and spaces to lowercase and dash-separated.", BSetting)
|
||||||
|
|
@ -333,12 +329,11 @@ object Keys
|
||||||
val (executionRoots, dummyRoots)= dummy[Seq[ScopedKey[_]]]("execution-roots", "The list of root tasks for this task execution. Roots are the top-level tasks that were directly requested to be run.")
|
val (executionRoots, dummyRoots)= dummy[Seq[ScopedKey[_]]]("execution-roots", "The list of root tasks for this task execution. Roots are the top-level tasks that were directly requested to be run.")
|
||||||
val (state, dummyState) = dummy[State]("state", "Current build state.")
|
val (state, dummyState) = dummy[State]("state", "Current build state.")
|
||||||
val (streamsManager, dummyStreamsManager) = dummy[Streams]("streams-manager", "Streams manager, which provides streams for different contexts.")
|
val (streamsManager, dummyStreamsManager) = dummy[Streams]("streams-manager", "Streams manager, which provides streams for different contexts.")
|
||||||
val resolvedScoped = SettingKey[ScopedKey[_]]("resolved-scoped", "The ScopedKey for the referencing setting or task.", DSetting)
|
val resolvedScoped = Def.resolvedScoped
|
||||||
val pluginData = TaskKey[PluginData]("plugin-data", "Information from the plugin build needed in the main build definition.", DTask)
|
val pluginData = TaskKey[PluginData]("plugin-data", "Information from the plugin build needed in the main build definition.", DTask)
|
||||||
private[sbt] val parseResult: TaskKey[Any] = TaskKey("$parse-result", "Internal: used to implement input tasks.", Invisible)
|
|
||||||
|
|
||||||
val triggeredBy = AttributeKey[Seq[Task[_]]]("triggered-by")
|
val triggeredBy = Def.triggeredBy
|
||||||
val runBefore = AttributeKey[Seq[Task[_]]]("run-before")
|
val runBefore = Def.runBefore
|
||||||
|
|
||||||
type Streams = std.Streams[ScopedKey[_]]
|
type Streams = std.Streams[ScopedKey[_]]
|
||||||
type TaskStreams = std.TaskStreams[ScopedKey[_]]
|
type TaskStreams = std.TaskStreams[ScopedKey[_]]
|
||||||
|
|
@ -351,47 +346,3 @@ object Keys
|
||||||
}
|
}
|
||||||
def isDummy(t: Task[_]): Boolean = t.info.attributes.get(isDummyTask) getOrElse false
|
def isDummy(t: Task[_]): Boolean = t.info.attributes.get(isDummyTask) getOrElse false
|
||||||
}
|
}
|
||||||
|
|
||||||
object KeyRanks
|
|
||||||
{
|
|
||||||
// task and setting ranks, used to prioritize displaying information
|
|
||||||
// main tasks
|
|
||||||
final val APlusTask = 4
|
|
||||||
final val ATask = 5
|
|
||||||
final val AMinusTask = 6
|
|
||||||
|
|
||||||
// main settings
|
|
||||||
final val APlusSetting = 9
|
|
||||||
final val ASetting = 10
|
|
||||||
final val AMinusSetting = 11
|
|
||||||
|
|
||||||
// less major tasks or tasks that print useful information
|
|
||||||
final val BPlusTask = 29
|
|
||||||
final val BTask = 30
|
|
||||||
final val BMinusTask = 31
|
|
||||||
|
|
||||||
// secondary settings
|
|
||||||
final val BPlusSetting = 39
|
|
||||||
final val BSetting = 40
|
|
||||||
final val BMinusSetting = 41
|
|
||||||
|
|
||||||
// advanced settings
|
|
||||||
final val CSetting = 100
|
|
||||||
// advanced tasks
|
|
||||||
final val CTask = 200
|
|
||||||
// explicit settings
|
|
||||||
final val DSetting = 10000
|
|
||||||
// explicit tasks
|
|
||||||
final val DTask = 20000
|
|
||||||
|
|
||||||
final val MainTaskCutoff = AMinusTask
|
|
||||||
final val MainSettingCutoff = AMinusSetting
|
|
||||||
final val MainCutoff = math.max(AMinusTask, AMinusSetting)
|
|
||||||
|
|
||||||
final val DefaultTaskRank = (ATask + BTask)/2
|
|
||||||
final val DefaultInputRank = ATask // input tasks are likely a main task
|
|
||||||
final val DefaultSettingRank = (ASetting + BSetting) / 2
|
|
||||||
|
|
||||||
// implementation details
|
|
||||||
val Invisible = Int.MaxValue
|
|
||||||
}
|
|
||||||
|
|
|
||||||
164
main/Load.scala
164
main/Load.scala
|
|
@ -13,20 +13,20 @@ package sbt
|
||||||
import collection.mutable
|
import collection.mutable
|
||||||
import Compiler.{Compilers,Inputs}
|
import Compiler.{Compilers,Inputs}
|
||||||
import inc.{FileValueCache, Locate}
|
import inc.{FileValueCache, Locate}
|
||||||
import Project.{inScope, ScopedKey, ScopeLocal, Setting}
|
import Project.{inScope,makeSettings}
|
||||||
import Keys.{appConfiguration, baseDirectory, configuration, fullResolvers, fullClasspath, pluginData, streams, Streams, thisProject, thisProjectRef, update}
|
import Def.{parseResult, ScopedKey, ScopeLocal, Setting}
|
||||||
import Keys.{exportedProducts, isDummy, loadedBuild, parseResult, resolvedScoped, taskDefinitionKey}
|
import Keys.{appConfiguration, baseDirectory, configuration, fullResolvers, fullClasspath, pluginData, streams, thisProject, thisProjectRef, update}
|
||||||
|
import Keys.{exportedProducts, isDummy, loadedBuild, resolvedScoped, taskDefinitionKey}
|
||||||
import tools.nsc.reporters.ConsoleReporter
|
import tools.nsc.reporters.ConsoleReporter
|
||||||
import Build.{analyzed, data}
|
import Build.{analyzed, data}
|
||||||
import Scope.{GlobalScope, ThisScope}
|
import Scope.{GlobalScope, ThisScope}
|
||||||
import Types.const
|
import Types.const
|
||||||
|
|
||||||
object Load
|
|
||||||
{
|
|
||||||
import BuildPaths._
|
import BuildPaths._
|
||||||
import BuildStreams._
|
import BuildStreams._
|
||||||
import Locate.DefinesClass
|
import Locate.DefinesClass
|
||||||
|
|
||||||
|
object Load
|
||||||
|
{
|
||||||
// note that there is State passed in but not pulled out
|
// note that there is State passed in but not pulled out
|
||||||
def defaultLoad(state: State, baseDirectory: File, log: Logger, isPlugin: Boolean = false, topLevelExtras: List[URI] = Nil): (() => Eval, BuildStructure) =
|
def defaultLoad(state: State, baseDirectory: File, log: Logger, isPlugin: Boolean = false, topLevelExtras: List[URI] = Nil): (() => Eval, BuildStructure) =
|
||||||
{
|
{
|
||||||
|
|
@ -55,7 +55,7 @@ object Load
|
||||||
new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass, delegates,
|
new LoadBuildConfiguration(stagingDirectory, classpath, loader, compilers, evalPluginDef, definesClass, delegates,
|
||||||
EvaluateTask.injectStreams, pluginMgmt, inject, None, Nil, log)
|
EvaluateTask.injectStreams, pluginMgmt, inject, None, Nil, log)
|
||||||
}
|
}
|
||||||
def injectGlobal(state: State): Seq[Project.Setting[_]] =
|
def injectGlobal(state: State): Seq[Setting[_]] =
|
||||||
(appConfiguration in GlobalScope :== state.configuration) +:
|
(appConfiguration in GlobalScope :== state.configuration) +:
|
||||||
EvaluateTask.injectSettings
|
EvaluateTask.injectSettings
|
||||||
def defaultWithGlobal(state: State, base: File, rawConfig: LoadBuildConfiguration, globalBase: File, log: Logger): LoadBuildConfiguration =
|
def defaultWithGlobal(state: State, base: File, rawConfig: LoadBuildConfiguration, globalBase: File, log: Logger): LoadBuildConfiguration =
|
||||||
|
|
@ -126,7 +126,7 @@ object Load
|
||||||
lazy val rootEval = lazyEval(loaded.units(loaded.root).unit)
|
lazy val rootEval = lazyEval(loaded.units(loaded.root).unit)
|
||||||
val settings = finalTransforms(buildConfigurations(loaded, getRootProject(projects), rootEval, config.injectSettings))
|
val settings = finalTransforms(buildConfigurations(loaded, getRootProject(projects), rootEval, config.injectSettings))
|
||||||
val delegates = config.delegates(loaded)
|
val delegates = config.delegates(loaded)
|
||||||
val data = Project.makeSettings(settings, delegates, config.scopeLocal)( Project.showLoadingKey( loaded ) )
|
val data = makeSettings(settings, delegates, config.scopeLocal)( Project.showLoadingKey( loaded ) )
|
||||||
val index = structureIndex(data, settings, loaded.extra(data))
|
val index = structureIndex(data, settings, loaded.extra(data))
|
||||||
val streams = mkStreams(projects, loaded.root, data)
|
val streams = mkStreams(projects, loaded.root, data)
|
||||||
(rootEval, new BuildStructure(projects, loaded.root, settings, data, index, streams, delegates, config.scopeLocal))
|
(rootEval, new BuildStructure(projects, loaded.root, settings, data, index, streams, delegates, config.scopeLocal))
|
||||||
|
|
@ -156,7 +156,7 @@ object Load
|
||||||
case resolvedScoped.key => Some(defining.asInstanceOf[T])
|
case resolvedScoped.key => Some(defining.asInstanceOf[T])
|
||||||
case parseResult.key =>
|
case parseResult.key =>
|
||||||
import std.TaskExtra._
|
import std.TaskExtra._
|
||||||
val getResult = InputTask.inputMap map { m => m get defining getOrElse error("No parsed value for " + Project.displayFull(defining) + "\n" + m) }
|
val getResult = InputTask.inputMap map { m => m get defining getOrElse error("No parsed value for " + Def.displayFull(defining) + "\n" + m) }
|
||||||
Some(getResult.asInstanceOf[T])
|
Some(getResult.asInstanceOf[T])
|
||||||
case _ => None
|
case _ => None
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +180,7 @@ object Load
|
||||||
def reapply(newSettings: Seq[Setting[_]], structure: BuildStructure)(implicit display: Show[ScopedKey[_]]): BuildStructure =
|
def reapply(newSettings: Seq[Setting[_]], structure: BuildStructure)(implicit display: Show[ScopedKey[_]]): BuildStructure =
|
||||||
{
|
{
|
||||||
val transformed = finalTransforms(newSettings)
|
val transformed = finalTransforms(newSettings)
|
||||||
val newData = Project.makeSettings(transformed, structure.delegates, structure.scopeLocal)
|
val newData = makeSettings(transformed, structure.delegates, structure.scopeLocal)
|
||||||
val newIndex = structureIndex(newData, transformed, index => buildUtil(structure.root, structure.units, index, newData))
|
val newIndex = structureIndex(newData, transformed, index => buildUtil(structure.root, structure.units, index, newData))
|
||||||
val newStreams = mkStreams(structure.units, structure.root, newData)
|
val newStreams = mkStreams(structure.units, structure.root, newData)
|
||||||
new BuildStructure(units = structure.units, root = structure.root, settings = transformed, data = newData, index = newIndex, streams = newStreams, delegates = structure.delegates, scopeLocal = structure.scopeLocal)
|
new BuildStructure(units = structure.units, root = structure.root, settings = transformed, data = newData, index = newIndex, streams = newStreams, delegates = structure.delegates, scopeLocal = structure.scopeLocal)
|
||||||
|
|
@ -439,7 +439,7 @@ object Load
|
||||||
"Put .sbt plugin definitions directly in project/,\n .scala plugin definitions in project/project/,\n and remove the project/plugins/ directory.")
|
"Put .sbt plugin definitions directly in project/,\n .scala plugin definitions in project/project/,\n and remove the project/plugins/ directory.")
|
||||||
val plugs = plugins(pluginDir, s, config)
|
val plugs = plugins(pluginDir, s, config)
|
||||||
val defs = definitionSources(defDir)
|
val defs = definitionSources(defDir)
|
||||||
val target = buildOutputDirectory(defDir, config.compilers)
|
val target = buildOutputDirectory(defDir, config.compilers.scalac.scalaInstance)
|
||||||
IO.createDirectory(target)
|
IO.createDirectory(target)
|
||||||
val loadedDefs =
|
val loadedDefs =
|
||||||
if(defs.isEmpty)
|
if(defs.isEmpty)
|
||||||
|
|
@ -594,10 +594,6 @@ object Load
|
||||||
def loadPlugin(pluginName: String, loader: ClassLoader): Plugin =
|
def loadPlugin(pluginName: String, loader: ClassLoader): Plugin =
|
||||||
ModuleUtilities.getObject(pluginName, loader).asInstanceOf[Plugin]
|
ModuleUtilities.getObject(pluginName, loader).asInstanceOf[Plugin]
|
||||||
|
|
||||||
def importAll(values: Seq[String]) = if(values.isEmpty) Nil else values.map( _ + "._" ).mkString("import ", ", ", "") :: Nil
|
|
||||||
def importAllRoot(values: Seq[String]) = importAll(values map rootedName)
|
|
||||||
def rootedName(s: String) = if(s contains '.') "_root_." + s else s
|
|
||||||
|
|
||||||
def findPlugins(analysis: inc.Analysis): Seq[String] = discover(analysis, "sbt.Plugin")
|
def findPlugins(analysis: inc.Analysis): Seq[String] = discover(analysis, "sbt.Plugin")
|
||||||
def findDefinitions(analysis: inc.Analysis): Seq[String] = discover(analysis, "sbt.Build")
|
def findDefinitions(analysis: inc.Analysis): Seq[String] = discover(analysis, "sbt.Build")
|
||||||
def discover(analysis: inc.Analysis, subclasses: String*): Seq[String] =
|
def discover(analysis: inc.Analysis, subclasses: String*): Seq[String] =
|
||||||
|
|
@ -634,93 +630,65 @@ object Load
|
||||||
}
|
}
|
||||||
|
|
||||||
def defaultEvalOptions: Seq[String] = Nil
|
def defaultEvalOptions: Seq[String] = Nil
|
||||||
def baseImports = "import sbt._, Process._, Keys._" :: Nil
|
|
||||||
|
|
||||||
final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]])
|
@deprecated("Use BuildUtil.baseImports", "0.13.0")
|
||||||
final class LoadedDefinitions(val base: File, val target: Seq[File], val loader: ClassLoader, val builds: Seq[Build], val buildNames: Seq[String])
|
def baseImports = BuildUtil.baseImports
|
||||||
final class LoadedPlugins(val base: File, val pluginData: PluginData, val loader: ClassLoader, val plugins: Seq[Plugin], val pluginNames: Seq[String])
|
@deprecated("Use BuildUtil.checkCycles", "0.13.0")
|
||||||
{
|
def checkCycles(units: Map[URI, LoadedBuildUnit]): Unit = BuildUtil.checkCycles(units)
|
||||||
def fullClasspath: Seq[Attributed[File]] = pluginData.classpath
|
@deprecated("Use BuildUtil.importAll", "0.13.0")
|
||||||
def classpath: Seq[File] = data(fullClasspath)
|
def importAll(values: Seq[String]): Seq[String] = BuildUtil.importAll(values)
|
||||||
}
|
@deprecated("Use BuildUtil.importAllRoot", "0.13.0")
|
||||||
final class BuildUnit(val uri: URI, val localBase: File, val definitions: LoadedDefinitions, val plugins: LoadedPlugins)
|
def importAllRoot(values: Seq[String]): Seq[String] = BuildUtil.importAllRoot(values)
|
||||||
{
|
@deprecated("Use BuildUtil.rootedNames", "0.13.0")
|
||||||
override def toString = if(uri.getScheme == "file") localBase.toString else (uri + " (locally: " + localBase +")")
|
def rootedName(s: String): String = BuildUtil.rootedName(s)
|
||||||
}
|
@deprecated("Use BuildUtil.getImports", "0.13.0")
|
||||||
|
def getImports(unit: BuildUnit): Seq[String] = BuildUtil.getImports(unit)
|
||||||
final class LoadedBuild(val root: URI, val units: Map[URI, LoadedBuildUnit])
|
|
||||||
{
|
|
||||||
checkCycles(units)
|
|
||||||
def allProjectRefs: Seq[(ProjectRef, ResolvedProject)] = for( (uri, unit) <- units.toSeq; (id, proj) <- unit.defined ) yield ProjectRef(uri, id) -> proj
|
|
||||||
def extra(data: Settings[Scope])(keyIndex: KeyIndex): BuildUtil[ResolvedProject] = buildUtil(root, units, keyIndex, data)
|
|
||||||
}
|
|
||||||
def checkCycles(units: Map[URI, LoadedBuildUnit])
|
|
||||||
{
|
|
||||||
def getRef(pref: ProjectRef) = units(pref.build).defined(pref.project)
|
|
||||||
def deps(proj: ResolvedProject)(base: ResolvedProject => Seq[ProjectRef]): Seq[ResolvedProject] = Dag.topologicalSort(proj)(p => base(p) map getRef)
|
|
||||||
// check for cycles
|
|
||||||
for( (_, lbu) <- units; proj <- lbu.defined.values) {
|
|
||||||
deps(proj)(_.dependencies.map(_.project))
|
|
||||||
deps(proj)(_.delegates)
|
|
||||||
deps(proj)(_.aggregate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final class PartBuild(val root: URI, val units: Map[URI, PartBuildUnit])
|
|
||||||
sealed trait BuildUnitBase { def rootProjects: Seq[String]; def buildSettings: Seq[Setting[_]] }
|
|
||||||
final class PartBuildUnit(val unit: BuildUnit, val defined: Map[String, Project], val rootProjects: Seq[String], val buildSettings: Seq[Setting[_]]) extends BuildUnitBase
|
|
||||||
{
|
|
||||||
def resolve(f: Project => ResolvedProject): LoadedBuildUnit = new LoadedBuildUnit(unit, defined mapValues f toMap, rootProjects, buildSettings)
|
|
||||||
def resolveRefs(f: ProjectReference => ProjectRef): LoadedBuildUnit = resolve(_ resolve f)
|
|
||||||
}
|
|
||||||
final class LoadedBuildUnit(val unit: BuildUnit, val defined: Map[String, ResolvedProject], val rootProjects: Seq[String], val buildSettings: Seq[Setting[_]]) extends BuildUnitBase
|
|
||||||
{
|
|
||||||
assert(!rootProjects.isEmpty, "No root projects defined for build unit " + unit)
|
|
||||||
val root = rootProjects.head
|
|
||||||
def localBase = unit.localBase
|
|
||||||
def classpath: Seq[File] = unit.definitions.target ++ unit.plugins.classpath
|
|
||||||
def loader = unit.definitions.loader
|
|
||||||
def imports = getImports(unit)
|
|
||||||
override def toString = unit.toString
|
|
||||||
}
|
|
||||||
def getImports(unit: BuildUnit) = baseImports ++ importAllRoot(unit.plugins.pluginNames ++ unit.definitions.buildNames)
|
|
||||||
|
|
||||||
def referenced[PR <: ProjectReference](definitions: Seq[ProjectDefinition[PR]]): Seq[PR] = definitions flatMap { _.referenced }
|
def referenced[PR <: ProjectReference](definitions: Seq[ProjectDefinition[PR]]): Seq[PR] = definitions flatMap { _.referenced }
|
||||||
|
|
||||||
final class BuildStructure(val units: Map[URI, LoadedBuildUnit], val root: URI, val settings: Seq[Setting[_]], val data: Settings[Scope], val index: StructureIndex, val streams: State => Streams, val delegates: Scope => Seq[Scope], val scopeLocal: ScopeLocal)
|
@deprecated("LoadedBuildUnit is now top-level", "0.13.0")
|
||||||
{
|
type LoadedBuildUnit = sbt.LoadedBuildUnit
|
||||||
val rootProject: URI => String = Load getRootProject units
|
|
||||||
def allProjects: Seq[ResolvedProject] = units.values.flatMap(_.defined.values).toSeq
|
@deprecated("BuildStructure is now top-level", "0.13.0")
|
||||||
def allProjects(build: URI): Seq[ResolvedProject] = units.get(build).toList.flatMap(_.defined.values)
|
type BuildStructure = sbt.BuildStructure
|
||||||
def allProjectRefs: Seq[ProjectRef] = units.toSeq flatMap { case (build, unit) => refs(build, unit.defined.values.toSeq) }
|
|
||||||
def allProjectRefs(build: URI): Seq[ProjectRef] = refs(build, allProjects(build))
|
@deprecated("StructureIndex is now top-level", "0.13.0")
|
||||||
val extra: BuildUtil[ResolvedProject] = buildUtil(root, units, index.keyIndex, data)
|
type StructureIndex = sbt.StructureIndex
|
||||||
private[this] def refs(build: URI, projects: Seq[ResolvedProject]): Seq[ProjectRef] = projects.map { p => ProjectRef(build, p.id) }
|
|
||||||
}
|
@deprecated("LoadBuildConfiguration is now top-level", "0.13.0")
|
||||||
def buildUtil(root: URI, units: Map[URI, LoadedBuildUnit], keyIndex: KeyIndex, data: Settings[Scope]): BuildUtil[ResolvedProject] =
|
type LoadBuildConfiguration = sbt.LoadBuildConfiguration
|
||||||
{
|
@deprecated("LoadBuildConfiguration is now top-level", "0.13.0")
|
||||||
val getp = (build: URI, project: String) => Load.getProject(units, build, project)
|
val LoadBuildConfiguration = sbt.LoadBuildConfiguration
|
||||||
val configs = (_: ResolvedProject).configurations.map(c => ConfigKey(c.name))
|
|
||||||
val aggregates = Aggregation.relation(units)
|
final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]])
|
||||||
new BuildUtil(keyIndex, data, root, Load getRootProject units, getp, configs, aggregates)
|
|
||||||
}
|
|
||||||
final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[Attributed[File]], loader: ClassLoader,
|
|
||||||
compilers: Compilers, evalPluginDef: (BuildStructure, State) => PluginData, definesClass: DefinesClass,
|
|
||||||
delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal,
|
|
||||||
pluginManagement: PluginManagement, injectSettings: InjectSettings, globalPlugin: Option[GlobalPlugin], extraBuilds: Seq[URI],
|
|
||||||
log: Logger)
|
|
||||||
{
|
|
||||||
lazy val (globalPluginClasspath, globalPluginLoader) = pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
|
||||||
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else getPluginNames(globalPluginClasspath, globalPluginLoader)
|
|
||||||
}
|
|
||||||
final case class InjectSettings(global: Seq[Setting[_]], project: Seq[Setting[_]], projectLoaded: ClassLoader => Seq[Setting[_]])
|
final case class InjectSettings(global: Seq[Setting[_]], project: Seq[Setting[_]], projectLoaded: ClassLoader => Seq[Setting[_]])
|
||||||
|
|
||||||
// information that is not original, but can be reconstructed from the rest of BuildStructure
|
@deprecated("LoadedDefinitions is now top-level", "0.13.0")
|
||||||
final class StructureIndex(
|
type LoadedDefinitions = sbt.LoadedDefinitions
|
||||||
val keyMap: Map[String, AttributeKey[_]],
|
@deprecated("LoadedPlugins is now top-level", "0.13.0")
|
||||||
val taskToKey: Map[Task[_], ScopedKey[Task[_]]],
|
type LoadedPlugins = sbt.LoadedPlugins
|
||||||
val triggers: Triggers[Task],
|
@deprecated("BuildUnit is now top-level", "0.13.0")
|
||||||
val keyIndex: KeyIndex,
|
type BuildUnit = sbt.BuildUnit
|
||||||
val aggregateKeyIndex: KeyIndex
|
@deprecated("LoadedBuild is now top-level", "0.13.0")
|
||||||
)
|
type LoadedBuild = sbt.LoadedBuild
|
||||||
|
@deprecated("PartBuild is now top-level", "0.13.0")
|
||||||
|
type PartBuild = sbt.PartBuild
|
||||||
|
@deprecated("BuildUnitBase is now top-level", "0.13.0")
|
||||||
|
type BuildUnitBase = sbt.BuildUnitBase
|
||||||
|
@deprecated("PartBuildUnit is now top-level", "0.13.0")
|
||||||
|
type PartBuildUnit = sbt.PartBuildUnit
|
||||||
|
@deprecated("Use BuildUtil.apply", "0.13.0")
|
||||||
|
def buildUtil(root: URI, units: Map[URI, LoadedBuildUnit], keyIndex: KeyIndex, data: Settings[Scope]): BuildUtil[ResolvedProject] = BuildUtil(root, units, keyIndex, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final case class LoadBuildConfiguration(stagingDirectory: File, classpath: Seq[Attributed[File]], loader: ClassLoader,
|
||||||
|
compilers: Compilers, evalPluginDef: (BuildStructure, State) => PluginData, definesClass: DefinesClass,
|
||||||
|
delegates: LoadedBuild => Scope => Seq[Scope], scopeLocal: ScopeLocal,
|
||||||
|
pluginManagement: PluginManagement, injectSettings: Load.InjectSettings, globalPlugin: Option[GlobalPlugin], extraBuilds: Seq[URI],
|
||||||
|
log: Logger)
|
||||||
|
{
|
||||||
|
lazy val (globalPluginClasspath, globalPluginLoader) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin))
|
||||||
|
lazy val globalPluginNames = if(globalPluginClasspath.isEmpty) Nil else Load.getPluginNames(globalPluginClasspath, globalPluginLoader)
|
||||||
|
}
|
||||||
|
|
||||||
final class IncompatiblePluginsException(msg: String, cause: Throwable) extends Exception(msg, cause)
|
final class IncompatiblePluginsException(msg: String, cause: Throwable) extends Exception(msg, cause)
|
||||||
|
|
@ -7,7 +7,7 @@ package sbt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import LogManager._
|
import LogManager._
|
||||||
import std.Transform
|
import std.Transform
|
||||||
import Project.ScopedKey
|
import Def.ScopedKey
|
||||||
import Scope.GlobalScope
|
import Scope.GlobalScope
|
||||||
import MainLogging._
|
import MainLogging._
|
||||||
import Keys.{logLevel, logManager, persistLogLevel, persistTraceLevel, state, traceLevel}
|
import Keys.{logLevel, logManager, persistLogLevel, persistTraceLevel, state, traceLevel}
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ object BuiltinCommands
|
||||||
if(Project.isProjectLoaded(s))
|
if(Project.isProjectLoaded(s))
|
||||||
{
|
{
|
||||||
val e = Project.extract(s)
|
val e = Project.extract(s)
|
||||||
val current = "The current project is " + Project.display(e.currentRef) + "\n"
|
val current = "The current project is " + Reference.display(e.currentRef) + "\n"
|
||||||
val sc = aboutScala(s, e)
|
val sc = aboutScala(s, e)
|
||||||
val built = if(sc.isEmpty) "" else "The current project is built against " + sc + "\n"
|
val built = if(sc.isEmpty) "" else "The current project is built against " + sc + "\n"
|
||||||
current + built + aboutPlugins(e)
|
current + built + aboutPlugins(e)
|
||||||
|
|
@ -199,7 +199,7 @@ object BuiltinCommands
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
def sessionCommand = Command.make(SessionCommand, sessionBrief, SessionSettings.Help)(SessionSettings.command)
|
def sessionCommand = Command.make(SessionCommand, sessionBrief, SessionSettings.Help)(SessionSettings.command)
|
||||||
def reapply(newSession: SessionSettings, structure: Load.BuildStructure, s: State): State =
|
def reapply(newSession: SessionSettings, structure: BuildStructure, s: State): State =
|
||||||
{
|
{
|
||||||
s.log.info("Reapplying settings...")
|
s.log.info("Reapplying settings...")
|
||||||
val newStructure = Load.reapply(newSession.mergeSettings, structure)( Project.showContextKey(newSession, structure) )
|
val newStructure = Load.reapply(newSession.mergeSettings, structure)( Project.showContextKey(newSession, structure) )
|
||||||
|
|
@ -215,13 +215,13 @@ object BuiltinCommands
|
||||||
reapply(setResult.session, structure, s)
|
reapply(setResult.session, structure, s)
|
||||||
}
|
}
|
||||||
// @deprecated("Use SettingCompletions.setThis", "0.13.0")
|
// @deprecated("Use SettingCompletions.setThis", "0.13.0")
|
||||||
def setThis(s: State, extracted: Extracted, settings: Seq[Project.Setting[_]], arg: String) =
|
def setThis(s: State, extracted: Extracted, settings: Seq[Def.Setting[_]], arg: String) =
|
||||||
SettingCompletions.setThis(s, extracted, settings, arg)
|
SettingCompletions.setThis(s, extracted, settings, arg)
|
||||||
def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) =>
|
def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) =>
|
||||||
s.log.info(inspectOutput(s, option, sk))
|
s.log.info(inspectOutput(s, option, sk))
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
def inspectOutput(s: State, option: InspectOption, sk: Project.ScopedKey[_]): String =
|
def inspectOutput(s: State, option: InspectOption, sk: Def.ScopedKey[_]): String =
|
||||||
{
|
{
|
||||||
val extracted = Project.extract(s)
|
val extracted = Project.extract(s)
|
||||||
import extracted._
|
import extracted._
|
||||||
|
|
@ -262,7 +262,7 @@ object BuiltinCommands
|
||||||
|
|
||||||
import InspectOption._
|
import InspectOption._
|
||||||
def inspectParser = (s: State) => spacedInspectOptionParser(s) flatMap {
|
def inspectParser = (s: State) => spacedInspectOptionParser(s) flatMap {
|
||||||
case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Project.ScopedKey(Global, key)))
|
case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Def.ScopedKey(Global, key)))
|
||||||
case opt @ (DependencyTree | Details(_)) => spacedKeyParser(s).map(key => (opt, key))
|
case opt @ (DependencyTree | Details(_)) => spacedKeyParser(s).map(key => (opt, key))
|
||||||
}
|
}
|
||||||
val spacedInspectOptionParser: (State => Parser[InspectOption]) = (s: State) => {
|
val spacedInspectOptionParser: (State => Parser[InspectOption]) = (s: State) => {
|
||||||
|
|
@ -322,7 +322,7 @@ object BuiltinCommands
|
||||||
extracted.structure.units(curi).imports.map(s => (s, -1))
|
extracted.structure.units(curi).imports.map(s => (s, -1))
|
||||||
}
|
}
|
||||||
|
|
||||||
def listBuild(uri: URI, build: Load.LoadedBuildUnit, current: Boolean, currentID: String, log: Logger) =
|
def listBuild(uri: URI, build: LoadedBuildUnit, current: Boolean, currentID: String, log: Logger) =
|
||||||
{
|
{
|
||||||
log.info("In " + uri)
|
log.info("In " + uri)
|
||||||
def prefix(id: String) = if(currentID != id) " " else if(current) " * " else "(*)"
|
def prefix(id: String) = if(currentID != id) " " else if(current) " * " else "(*)"
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ object DefaultOptions {
|
||||||
import Opts._
|
import Opts._
|
||||||
import Path._
|
import Path._
|
||||||
import BuildPaths.{getGlobalBase, getGlobalSettingsDirectory}
|
import BuildPaths.{getGlobalBase, getGlobalSettingsDirectory}
|
||||||
import Project.{Setting, extract}
|
import Project.{extract, richInitializeTask}
|
||||||
|
import Def.Setting
|
||||||
|
|
||||||
def javac: Seq[String] = compile.encoding("UTF-8")
|
def javac: Seq[String] = compile.encoding("UTF-8")
|
||||||
def scalac: Seq[String] = compile.encoding("UTF-8")
|
def scalac: Seq[String] = compile.encoding("UTF-8")
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ package sbt
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Keys.{Streams, TaskStreams}
|
import Keys.{Streams, TaskStreams}
|
||||||
import Project.ScopedKey
|
import Def.ScopedKey
|
||||||
import Aggregation.{KeyValue, Values}
|
import Aggregation.{KeyValue, Values}
|
||||||
import Types.idFun
|
import Types.idFun
|
||||||
import Highlight.{bold, showMatches}
|
import Highlight.{bold, showMatches}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import Keys.Classpath
|
import Keys.Classpath
|
||||||
import Project.Setting
|
import Def.Setting
|
||||||
import PluginManagement._
|
import PluginManagement._
|
||||||
|
|
||||||
import java.net.{URL,URLClassLoader}
|
import java.net.{URL,URLClassLoader}
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ package sbt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import Project._
|
import Project._
|
||||||
import Keys.{appConfiguration, stateBuildStructure, commands, configuration, historyPath, projectCommand, sessionSettings, sessionVars, shellPrompt, thisProject, thisProjectRef, watch}
|
import Keys.{appConfiguration, stateBuildStructure, commands, configuration, historyPath, projectCommand, sessionSettings, shellPrompt, thisProject, thisProjectRef, watch}
|
||||||
import Scope.{GlobalScope,ThisScope}
|
import Scope.{GlobalScope,ThisScope}
|
||||||
import Load.BuildStructure
|
import Def.{Flattened, Initialize, ScopedKey, Setting}
|
||||||
import Types.{idFun, Id}
|
import Types.idFun
|
||||||
import complete.DefaultParsers
|
import complete.DefaultParsers
|
||||||
|
|
||||||
sealed trait ProjectDefinition[PR <: ProjectReference]
|
sealed trait ProjectDefinition[PR <: ProjectReference]
|
||||||
|
|
@ -17,7 +17,7 @@ sealed trait ProjectDefinition[PR <: ProjectReference]
|
||||||
def id: String
|
def id: String
|
||||||
def base: File
|
def base: File
|
||||||
def configurations: Seq[Configuration]
|
def configurations: Seq[Configuration]
|
||||||
def settings: Seq[Project.Setting[_]]
|
def settings: Seq[Setting[_]]
|
||||||
def aggregate: Seq[PR]
|
def aggregate: Seq[PR]
|
||||||
@deprecated("Delegation between projects should be replaced by directly sharing settings.", "0.13.0")
|
@deprecated("Delegation between projects should be replaced by directly sharing settings.", "0.13.0")
|
||||||
def delegates: Seq[PR]
|
def delegates: Seq[PR]
|
||||||
|
|
@ -36,7 +36,7 @@ sealed trait ProjectDefinition[PR <: ProjectReference]
|
||||||
sealed trait Project extends ProjectDefinition[ProjectReference]
|
sealed trait Project extends ProjectDefinition[ProjectReference]
|
||||||
{
|
{
|
||||||
def copy(id: String = id, base: File = base, aggregate: => Seq[ProjectReference] = aggregate, dependencies: => Seq[ClasspathDep[ProjectReference]] = dependencies,
|
def copy(id: String = id, base: File = base, aggregate: => Seq[ProjectReference] = aggregate, dependencies: => Seq[ClasspathDep[ProjectReference]] = dependencies,
|
||||||
delegates: => Seq[ProjectReference] = delegates, settings: => Seq[Project.Setting[_]] = settings, configurations: Seq[Configuration] = configurations,
|
delegates: => Seq[ProjectReference] = delegates, settings: => Seq[Setting[_]] = settings, configurations: Seq[Configuration] = configurations,
|
||||||
auto: AddSettings = auto): Project =
|
auto: AddSettings = auto): Project =
|
||||||
Project(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto)
|
Project(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto)
|
||||||
|
|
||||||
|
|
@ -61,85 +61,28 @@ sealed trait Project extends ProjectDefinition[ProjectReference]
|
||||||
def delegateTo(from: ProjectReference*): Project = copy(delegates = delegates ++ from)
|
def delegateTo(from: ProjectReference*): Project = copy(delegates = delegates ++ from)
|
||||||
def aggregate(refs: ProjectReference*): Project = copy(aggregate = (aggregate: Seq[ProjectReference]) ++ refs)
|
def aggregate(refs: ProjectReference*): Project = copy(aggregate = (aggregate: Seq[ProjectReference]) ++ refs)
|
||||||
def configs(cs: Configuration*): Project = copy(configurations = configurations ++ cs)
|
def configs(cs: Configuration*): Project = copy(configurations = configurations ++ cs)
|
||||||
def settings(ss: Project.Setting[_]*): Project = copy(settings = (settings: Seq[Project.Setting[_]]) ++ ss)
|
def settings(ss: Setting[_]*): Project = copy(settings = (settings: Seq[Setting[_]]) ++ ss)
|
||||||
def autoSettings(select: AddSettings*): Project = copy(auto = AddSettings.seq(select : _*))
|
def autoSettings(select: AddSettings*): Project = copy(auto = AddSettings.seq(select : _*))
|
||||||
}
|
}
|
||||||
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef]
|
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef]
|
||||||
|
|
||||||
final case class Extracted(structure: BuildStructure, session: SessionSettings, currentRef: ProjectRef)(implicit val showKey: Show[ScopedKey[_]])
|
|
||||||
{
|
|
||||||
def rootProject = structure.rootProject
|
|
||||||
lazy val currentUnit = structure units currentRef.build
|
|
||||||
lazy val currentProject = currentUnit defined currentRef.project
|
|
||||||
lazy val currentLoader: ClassLoader = currentUnit.loader
|
|
||||||
def get[T](key: TaskKey[T]): Task[T] = get(key.task)
|
|
||||||
def get[T](key: SettingKey[T]) = getOrError(inCurrent(key), key.key)
|
|
||||||
def getOpt[T](key: SettingKey[T]): Option[T] = structure.data.get(inCurrent(key), key.key)
|
|
||||||
private[this] def inCurrent[T](key: SettingKey[T]): Scope = if(key.scope.project == This) key.scope.copy(project = Select(currentRef)) else key.scope
|
|
||||||
@deprecated("This method does not apply state changes requested during task execution. Use 'runTask' instead, which does.", "0.11.1")
|
|
||||||
def evalTask[T](key: TaskKey[T], state: State): T = runTask(key, state)._2
|
|
||||||
def runTask[T](key: TaskKey[T], state: State): (State, T) =
|
|
||||||
{
|
|
||||||
import EvaluateTask._
|
|
||||||
val rkey = resolve(key.scopedKey)
|
|
||||||
val config = extractedConfig(this, structure)
|
|
||||||
val value: Option[(State, Result[T])] = apply(structure, key.task.scopedKey, state, currentRef, config)
|
|
||||||
val (newS, result) = getOrError(rkey.scope, rkey.key, value)
|
|
||||||
(newS, processResult(result, newS.log))
|
|
||||||
}
|
|
||||||
def runAggregated[T](key: TaskKey[T], state: State): State =
|
|
||||||
{
|
|
||||||
val rkey = resolve(key.scopedKey)
|
|
||||||
val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra)
|
|
||||||
val tasks = Act.keyValues(structure)(keys)
|
|
||||||
Aggregation.runTasks(state, structure, tasks, Aggregation.Dummies(KNil, HNil), show = false )(showKey)
|
|
||||||
}
|
|
||||||
private[this] def resolve[T](key: ScopedKey[T]): ScopedKey[T] =
|
|
||||||
Project.mapScope(Scope.resolveScope(GlobalScope, currentRef.build, rootProject) )( key.scopedKey )
|
|
||||||
private def getOrError[T](scope: Scope, key: AttributeKey[_], value: Option[T])(implicit display: Show[ScopedKey[_]]): T =
|
|
||||||
value getOrElse error(display(ScopedKey(scope, key)) + " is undefined.")
|
|
||||||
private def getOrError[T](scope: Scope, key: AttributeKey[T])(implicit display: Show[ScopedKey[_]]): T =
|
|
||||||
structure.data.get(scope, key) getOrElse error(display(ScopedKey(scope, key)) + " is undefined.")
|
|
||||||
|
|
||||||
def append(settings: Seq[Setting[_]], state: State): State =
|
|
||||||
{
|
|
||||||
val appendSettings = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
|
|
||||||
val newStructure = Load.reapply(session.original ++ appendSettings, structure)
|
|
||||||
Project.setProject(session, newStructure, state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed trait ClasspathDep[PR <: ProjectReference] { def project: PR; def configuration: Option[String] }
|
sealed trait ClasspathDep[PR <: ProjectReference] { def project: PR; def configuration: Option[String] }
|
||||||
final case class ResolvedClasspathDependency(project: ProjectRef, configuration: Option[String]) extends ClasspathDep[ProjectRef]
|
final case class ResolvedClasspathDependency(project: ProjectRef, configuration: Option[String]) extends ClasspathDep[ProjectRef]
|
||||||
final case class ClasspathDependency(project: ProjectReference, configuration: Option[String]) extends ClasspathDep[ProjectReference]
|
final case class ClasspathDependency(project: ProjectReference, configuration: Option[String]) extends ClasspathDep[ProjectReference]
|
||||||
|
|
||||||
object Project extends Init[Scope] with ProjectExtra
|
object Project extends ProjectExtra
|
||||||
{
|
{
|
||||||
lazy val showFullKey: Show[ScopedKey[_]] = showFullKey(None)
|
|
||||||
def showFullKey(keyNameColor: Option[String]): Show[ScopedKey[_]] =
|
|
||||||
new Show[ScopedKey[_]] { def apply(key: ScopedKey[_]) = displayFull(key, keyNameColor) }
|
|
||||||
def showContextKey(state: State): Show[ScopedKey[_]] =
|
def showContextKey(state: State): Show[ScopedKey[_]] =
|
||||||
showContextKey(state, None)
|
showContextKey(state, None)
|
||||||
|
|
||||||
def showContextKey(state: State, keyNameColor: Option[String]): Show[ScopedKey[_]] =
|
def showContextKey(state: State, keyNameColor: Option[String]): Show[ScopedKey[_]] =
|
||||||
if(isProjectLoaded(state)) showContextKey( session(state), structure(state), keyNameColor ) else showFullKey
|
if(isProjectLoaded(state)) showContextKey( session(state), structure(state), keyNameColor ) else Def.showFullKey
|
||||||
|
|
||||||
def showContextKey(session: SessionSettings, structure: BuildStructure, keyNameColor: Option[String] = None): Show[ScopedKey[_]] =
|
def showContextKey(session: SessionSettings, structure: BuildStructure, keyNameColor: Option[String] = None): Show[ScopedKey[_]] =
|
||||||
showRelativeKey(session.current, structure.allProjects.size > 1, keyNameColor)
|
Def.showRelativeKey(session.current, structure.allProjects.size > 1, keyNameColor)
|
||||||
|
|
||||||
def showLoadingKey(loaded: Load.LoadedBuild, keyNameColor: Option[String] = None): Show[ScopedKey[_]] =
|
def showLoadingKey(loaded: LoadedBuild, keyNameColor: Option[String] = None): Show[ScopedKey[_]] =
|
||||||
showRelativeKey( ProjectRef(loaded.root, loaded.units(loaded.root).rootProjects.head), loaded.allProjectRefs.size > 1, keyNameColor)
|
Def.showRelativeKey( ProjectRef(loaded.root, loaded.units(loaded.root).rootProjects.head), loaded.allProjectRefs.size > 1, keyNameColor)
|
||||||
|
|
||||||
def showRelativeKey(current: ProjectRef, multi: Boolean, keyNameColor: Option[String] = None): Show[ScopedKey[_]] = new Show[ScopedKey[_]] {
|
|
||||||
def apply(key: ScopedKey[_]) =
|
|
||||||
Scope.display(key.scope, colored(key.key.label, keyNameColor), ref => displayRelative(current, multi, ref))
|
|
||||||
}
|
|
||||||
def displayRelative(current: ProjectRef, multi: Boolean, project: Reference): String = project match {
|
|
||||||
case BuildRef(current.build) => "{.}/"
|
|
||||||
case `current` => if(multi) current.project + "/" else ""
|
|
||||||
case ProjectRef(current.build, x) => x + "/"
|
|
||||||
case _ => display(project) + "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract class ProjectDef[PR <: ProjectReference](val id: String, val base: File, aggregate0: => Seq[PR], dependencies0: => Seq[ClasspathDep[PR]],
|
private abstract class ProjectDef[PR <: ProjectReference](val id: String, val base: File, aggregate0: => Seq[PR], dependencies0: => Seq[ClasspathDep[PR]],
|
||||||
delegates0: => Seq[PR], settings0: => Seq[Setting[_]], val configurations: Seq[Configuration], val auto: AddSettings) extends ProjectDefinition[PR]
|
delegates0: => Seq[PR], settings0: => Seq[Setting[_]], val configurations: Seq[Configuration], val auto: AddSettings) extends ProjectDefinition[PR]
|
||||||
|
|
@ -183,8 +126,8 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
def getProjectForReference(ref: Reference, structure: BuildStructure): Option[ResolvedProject] =
|
def getProjectForReference(ref: Reference, structure: BuildStructure): Option[ResolvedProject] =
|
||||||
ref match { case pr: ProjectRef => getProject(pr, structure); case _ => None }
|
ref match { case pr: ProjectRef => getProject(pr, structure); case _ => None }
|
||||||
def getProject(ref: ProjectRef, structure: BuildStructure): Option[ResolvedProject] = getProject(ref, structure.units)
|
def getProject(ref: ProjectRef, structure: BuildStructure): Option[ResolvedProject] = getProject(ref, structure.units)
|
||||||
def getProject(ref: ProjectRef, structure: Load.LoadedBuild): Option[ResolvedProject] = getProject(ref, structure.units)
|
def getProject(ref: ProjectRef, structure: LoadedBuild): Option[ResolvedProject] = getProject(ref, structure.units)
|
||||||
def getProject(ref: ProjectRef, units: Map[URI, Load.LoadedBuildUnit]): Option[ResolvedProject] =
|
def getProject(ref: ProjectRef, units: Map[URI, LoadedBuildUnit]): Option[ResolvedProject] =
|
||||||
(units get ref.build).flatMap(_.defined get ref.project)
|
(units get ref.build).flatMap(_.defined get ref.project)
|
||||||
|
|
||||||
def runUnloadHooks(s: State): State =
|
def runUnloadHooks(s: State): State =
|
||||||
|
|
@ -227,40 +170,11 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap =
|
def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap =
|
||||||
vopt match { case Some(v) => attributes.put(key, v); case None => attributes.remove(key) }
|
vopt match { case Some(v) => attributes.put(key, v); case None => attributes.remove(key) }
|
||||||
def makeSettings(settings: Seq[Setting[_]], delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]])(implicit display: Show[ScopedKey[_]]) =
|
def makeSettings(settings: Seq[Setting[_]], delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]])(implicit display: Show[ScopedKey[_]]) =
|
||||||
make(settings)(delegates, scopeLocal, display)
|
Def.make(settings)(delegates, scopeLocal, display)
|
||||||
|
|
||||||
def equal(a: ScopedKey[_], b: ScopedKey[_], mask: ScopeMask): Boolean =
|
def equal(a: ScopedKey[_], b: ScopedKey[_], mask: ScopeMask): Boolean =
|
||||||
a.key == b.key && Scope.equal(a.scope, b.scope, mask)
|
a.key == b.key && Scope.equal(a.scope, b.scope, mask)
|
||||||
|
|
||||||
def colored(s: String, color: Option[String]): String = color match {
|
|
||||||
case Some(c) => c + s + scala.Console.RESET
|
|
||||||
case None => s
|
|
||||||
}
|
|
||||||
def displayFull(scoped: ScopedKey[_]): String = displayFull(scoped, None)
|
|
||||||
def displayFull(scoped: ScopedKey[_], keyNameColor: Option[String]): String = Scope.display(scoped.scope, colored(scoped.key.label, keyNameColor))
|
|
||||||
def displayMasked(scoped: ScopedKey[_], mask: ScopeMask): String = Scope.displayMasked(scoped.scope, scoped.key.label, mask)
|
|
||||||
def display(ref: Reference): String =
|
|
||||||
ref match
|
|
||||||
{
|
|
||||||
case pr: ProjectReference => display(pr)
|
|
||||||
case br: BuildReference => display(br)
|
|
||||||
}
|
|
||||||
def display(ref: BuildReference) =
|
|
||||||
ref match
|
|
||||||
{
|
|
||||||
case ThisBuild => "{<this>}"
|
|
||||||
case BuildRef(uri) => "{" + uri + "}"
|
|
||||||
}
|
|
||||||
def display(ref: ProjectReference) =
|
|
||||||
ref match
|
|
||||||
{
|
|
||||||
case ThisProject => "{<this>}<this>"
|
|
||||||
case LocalRootProject => "{<this>}<root>"
|
|
||||||
case LocalProject(id) => "{<this>}" + id
|
|
||||||
case RootProject(uri) => "{" + uri + " }<root>"
|
|
||||||
case ProjectRef(uri, id) => "{" + uri + "}" + id
|
|
||||||
}
|
|
||||||
|
|
||||||
def fillTaskAxis(scoped: ScopedKey[_]): ScopedKey[_] =
|
def fillTaskAxis(scoped: ScopedKey[_]): ScopedKey[_] =
|
||||||
ScopedKey(Scope.fillTaskAxis(scoped.scope, scoped.key), scoped.key)
|
ScopedKey(Scope.fillTaskAxis(scoped.scope, scoped.key), scoped.key)
|
||||||
|
|
||||||
|
|
@ -294,7 +208,7 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
case Some(sc) => "Provided by:\n\t" + Scope.display(sc, key.label) + "\n"
|
case Some(sc) => "Provided by:\n\t" + Scope.display(sc, key.label) + "\n"
|
||||||
case None => ""
|
case None => ""
|
||||||
}
|
}
|
||||||
val comp = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display)
|
val comp = Def.compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display)
|
||||||
val definedAt = comp get scoped map { c =>
|
val definedAt = comp get scoped map { c =>
|
||||||
def fmt(s: Setting[_]) = s.pos match {
|
def fmt(s: Setting[_]) = s.pos match {
|
||||||
case pos: FilePosition => Some(pos.path + ":" + pos.startLine)
|
case pos: FilePosition => Some(pos.path + ":" + pos.startLine)
|
||||||
|
|
@ -309,7 +223,7 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
} getOrElse ""
|
} getOrElse ""
|
||||||
|
|
||||||
|
|
||||||
val cMap = flattenLocals(comp)
|
val cMap = Def.flattenLocals(comp)
|
||||||
val related = cMap.keys.filter(k => k.key == key && k.scope != scope)
|
val related = cMap.keys.filter(k => k.key == key && k.scope != scope)
|
||||||
val depends = cMap.get(scoped) match { case Some(c) => c.dependencies.toSet; case None => Set.empty }
|
val depends = cMap.get(scoped) match { case Some(c) => c.dependencies.toSet; case None => Set.empty }
|
||||||
|
|
||||||
|
|
@ -343,7 +257,7 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
def relation(structure: BuildStructure, actual: Boolean)(implicit display: Show[ScopedKey[_]]) =
|
def relation(structure: BuildStructure, actual: Boolean)(implicit display: Show[ScopedKey[_]]) =
|
||||||
{
|
{
|
||||||
type Rel = Relation[ScopedKey[_], ScopedKey[_]]
|
type Rel = Relation[ScopedKey[_], ScopedKey[_]]
|
||||||
val cMap = flattenLocals(compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display))
|
val cMap = Def.flattenLocals(Def.compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display))
|
||||||
((Relation.empty: Rel) /: cMap) { case (r, (key, value)) =>
|
((Relation.empty: Rel) /: cMap) { case (r, (key, value)) =>
|
||||||
r + (key, value.dependencies)
|
r + (key, value.dependencies)
|
||||||
}
|
}
|
||||||
|
|
@ -412,26 +326,25 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
val extracted = Project.extract(state)
|
val extracted = Project.extract(state)
|
||||||
EvaluateTask(extracted.structure, taskKey, state, extracted.currentRef, config)
|
EvaluateTask(extracted.structure, taskKey, state, extracted.currentRef, config)
|
||||||
}
|
}
|
||||||
// this is here instead of Scoped so that it is considered without need for import (because of Project.Initialize)
|
|
||||||
implicit def richInitializeTask[T](init: Initialize[Task[T]]): Scoped.RichInitializeTask[T] = new Scoped.RichInitializeTask(init)
|
|
||||||
implicit def richInitializeInputTask[T](init: Initialize[InputTask[T]]): Scoped.RichInitializeInputTask[T] = new Scoped.RichInitializeInputTask(init)
|
|
||||||
implicit def richInitialize[T](i: Initialize[T]): Scoped.RichInitialize[T] = new Scoped.RichInitialize[T](i)
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class ScopedKeyData[A](scoped: ScopedKey[A], value: Any)
|
/** Many methods were moved to Def in 0.13. This implicit makes those methods still available on Project for the transition. */
|
||||||
{
|
@inline
|
||||||
import Types.const
|
@deprecated("Use Def directly", "0.13.0")
|
||||||
val key = scoped.key
|
implicit def projectToDef(p: Project.type): Def.type = Def
|
||||||
val scope = scoped.scope
|
|
||||||
def typeName: String = fold(fmtMf("Task[%s]"), fmtMf("InputTask[%s]"), key.manifest.toString)
|
implicit def projectToRef(p: Project): ProjectReference = LocalProject(p.id)
|
||||||
def settingValue: Option[Any] = fold(const(None), const(None), Some(value))
|
|
||||||
def description: String = fold(fmtMf("Task: %s"), fmtMf("Input task: %s"),
|
final class RichTaskSessionVar[S](i: Initialize[Task[S]])
|
||||||
"Setting: %s = %s" format (key.manifest.toString, value.toString))
|
{
|
||||||
def fold[A](targ: OptManifest[_] => A, itarg: OptManifest[_] => A, s: => A): A =
|
import SessionVar.{persistAndSet, resolveContext, set, transform => tx}
|
||||||
if (key.manifest.erasure == classOf[Task[_]]) targ(key.manifest.typeArguments.head)
|
|
||||||
else if (key.manifest.erasure == classOf[InputTask[_]]) itarg(key.manifest.typeArguments.head)
|
def updateState(f: (State, S) => State): Initialize[Task[S]] = i(t => tx(t, f))
|
||||||
else s
|
def storeAs(key: TaskKey[S])(implicit f: sbinary.Format[S]): Initialize[Task[S]] = (Keys.resolvedScoped, i) { (scoped, task) =>
|
||||||
def fmtMf(s: String): OptManifest[_] => String = s format _
|
tx(task, (state, value) => persistAndSet( resolveContext(key, scoped.scope, state), state, value)(f))
|
||||||
|
}
|
||||||
|
def keepAs(key: TaskKey[S]): Initialize[Task[S]] =
|
||||||
|
(i, Keys.resolvedScoped)( (t,scoped) => tx(t, (state,value) => set(resolveContext(key, scoped.scope, state), state, value) ) )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ProjectExtra
|
trait ProjectExtra
|
||||||
|
|
@ -439,6 +352,14 @@ trait ProjectExtra
|
||||||
implicit def configDependencyConstructor[T <% ProjectReference](p: T): Constructor = new Constructor(p)
|
implicit def configDependencyConstructor[T <% ProjectReference](p: T): Constructor = new Constructor(p)
|
||||||
implicit def classpathDependency[T <% ProjectReference](p: T): ClasspathDependency = new ClasspathDependency(p, None)
|
implicit def classpathDependency[T <% ProjectReference](p: T): ClasspathDependency = new ClasspathDependency(p, None)
|
||||||
|
|
||||||
|
// These used to be in Project so that they didn't need to get imported (due to Initialize being nested in Project).
|
||||||
|
// Moving Initialize and other settings types to Def and decoupling Project, Def, and Structure means these go here for now
|
||||||
|
implicit def richInitializeTask[T](init: Initialize[Task[T]]): Scoped.RichInitializeTask[T] = new Scoped.RichInitializeTask(init)
|
||||||
|
implicit def richInitializeInputTask[T](init: Initialize[InputTask[T]]): Scoped.RichInitializeInputTask[T] = new Scoped.RichInitializeInputTask(init)
|
||||||
|
implicit def richInitialize[T](i: Initialize[T]): Scoped.RichInitialize[T] = new Scoped.RichInitialize[T](i)
|
||||||
|
|
||||||
|
implicit def richTaskSessionVar[T](init: Initialize[Task[T]]): Project.RichTaskSessionVar[T] = new Project.RichTaskSessionVar(init)
|
||||||
|
|
||||||
def inConfig(conf: Configuration)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
|
def inConfig(conf: Configuration)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
|
||||||
inScope(ThisScope.copy(config = Select(conf)) )( (configuration :== conf) +: ss)
|
inScope(ThisScope.copy(config = Select(conf)) )( (configuration :== conf) +: ss)
|
||||||
def inTask(t: Scoped)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
|
def inTask(t: Scoped)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
|
||||||
|
|
@ -446,69 +367,3 @@ trait ProjectExtra
|
||||||
def inScope(scope: Scope)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
|
def inScope(scope: Scope)(ss: Seq[Setting[_]]): Seq[Setting[_]] =
|
||||||
Project.transform(Scope.replaceThis(scope), ss)
|
Project.transform(Scope.replaceThis(scope), ss)
|
||||||
}
|
}
|
||||||
|
|
||||||
import sbinary.{Format, Operations}
|
|
||||||
object SessionVar
|
|
||||||
{
|
|
||||||
val DefaultDataID = "data"
|
|
||||||
|
|
||||||
// these are required because of inference+manifest limitations
|
|
||||||
final case class Key[T](key: ScopedKey[Task[T]])
|
|
||||||
final case class Map(map: IMap[Key, Id]) {
|
|
||||||
def get[T](k: ScopedKey[Task[T]]): Option[T] = map get Key(k)
|
|
||||||
def put[T](k: ScopedKey[Task[T]], v: T): Map = Map(map put (Key(k), v))
|
|
||||||
}
|
|
||||||
def emptyMap = Map(IMap.empty)
|
|
||||||
|
|
||||||
def persistAndSet[T](key: ScopedKey[Task[T]], state: State, value: T)(implicit f: sbinary.Format[T]): State =
|
|
||||||
{
|
|
||||||
persist(key, state, value)(f)
|
|
||||||
set(key, state, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
def persist[T](key: ScopedKey[Task[T]], state: State, value: T)(implicit f: sbinary.Format[T]): Unit =
|
|
||||||
Project.structure(state).streams(state).use(key)( s =>
|
|
||||||
Operations.write(s.binary(DefaultDataID), value)(f)
|
|
||||||
)
|
|
||||||
|
|
||||||
def clear(s: State): State = s.put(sessionVars, SessionVar.emptyMap)
|
|
||||||
|
|
||||||
def get[T](key: ScopedKey[Task[T]], state: State): Option[T] = orEmpty(state get sessionVars) get key
|
|
||||||
|
|
||||||
def set[T](key: ScopedKey[Task[T]], state: State, value: T): State = state.update(sessionVars)(om => orEmpty(om) put (key, value))
|
|
||||||
|
|
||||||
def orEmpty(opt: Option[Map]) = opt getOrElse emptyMap
|
|
||||||
|
|
||||||
def transform[S](task: Task[S], f: (State, S) => State): Task[S] =
|
|
||||||
{
|
|
||||||
val g = (s: S, map: AttributeMap) => map.put(Keys.transformState, (state: State) => f(state, s))
|
|
||||||
task.copy(info = task.info.postTransform(g))
|
|
||||||
}
|
|
||||||
|
|
||||||
def resolveContext[T](key: ScopedKey[Task[T]], context: Scope, state: State): ScopedKey[Task[T]] =
|
|
||||||
{
|
|
||||||
val subScope = Scope.replaceThis(context)(key.scope)
|
|
||||||
val scope = Project.structure(state).data.definingScope(subScope, key.key) getOrElse subScope
|
|
||||||
ScopedKey(scope, key.key)
|
|
||||||
}
|
|
||||||
|
|
||||||
def read[T](key: ScopedKey[Task[T]], state: State)(implicit f: Format[T]): Option[T] =
|
|
||||||
Project.structure(state).streams(state).use(key) { s =>
|
|
||||||
try { Some(Operations.read(s.readBinary(key, DefaultDataID))) }
|
|
||||||
catch { case e: Exception => None }
|
|
||||||
}
|
|
||||||
|
|
||||||
def load[T](key: ScopedKey[Task[T]], state: State)(implicit f: Format[T]): Option[T] =
|
|
||||||
get(key, state) orElse read(key, state)(f)
|
|
||||||
|
|
||||||
def loadAndSet[T](key: ScopedKey[Task[T]], state: State, setIfUnset: Boolean = true)(implicit f: Format[T]): (State, Option[T]) =
|
|
||||||
get(key, state) match {
|
|
||||||
case s: Some[T] => (state, s)
|
|
||||||
case None => read(key, state)(f) match {
|
|
||||||
case s @ Some(t) =>
|
|
||||||
val newState = if(setIfUnset && get(key, state).isDefined) state else set(key, state, t)
|
|
||||||
(newState, s)
|
|
||||||
case None => (state, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* sbt -- Simple Build Tool
|
||||||
|
* Copyright 2011 Mark Harrah
|
||||||
|
*/
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URI
|
||||||
|
import BuildLoader.ResolveInfo
|
||||||
|
import Def.{ScopedKey, Setting}
|
||||||
|
|
||||||
|
object RetrieveUnit
|
||||||
|
{
|
||||||
|
def apply(info: ResolveInfo): Option[() => File] =
|
||||||
|
{
|
||||||
|
info.uri match {
|
||||||
|
case Scheme("svn") | Scheme("svn+ssh") => Resolvers.subversion(info)
|
||||||
|
case Scheme("hg") => Resolvers.mercurial(info)
|
||||||
|
case Scheme("git") => Resolvers.git(info)
|
||||||
|
case Path(path) if path.endsWith(".git") => Resolvers.git(info)
|
||||||
|
case Scheme("http") | Scheme("https") | Scheme("ftp") => Resolvers.remote(info)
|
||||||
|
case Scheme("file") => Resolvers.local(info)
|
||||||
|
case _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Scheme
|
||||||
|
{
|
||||||
|
def unapply(uri: URI) = Option(uri.getScheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
object Path
|
||||||
|
{
|
||||||
|
import RichURI.fromURI
|
||||||
|
|
||||||
|
def unapply(uri: URI) = Option(uri.withoutMarkerScheme.getPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import Def.ScopedKey
|
||||||
|
|
||||||
|
final case class ScopedKeyData[A](scoped: ScopedKey[A], value: Any)
|
||||||
|
{
|
||||||
|
import Types.const
|
||||||
|
val key = scoped.key
|
||||||
|
val scope = scoped.scope
|
||||||
|
def typeName: String = fold(fmtMf("Task[%s]"), fmtMf("InputTask[%s]"), key.manifest.toString)
|
||||||
|
def settingValue: Option[Any] = fold(const(None), const(None), Some(value))
|
||||||
|
def description: String = fold(fmtMf("Task: %s"), fmtMf("Input task: %s"),
|
||||||
|
"Setting: %s = %s" format (key.manifest.toString, value.toString))
|
||||||
|
def fold[A](targ: OptManifest[_] => A, itarg: OptManifest[_] => A, s: => A): A =
|
||||||
|
if (key.manifest.erasure == classOf[Task[_]]) targ(key.manifest.typeArguments.head)
|
||||||
|
else if (key.manifest.erasure == classOf[InputTask[_]]) itarg(key.manifest.typeArguments.head)
|
||||||
|
else s
|
||||||
|
def fmtMf(s: String): OptManifest[_] => String = s format _
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import Def.{ScopedKey,Setting}
|
||||||
import Project._
|
import Project._
|
||||||
import Types.Endo
|
import Types.Endo
|
||||||
import compiler.Eval
|
import compiler.Eval
|
||||||
|
|
@ -89,7 +90,7 @@ object SessionSettings
|
||||||
val newSession = session.copy(append = newAppend.toMap, original = newOriginal.flatten.toSeq)
|
val newSession = session.copy(append = newAppend.toMap, original = newOriginal.flatten.toSeq)
|
||||||
reapply(newSession.copy(original = newSession.mergeSettings, append = Map.empty), s)
|
reapply(newSession.copy(original = newSession.mergeSettings, append = Map.empty), s)
|
||||||
}
|
}
|
||||||
def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: Load.BuildStructure): (Seq[SessionSetting], Seq[Setting[_]]) =
|
def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: BuildStructure): (Seq[SessionSetting], Seq[Setting[_]]) =
|
||||||
{
|
{
|
||||||
val project = Project.getProject(pref, structure).getOrElse(error("Invalid project reference " + pref))
|
val project = Project.getProject(pref, structure).getOrElse(error("Invalid project reference " + pref))
|
||||||
val writeTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt"))
|
val writeTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt"))
|
||||||
|
|
@ -140,7 +141,7 @@ object SessionSettings
|
||||||
def printAllSettings(s: State): State =
|
def printAllSettings(s: State): State =
|
||||||
withSettings(s){ session =>
|
withSettings(s){ session =>
|
||||||
for( (ref, settings) <- session.append if !settings.isEmpty) {
|
for( (ref, settings) <- session.append if !settings.isEmpty) {
|
||||||
println("In " + Project.display(ref))
|
println("In " + Reference.display(ref))
|
||||||
printSettings(settings)
|
printSettings(settings)
|
||||||
}
|
}
|
||||||
s
|
s
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import Def.ScopedKey
|
||||||
|
import Types.Id
|
||||||
|
import Keys.sessionVars
|
||||||
|
import sbinary.{Format, Operations}
|
||||||
|
|
||||||
|
object SessionVar
|
||||||
|
{
|
||||||
|
val DefaultDataID = "data"
|
||||||
|
|
||||||
|
// these are required because of inference+manifest limitations
|
||||||
|
final case class Key[T](key: ScopedKey[Task[T]])
|
||||||
|
final case class Map(map: IMap[Key, Id]) {
|
||||||
|
def get[T](k: ScopedKey[Task[T]]): Option[T] = map get Key(k)
|
||||||
|
def put[T](k: ScopedKey[Task[T]], v: T): Map = Map(map put (Key(k), v))
|
||||||
|
}
|
||||||
|
def emptyMap = Map(IMap.empty)
|
||||||
|
|
||||||
|
def persistAndSet[T](key: ScopedKey[Task[T]], state: State, value: T)(implicit f: sbinary.Format[T]): State =
|
||||||
|
{
|
||||||
|
persist(key, state, value)(f)
|
||||||
|
set(key, state, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
def persist[T](key: ScopedKey[Task[T]], state: State, value: T)(implicit f: sbinary.Format[T]): Unit =
|
||||||
|
Project.structure(state).streams(state).use(key)( s =>
|
||||||
|
Operations.write(s.binary(DefaultDataID), value)(f)
|
||||||
|
)
|
||||||
|
|
||||||
|
def clear(s: State): State = s.put(sessionVars, SessionVar.emptyMap)
|
||||||
|
|
||||||
|
def get[T](key: ScopedKey[Task[T]], state: State): Option[T] = orEmpty(state get sessionVars) get key
|
||||||
|
|
||||||
|
def set[T](key: ScopedKey[Task[T]], state: State, value: T): State = state.update(sessionVars)(om => orEmpty(om) put (key, value))
|
||||||
|
|
||||||
|
def orEmpty(opt: Option[Map]) = opt getOrElse emptyMap
|
||||||
|
|
||||||
|
def transform[S](task: Task[S], f: (State, S) => State): Task[S] =
|
||||||
|
{
|
||||||
|
val g = (s: S, map: AttributeMap) => map.put(Keys.transformState, (state: State) => f(state, s))
|
||||||
|
task.copy(info = task.info.postTransform(g))
|
||||||
|
}
|
||||||
|
|
||||||
|
def resolveContext[T](key: ScopedKey[Task[T]], context: Scope, state: State): ScopedKey[Task[T]] =
|
||||||
|
{
|
||||||
|
val subScope = Scope.replaceThis(context)(key.scope)
|
||||||
|
val scope = Project.structure(state).data.definingScope(subScope, key.key) getOrElse subScope
|
||||||
|
ScopedKey(scope, key.key)
|
||||||
|
}
|
||||||
|
|
||||||
|
def read[T](key: ScopedKey[Task[T]], state: State)(implicit f: Format[T]): Option[T] =
|
||||||
|
Project.structure(state).streams(state).use(key) { s =>
|
||||||
|
try { Some(Operations.read(s.readBinary(key, DefaultDataID))) }
|
||||||
|
catch { case e: Exception => None }
|
||||||
|
}
|
||||||
|
|
||||||
|
def load[T](key: ScopedKey[Task[T]], state: State)(implicit f: Format[T]): Option[T] =
|
||||||
|
get(key, state) orElse read(key, state)(f)
|
||||||
|
|
||||||
|
def loadAndSet[T](key: ScopedKey[Task[T]], state: State, setIfUnset: Boolean = true)(implicit f: Format[T]): (State, Option[T]) =
|
||||||
|
get(key, state) match {
|
||||||
|
case s: Some[T] => (state, s)
|
||||||
|
case None => read(key, state)(f) match {
|
||||||
|
case s @ Some(t) =>
|
||||||
|
val newState = if(setIfUnset && get(key, state).isDefined) state else set(key, state, t)
|
||||||
|
(newState, s)
|
||||||
|
case None => (state, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,8 +3,8 @@ package sbt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import Project._
|
import Project._
|
||||||
|
import Def.{ScopedKey, Setting}
|
||||||
import Scope.{GlobalScope,ThisScope}
|
import Scope.{GlobalScope,ThisScope}
|
||||||
import Load.BuildStructure
|
|
||||||
import Types.{const, idFun, Id}
|
import Types.{const, idFun, Id}
|
||||||
import complete._
|
import complete._
|
||||||
import DefaultParsers._
|
import DefaultParsers._
|
||||||
|
|
@ -31,7 +31,7 @@ private[sbt] object SettingCompletions
|
||||||
{
|
{
|
||||||
val akey = setting.key.key
|
val akey = setting.key.key
|
||||||
val global = ScopedKey(Global, akey)
|
val global = ScopedKey(Global, akey)
|
||||||
val globalSetting = resolve( Project.setting(global, setting.init, setting.pos) )
|
val globalSetting = resolve( Def.setting(global, setting.init, setting.pos) )
|
||||||
globalSetting ++ allDefs.flatMap { d =>
|
globalSetting ++ allDefs.flatMap { d =>
|
||||||
if(d.key == akey)
|
if(d.key == akey)
|
||||||
Seq( SettingKey(akey) in d.scope <<= global)
|
Seq( SettingKey(akey) in d.scope <<= global)
|
||||||
|
|
@ -45,7 +45,7 @@ private[sbt] object SettingCompletions
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Implementation of the `set` command that will reload the current project with `settings` appended to the current settings. */
|
/** Implementation of the `set` command that will reload the current project with `settings` appended to the current settings. */
|
||||||
def setThis(s: State, extracted: Extracted, settings: Seq[Project.Setting[_]], arg: String): SetResult =
|
def setThis(s: State, extracted: Extracted, settings: Seq[Def.Setting[_]], arg: String): SetResult =
|
||||||
{
|
{
|
||||||
import extracted._
|
import extracted._
|
||||||
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
|
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, settings)
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ package sbt
|
||||||
|
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Project.{ScopedKey, flattenLocals, compiled}
|
import Def.{compiled,flattenLocals,ScopedKey}
|
||||||
import Load.BuildStructure
|
|
||||||
import Predef.{any2stringadd => _, _}
|
import Predef.{any2stringadd => _, _}
|
||||||
|
|
||||||
object SettingGraph
|
object SettingGraph
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
/* sbt -- Simple Build Tool
|
|
||||||
* Copyright 2011 Mark Harrah
|
|
||||||
*/
|
|
||||||
package sbt
|
|
||||||
|
|
||||||
import Load.BuildStructure
|
|
||||||
import Project.{Initialize, ScopedKey}
|
|
||||||
import Keys.{resolvedScoped, streams, TaskStreams}
|
|
||||||
import std.TaskExtra._
|
|
||||||
import Types.{:+:, idFun}
|
|
||||||
|
|
||||||
import sbinary.{Format, Operations}
|
|
||||||
|
|
||||||
@deprecated("Superseded by task state system.", "0.11.1")
|
|
||||||
object TaskData
|
|
||||||
{
|
|
||||||
val DefaultDataID = "data"
|
|
||||||
|
|
||||||
def apply[I,O](readFrom: Scoped, id: String = DefaultDataID)(f: (State, I) => O)(default: => I)(implicit fmt: Format[I]): Initialize[State => O] =
|
|
||||||
resolvedScoped { resolved =>
|
|
||||||
s => f(s, readData(Project structure s, resolved, readFrom.key, id) getOrElse default)
|
|
||||||
}
|
|
||||||
|
|
||||||
def readData[T](structure: BuildStructure, reader: ScopedKey[_], readFrom: AttributeKey[_], id: String)(implicit f: Format[T]): Option[T] =
|
|
||||||
try {
|
|
||||||
dataStreams(structure, reader, readFrom) { (ts,key) =>
|
|
||||||
Operations.read( ts.readBinary(key, id) )(f)
|
|
||||||
}
|
|
||||||
} catch { case e: Exception => None }
|
|
||||||
|
|
||||||
def dataStreams[T](structure: BuildStructure, reader: ScopedKey[_], readFrom: AttributeKey[_])(f: (TaskStreams, ScopedKey[_]) => T): Option[T] =
|
|
||||||
structure.data.definingScope(reader.scope, readFrom) map { defined =>
|
|
||||||
val key = ScopedKey(Scope.fillTaskAxis(defined, readFrom), readFrom)
|
|
||||||
structure.streams(fakeState(structure)).use(reader)(ts => f(ts, key))
|
|
||||||
}
|
|
||||||
def write[T](i: Initialize[Task[T]], id: String = DefaultDataID)(implicit f: Format[T]): Initialize[Task[T]] = writeRelated(i, id)(idFun[T])(f)
|
|
||||||
|
|
||||||
def writeRelated[T, S](i: Initialize[Task[T]], id: String = DefaultDataID)(convert: T => S)(implicit f: Format[S]): Initialize[Task[T]] =
|
|
||||||
(streams zipWith i) { (sTask, iTask) =>
|
|
||||||
(sTask,iTask) map { case s :+: value :+: HNil =>
|
|
||||||
Operations.write( s.binary(id), convert(value) )(f)
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// exists to keep the method signatures the same (since this object is potentially used but deprecated),
|
|
||||||
// but allow the BuildStructure Streams to be constructed from State, which isn't actually needed here
|
|
||||||
private[this] def fakeState(structure: BuildStructure): State =
|
|
||||||
{
|
|
||||||
val config = Keys.appConfiguration in Scope.GlobalScope get structure.data
|
|
||||||
State(config.get, Nil, Set.empty, None, Nil, State.newHistory, AttributeMap.empty, StandardMain.initialGlobalLogging, State.Continue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import Keys.Classpath
|
import Def.Classpath
|
||||||
import scala.annotation.implicitNotFound
|
import scala.annotation.implicitNotFound
|
||||||
|
|
||||||
object Append
|
object Append
|
||||||
{
|
{
|
||||||
@implicitNotFound(msg = "No implicit for Append.Value[${A}, ${B}] found,\n so ${B} cannot be appended to ${A}")
|
@implicitNotFound(msg = "No implicit for Append.Value[${A}, ${B}] found,\n so ${B} cannot be appended to ${A}")
|
||||||
sealed trait Value[A,B]
|
sealed trait Value[A,B]
|
||||||
{
|
{
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
final case class ConfigKey(name: String)
|
||||||
|
object ConfigKey
|
||||||
|
{
|
||||||
|
implicit def configurationToKey(c: Configuration): ConfigKey = ConfigKey(c.name)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object Def extends Init[Scope]
|
||||||
|
{
|
||||||
|
type Classpath = Seq[Attributed[File]]
|
||||||
|
|
||||||
|
val triggeredBy = AttributeKey[Seq[Task[_]]]("triggered-by")
|
||||||
|
val runBefore = AttributeKey[Seq[Task[_]]]("run-before")
|
||||||
|
private[sbt] val parseResult: TaskKey[Any] = TaskKey("$parse-result", "Internal: used to implement input tasks.", KeyRanks.Invisible)
|
||||||
|
// TODO: move back to Keys
|
||||||
|
val resolvedScoped = SettingKey[ScopedKey[_]]("resolved-scoped", "The ScopedKey for the referencing setting or task.", KeyRanks.DSetting)
|
||||||
|
|
||||||
|
lazy val showFullKey: Show[ScopedKey[_]] = showFullKey(None)
|
||||||
|
def showFullKey(keyNameColor: Option[String]): Show[ScopedKey[_]] =
|
||||||
|
new Show[ScopedKey[_]] { def apply(key: ScopedKey[_]) = displayFull(key, keyNameColor) }
|
||||||
|
|
||||||
|
def showRelativeKey(current: ProjectRef, multi: Boolean, keyNameColor: Option[String] = None): Show[ScopedKey[_]] = new Show[ScopedKey[_]] {
|
||||||
|
def apply(key: ScopedKey[_]) =
|
||||||
|
Scope.display(key.scope, colored(key.key.label, keyNameColor), ref => displayRelative(current, multi, ref))
|
||||||
|
}
|
||||||
|
def displayRelative(current: ProjectRef, multi: Boolean, project: Reference): String = project match {
|
||||||
|
case BuildRef(current.build) => "{.}/"
|
||||||
|
case `current` => if(multi) current.project + "/" else ""
|
||||||
|
case ProjectRef(current.build, x) => x + "/"
|
||||||
|
case _ => Reference.display(project) + "/"
|
||||||
|
}
|
||||||
|
def displayFull(scoped: ScopedKey[_]): String = displayFull(scoped, None)
|
||||||
|
def displayFull(scoped: ScopedKey[_], keyNameColor: Option[String]): String = Scope.display(scoped.scope, colored(scoped.key.label, keyNameColor))
|
||||||
|
def displayMasked(scoped: ScopedKey[_], mask: ScopeMask): String = Scope.displayMasked(scoped.scope, scoped.key.label, mask)
|
||||||
|
|
||||||
|
def colored(s: String, color: Option[String]): String = color match {
|
||||||
|
case Some(c) => c + s + scala.Console.RESET
|
||||||
|
case None => s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
sealed trait DelegateIndex
|
||||||
|
{
|
||||||
|
def project(ref: ProjectRef): Seq[ScopeAxis[ResolvedReference]]
|
||||||
|
def config(ref: ProjectRef, conf: ConfigKey): Seq[ScopeAxis[ConfigKey]]
|
||||||
|
// def task(ref: ProjectRef, task: ScopedKey[_]): Seq[ScopeAxis[ScopedKey[_]]]
|
||||||
|
// def extra(ref: ProjectRef, e: AttributeMap): Seq[ScopeAxis[AttributeMap]]
|
||||||
|
}
|
||||||
|
private final class DelegateIndex0(refs: Map[ProjectRef, ProjectDelegates]) extends DelegateIndex
|
||||||
|
{
|
||||||
|
def project(ref: ProjectRef): Seq[ScopeAxis[ResolvedReference]] = refs.get(ref) match { case Some(pd) => pd.refs; case None => Nil }
|
||||||
|
def config(ref: ProjectRef, conf: ConfigKey): Seq[ScopeAxis[ConfigKey]] =
|
||||||
|
refs.get(ref) match {
|
||||||
|
case Some(pd) => pd.confs.get(conf) match { case Some(cs) => cs; case None => Select(conf) :: Global :: Nil }
|
||||||
|
case None => Select(conf) :: Global :: Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private final class ProjectDelegates(val ref: ProjectRef, val refs: Seq[ScopeAxis[ResolvedReference]], val confs: Map[ConfigKey, Seq[ScopeAxis[ConfigKey]]])
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
object KeyRanks
|
||||||
|
{
|
||||||
|
// task and setting ranks, used to prioritize displaying information
|
||||||
|
// main tasks
|
||||||
|
final val APlusTask = 4
|
||||||
|
final val ATask = 5
|
||||||
|
final val AMinusTask = 6
|
||||||
|
|
||||||
|
// main settings
|
||||||
|
final val APlusSetting = 9
|
||||||
|
final val ASetting = 10
|
||||||
|
final val AMinusSetting = 11
|
||||||
|
|
||||||
|
// less major tasks or tasks that print useful information
|
||||||
|
final val BPlusTask = 29
|
||||||
|
final val BTask = 30
|
||||||
|
final val BMinusTask = 31
|
||||||
|
|
||||||
|
// secondary settings
|
||||||
|
final val BPlusSetting = 39
|
||||||
|
final val BSetting = 40
|
||||||
|
final val BMinusSetting = 41
|
||||||
|
|
||||||
|
// advanced settings
|
||||||
|
final val CSetting = 100
|
||||||
|
// advanced tasks
|
||||||
|
final val CTask = 200
|
||||||
|
// explicit settings
|
||||||
|
final val DSetting = 10000
|
||||||
|
// explicit tasks
|
||||||
|
final val DTask = 20000
|
||||||
|
|
||||||
|
final val MainTaskCutoff = AMinusTask
|
||||||
|
final val MainSettingCutoff = AMinusSetting
|
||||||
|
final val MainCutoff = math.max(AMinusTask, AMinusSetting)
|
||||||
|
|
||||||
|
final val DefaultTaskRank = (ATask + BTask)/2
|
||||||
|
final val DefaultInputRank = ATask // input tasks are likely a main task
|
||||||
|
final val DefaultSettingRank = (ASetting + BSetting) / 2
|
||||||
|
|
||||||
|
// implementation details
|
||||||
|
val Invisible = Int.MaxValue
|
||||||
|
}
|
||||||
|
|
@ -64,6 +64,29 @@ object Reference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def display(ref: Reference): String =
|
||||||
|
ref match
|
||||||
|
{
|
||||||
|
case pr: ProjectReference => display(pr)
|
||||||
|
case br: BuildReference => display(br)
|
||||||
|
}
|
||||||
|
|
||||||
|
def display(ref: BuildReference): String =
|
||||||
|
ref match
|
||||||
|
{
|
||||||
|
case ThisBuild => "{<this>}"
|
||||||
|
case BuildRef(uri) => "{" + uri + "}"
|
||||||
|
}
|
||||||
|
def display(ref: ProjectReference): String =
|
||||||
|
ref match
|
||||||
|
{
|
||||||
|
case ThisProject => "{<this>}<this>"
|
||||||
|
case LocalRootProject => "{<this>}<root>"
|
||||||
|
case LocalProject(id) => "{<this>}" + id
|
||||||
|
case RootProject(uri) => "{" + uri + " }<root>"
|
||||||
|
case ProjectRef(uri, id) => "{" + uri + "}" + id
|
||||||
|
}
|
||||||
|
|
||||||
def buildURI(ref: ResolvedReference): URI = ref match {
|
def buildURI(ref: ResolvedReference): URI = ref match {
|
||||||
case BuildRef(b) => b
|
case BuildRef(b) => b
|
||||||
case ProjectRef(b, _) => b
|
case ProjectRef(b, _) => b
|
||||||
|
|
@ -78,5 +101,4 @@ object Reference
|
||||||
implicit def uriToRef(u: URI): ProjectReference = RootProject(u)
|
implicit def uriToRef(u: URI): ProjectReference = RootProject(u)
|
||||||
implicit def fileToRef(f: File): ProjectReference = RootProject(f)
|
implicit def fileToRef(f: File): ProjectReference = RootProject(f)
|
||||||
implicit def stringToReference(s: String): ProjectReference = LocalProject(s)
|
implicit def stringToReference(s: String): ProjectReference = LocalProject(s)
|
||||||
implicit def projectToRef(p: Project): ProjectReference = LocalProject(p.id)
|
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import Types.some
|
|
||||||
|
|
||||||
final case class Scope(project: ScopeAxis[Reference], config: ScopeAxis[ConfigKey], task: ScopeAxis[AttributeKey[_]], extra: ScopeAxis[AttributeMap])
|
final case class Scope(project: ScopeAxis[Reference], config: ScopeAxis[ConfigKey], task: ScopeAxis[AttributeKey[_]], extra: ScopeAxis[AttributeMap])
|
||||||
{
|
{
|
||||||
|
|
@ -121,7 +120,7 @@ object Scope
|
||||||
(!mask.extra || a.extra == b.extra)
|
(!mask.extra || a.extra == b.extra)
|
||||||
|
|
||||||
def projectPrefix(project: ScopeAxis[Reference], show: Reference => String = showProject): String = project.foldStrict(show, "*/", "./")
|
def projectPrefix(project: ScopeAxis[Reference], show: Reference => String = showProject): String = project.foldStrict(show, "*/", "./")
|
||||||
def showProject = (ref: Reference) => Project.display(ref) + "/"
|
def showProject = (ref: Reference) => Reference.display(ref) + "/"
|
||||||
|
|
||||||
def parseScopedKey(command: String): (Scope, String) =
|
def parseScopedKey(command: String): (Scope, String) =
|
||||||
{
|
{
|
||||||
|
|
@ -231,68 +230,3 @@ object Scope
|
||||||
else
|
else
|
||||||
for( c <- withGlobalAxis(scope.config); t <- withGlobalAxis(scope.task); e <- withGlobalAxis(scope.extra) ) yield Scope(Global, c, t, e)
|
for( c <- withGlobalAxis(scope.config); t <- withGlobalAxis(scope.task); e <- withGlobalAxis(scope.extra) ) yield Scope(Global, c, t, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sealed trait ScopeAxis[+S] {
|
|
||||||
def foldStrict[T](f: S => T, ifGlobal: T, ifThis: T): T = fold(f, ifGlobal, ifThis)
|
|
||||||
def fold[T](f: S => T, ifGlobal: => T, ifThis: => T): T = this match {
|
|
||||||
case This => ifThis
|
|
||||||
case Global => ifGlobal
|
|
||||||
case Select(s) => f(s)
|
|
||||||
}
|
|
||||||
def toOption: Option[S] = foldStrict(some.fn, None, None)
|
|
||||||
def map[T](f: S => T): ScopeAxis[T] = foldStrict(s => Select(f(s)), Global, This)
|
|
||||||
def isSelect: Boolean = false
|
|
||||||
}
|
|
||||||
case object This extends ScopeAxis[Nothing]
|
|
||||||
case object Global extends ScopeAxis[Nothing]
|
|
||||||
final case class Select[S](s: S) extends ScopeAxis[S] {
|
|
||||||
override def isSelect = true
|
|
||||||
}
|
|
||||||
object ScopeAxis
|
|
||||||
{
|
|
||||||
implicit def scopeAxisToScope(axis: ScopeAxis[Nothing]): Scope =
|
|
||||||
Scope(axis, axis, axis, axis)
|
|
||||||
def fromOption[T](o: Option[T]): ScopeAxis[T] = o match {
|
|
||||||
case Some(v) => Select(v)
|
|
||||||
case None => Global
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** Specifies the Scope axes that should be used for an operation. `true` indicates an axis should be used. */
|
|
||||||
final case class ScopeMask(project: Boolean = true, config: Boolean = true, task: Boolean = true, extra: Boolean = true)
|
|
||||||
{
|
|
||||||
def concatShow(p: String, c: String, t: String, sep: String, x: String): String =
|
|
||||||
{
|
|
||||||
val sb = new StringBuilder
|
|
||||||
if(project) sb.append(p)
|
|
||||||
if(config) sb.append(c)
|
|
||||||
if(task) sb.append(t)
|
|
||||||
sb.append(sep)
|
|
||||||
if(extra) sb.append(x)
|
|
||||||
sb.toString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final case class ConfigKey(name: String)
|
|
||||||
object ConfigKey
|
|
||||||
{
|
|
||||||
implicit def configurationToKey(c: Configuration): ConfigKey = ConfigKey(c.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed trait DelegateIndex
|
|
||||||
{
|
|
||||||
def project(ref: ProjectRef): Seq[ScopeAxis[ResolvedReference]]
|
|
||||||
def config(ref: ProjectRef, conf: ConfigKey): Seq[ScopeAxis[ConfigKey]]
|
|
||||||
// def task(ref: ProjectRef, task: ScopedKey[_]): Seq[ScopeAxis[ScopedKey[_]]]
|
|
||||||
// def extra(ref: ProjectRef, e: AttributeMap): Seq[ScopeAxis[AttributeMap]]
|
|
||||||
}
|
|
||||||
private final class DelegateIndex0(refs: Map[ProjectRef, ProjectDelegates]) extends DelegateIndex
|
|
||||||
{
|
|
||||||
def project(ref: ProjectRef): Seq[ScopeAxis[ResolvedReference]] = refs.get(ref) match { case Some(pd) => pd.refs; case None => Nil }
|
|
||||||
def config(ref: ProjectRef, conf: ConfigKey): Seq[ScopeAxis[ConfigKey]] =
|
|
||||||
refs.get(ref) match {
|
|
||||||
case Some(pd) => pd.confs.get(conf) match { case Some(cs) => cs; case None => Select(conf) :: Global :: Nil }
|
|
||||||
case None => Select(conf) :: Global :: Nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private final class ProjectDelegates(val ref: ProjectRef, val refs: Seq[ScopeAxis[ResolvedReference]], val confs: Map[ConfigKey, Seq[ScopeAxis[ConfigKey]]])
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import Types.some
|
||||||
|
|
||||||
|
sealed trait ScopeAxis[+S] {
|
||||||
|
def foldStrict[T](f: S => T, ifGlobal: T, ifThis: T): T = fold(f, ifGlobal, ifThis)
|
||||||
|
def fold[T](f: S => T, ifGlobal: => T, ifThis: => T): T = this match {
|
||||||
|
case This => ifThis
|
||||||
|
case Global => ifGlobal
|
||||||
|
case Select(s) => f(s)
|
||||||
|
}
|
||||||
|
def toOption: Option[S] = foldStrict(some.fn, None, None)
|
||||||
|
def map[T](f: S => T): ScopeAxis[T] = foldStrict(s => Select(f(s)), Global, This)
|
||||||
|
def isSelect: Boolean = false
|
||||||
|
}
|
||||||
|
case object This extends ScopeAxis[Nothing]
|
||||||
|
case object Global extends ScopeAxis[Nothing]
|
||||||
|
final case class Select[S](s: S) extends ScopeAxis[S] {
|
||||||
|
override def isSelect = true
|
||||||
|
}
|
||||||
|
object ScopeAxis
|
||||||
|
{
|
||||||
|
implicit def scopeAxisToScope(axis: ScopeAxis[Nothing]): Scope =
|
||||||
|
Scope(axis, axis, axis, axis)
|
||||||
|
def fromOption[T](o: Option[T]): ScopeAxis[T] = o match {
|
||||||
|
case Some(v) => Select(v)
|
||||||
|
case None => Global
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
/** Specifies the Scope axes that should be used for an operation. `true` indicates an axis should be used. */
|
||||||
|
final case class ScopeMask(project: Boolean = true, config: Boolean = true, task: Boolean = true, extra: Boolean = true)
|
||||||
|
{
|
||||||
|
def concatShow(p: String, c: String, t: String, sep: String, x: String): String =
|
||||||
|
{
|
||||||
|
val sb = new StringBuilder
|
||||||
|
if(project) sb.append(p)
|
||||||
|
if(config) sb.append(c)
|
||||||
|
if(task) sb.append(t)
|
||||||
|
sb.append(sep)
|
||||||
|
if(extra) sb.append(x)
|
||||||
|
sb.toString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,14 +5,16 @@ package sbt
|
||||||
|
|
||||||
/** An abstraction on top of Settings for build configuration and task definition. */
|
/** An abstraction on top of Settings for build configuration and task definition. */
|
||||||
|
|
||||||
import Types._
|
|
||||||
import std.TaskExtra.{task => mktask, _}
|
|
||||||
import Task._
|
|
||||||
import Project.{Initialize, KeyedInitialize, ScopedKey, Setting, setting}
|
|
||||||
import complete.Parser
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
|
import complete.Parser
|
||||||
|
import ConcurrentRestrictions.Tag
|
||||||
|
import Def.{Initialize, KeyedInitialize, ScopedKey, Setting, setting}
|
||||||
import Path._
|
import Path._
|
||||||
|
import std.TaskExtra.{task => mktask, _}
|
||||||
|
import Task._
|
||||||
|
import Types._
|
||||||
|
|
||||||
/** Parses input and produces a task to run. Constructed using the companion object. */
|
/** Parses input and produces a task to run. Constructed using the companion object. */
|
||||||
sealed trait InputTask[T] {
|
sealed trait InputTask[T] {
|
||||||
|
|
@ -43,7 +45,7 @@ object InputTask
|
||||||
def free[I,T](p: State => Parser[I])(c: I => Task[T]): InputTask[T] = free(s => p(s) map c)
|
def free[I,T](p: State => Parser[I])(c: I => Task[T]): InputTask[T] = free(s => p(s) map c)
|
||||||
|
|
||||||
def separate[I,T](p: State => Parser[I])(action: Initialize[I => Task[T]]): Initialize[InputTask[T]] =
|
def separate[I,T](p: State => Parser[I])(action: Initialize[I => Task[T]]): Initialize[InputTask[T]] =
|
||||||
separate(Project value p)(action)
|
separate(Def value p)(action)
|
||||||
def separate[I,T](p: Initialize[State => Parser[I]])(action: Initialize[I => Task[T]]): Initialize[InputTask[T]] =
|
def separate[I,T](p: Initialize[State => Parser[I]])(action: Initialize[I => Task[T]]): Initialize[InputTask[T]] =
|
||||||
p.zipWith(action)((parser, act) => free(parser)(act))
|
p.zipWith(action)((parser, act) => free(parser)(act))
|
||||||
|
|
||||||
|
|
@ -56,8 +58,8 @@ object InputTask
|
||||||
// However, this results in a minimal interface to the full capabilities of an InputTask for users
|
// However, this results in a minimal interface to the full capabilities of an InputTask for users
|
||||||
def apply[I,T](p: Initialize[State => Parser[I]])(action: TaskKey[I] => Initialize[Task[T]]): Initialize[InputTask[T]] =
|
def apply[I,T](p: Initialize[State => Parser[I]])(action: TaskKey[I] => Initialize[Task[T]]): Initialize[InputTask[T]] =
|
||||||
{
|
{
|
||||||
val key: TaskKey[I] = Keys.parseResult.asInstanceOf[TaskKey[I]]
|
val key: TaskKey[I] = Def.parseResult.asInstanceOf[TaskKey[I]]
|
||||||
(p zip Keys.resolvedScoped zipWith action(key)) { case ((parserF, scoped), act) =>
|
(p zip Def.resolvedScoped zipWith action(key)) { case ((parserF, scoped), act) =>
|
||||||
new InputDynamic[T]
|
new InputDynamic[T]
|
||||||
{
|
{
|
||||||
type Result = I
|
type Result = I
|
||||||
|
|
@ -68,7 +70,7 @@ object InputTask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def apply[I,T](p: State => Parser[I])(action: TaskKey[I] => Initialize[Task[T]]): Initialize[InputTask[T]] =
|
def apply[I,T](p: State => Parser[I])(action: TaskKey[I] => Initialize[Task[T]]): Initialize[InputTask[T]] =
|
||||||
apply(Project.value(p))(action)
|
apply(Def.value(p))(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait Scoped { def scope: Scope; val key: AttributeKey[_] }
|
sealed trait Scoped { def scope: Scope; val key: AttributeKey[_] }
|
||||||
|
|
@ -153,13 +155,13 @@ object Scoped
|
||||||
def scopedKey: ScopedKey[S]
|
def scopedKey: ScopedKey[S]
|
||||||
|
|
||||||
private[sbt] final def :==(value: S): Setting[S] = :=(value)
|
private[sbt] final def :==(value: S): Setting[S] = :=(value)
|
||||||
final def := (value: => S): Setting[S] = setting(scopedKey, Project.value(value))
|
final def := (value: => S): Setting[S] = setting(scopedKey, Def.value(value))
|
||||||
final def ~= (f: S => S): Setting[S] = Project.update(scopedKey)(f)
|
final def ~= (f: S => S): Setting[S] = Def.update(scopedKey)(f)
|
||||||
final def <<= (app: Initialize[S]): Setting[S] = setting(scopedKey, app)
|
final def <<= (app: Initialize[S]): Setting[S] = setting(scopedKey, app)
|
||||||
final def get(settings: Settings[Scope]): Option[S] = settings.get(scopedKey.scope, scopedKey.key)
|
final def get(settings: Settings[Scope]): Option[S] = settings.get(scopedKey.scope, scopedKey.key)
|
||||||
final def ? : Initialize[Option[S]] = Project.optional(scopedKey)(idFun)
|
final def ? : Initialize[Option[S]] = Def.optional(scopedKey)(idFun)
|
||||||
final def or[T >: S](i: Initialize[T]): Initialize[T] = (this.?, i)(_ getOrElse _ )
|
final def or[T >: S](i: Initialize[T]): Initialize[T] = (this.?, i)(_ getOrElse _ )
|
||||||
final def ??[T >: S](or: => T): Initialize[T] = Project.optional(scopedKey)(_ getOrElse or )
|
final def ??[T >: S](or: => T): Initialize[T] = Def.optional(scopedKey)(_ getOrElse or )
|
||||||
}
|
}
|
||||||
final class RichInitialize[S](init: Initialize[S])
|
final class RichInitialize[S](init: Initialize[S])
|
||||||
{
|
{
|
||||||
|
|
@ -172,12 +174,12 @@ object Scoped
|
||||||
{ self: TaskKey[S] =>
|
{ self: TaskKey[S] =>
|
||||||
|
|
||||||
private[sbt] def :==(value: S): Setting[Task[S]] = :=(value)
|
private[sbt] def :==(value: S): Setting[Task[S]] = :=(value)
|
||||||
private[sbt] def ::=(value: Task[S]): Setting[Task[S]] = Project.setting(scopedKey, Project.value( value ))
|
private[sbt] def ::=(value: Task[S]): Setting[Task[S]] = Def.setting(scopedKey, Def.value( value ))
|
||||||
def := (value: => S): Setting[Task[S]] = ::=(mktask(value))
|
def := (value: => S): Setting[Task[S]] = ::=(mktask(value))
|
||||||
private[sbt] def :== (v: SettingKey[S]): Setting[Task[S]] = <<=( v(constant))
|
private[sbt] def :== (v: SettingKey[S]): Setting[Task[S]] = <<=( v(constant))
|
||||||
def ~= (f: S => S): Setting[Task[S]] = Project.update(scopedKey)( _ map f )
|
def ~= (f: S => S): Setting[Task[S]] = Def.update(scopedKey)( _ map f )
|
||||||
|
|
||||||
def <<= (app: Initialize[Task[S]]): Setting[Task[S]] = Project.setting(scopedKey, app)
|
def <<= (app: Initialize[Task[S]]): Setting[Task[S]] = Def.setting(scopedKey, app)
|
||||||
|
|
||||||
def task: SettingKey[Task[S]] = scopedSetting(scope, key)
|
def task: SettingKey[Task[S]] = scopedSetting(scope, key)
|
||||||
def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key)
|
def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key)
|
||||||
|
|
@ -185,8 +187,8 @@ object Scoped
|
||||||
@deprecated("A call to 'identity' is no longer necessary and can be removed.", "0.11.0")
|
@deprecated("A call to 'identity' is no longer necessary and can be removed.", "0.11.0")
|
||||||
def identity: Initialize[Task[S]] = this
|
def identity: Initialize[Task[S]] = this
|
||||||
|
|
||||||
def ? : Initialize[Task[Option[S]]] = Project.optional(scopedKey) { case None => mktask { None }; case Some(t) => t map some.fn }
|
def ? : Initialize[Task[Option[S]]] = Def.optional(scopedKey) { case None => mktask { None }; case Some(t) => t map some.fn }
|
||||||
def ??[T >: S](or: => T): Initialize[Task[T]] = Project.optional(scopedKey)( _ getOrElse mktask(or) )
|
def ??[T >: S](or: => T): Initialize[Task[T]] = Def.optional(scopedKey)( _ getOrElse mktask(or) )
|
||||||
def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = (this.? zipWith i)( (x,y) => (x :^: y :^: KNil) map hf2( _ getOrElse _ ))
|
def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = (this.? zipWith i)( (x,y) => (x :^: y :^: KNil) map hf2( _ getOrElse _ ))
|
||||||
}
|
}
|
||||||
final class RichInitializeTask[S](i: Initialize[Task[S]]) extends RichInitTaskBase[S, Task]
|
final class RichInitializeTask[S](i: Initialize[Task[S]]) extends RichInitTaskBase[S, Task]
|
||||||
|
|
@ -195,17 +197,8 @@ object Scoped
|
||||||
|
|
||||||
def dependsOn(tasks: AnyInitTask*): Initialize[Task[S]] = (i, Initialize.joinAny(tasks)) { (thisTask, deps) => thisTask.dependsOn(deps : _*) }
|
def dependsOn(tasks: AnyInitTask*): Initialize[Task[S]] = (i, Initialize.joinAny(tasks)) { (thisTask, deps) => thisTask.dependsOn(deps : _*) }
|
||||||
|
|
||||||
import SessionVar.{persistAndSet, resolveContext, set, transform}
|
def triggeredBy(tasks: AnyInitTask*): Initialize[Task[S]] = nonLocal(tasks, Def.triggeredBy)
|
||||||
|
def runBefore(tasks: AnyInitTask*): Initialize[Task[S]] = nonLocal(tasks, Def.runBefore)
|
||||||
def updateState(f: (State, S) => State): Initialize[Task[S]] = onTask(t => transform(t, f))
|
|
||||||
def storeAs(key: TaskKey[S])(implicit f: sbinary.Format[S]): Initialize[Task[S]] = (Keys.resolvedScoped, i) { (scoped, task) =>
|
|
||||||
transform(task, (state, value) => persistAndSet( resolveContext(key, scoped.scope, state), state, value)(f))
|
|
||||||
}
|
|
||||||
def keepAs(key: TaskKey[S]): Initialize[Task[S]] =
|
|
||||||
(i, Keys.resolvedScoped)( (t,scoped) => transform(t, (state,value) => set(resolveContext(key, scoped.scope, state), state, value) ) )
|
|
||||||
|
|
||||||
def triggeredBy(tasks: AnyInitTask*): Initialize[Task[S]] = nonLocal(tasks, Keys.triggeredBy)
|
|
||||||
def runBefore(tasks: AnyInitTask*): Initialize[Task[S]] = nonLocal(tasks, Keys.runBefore)
|
|
||||||
private[this] def nonLocal(tasks: Seq[AnyInitTask], key: AttributeKey[Seq[Task[_]]]): Initialize[Task[S]] =
|
private[this] def nonLocal(tasks: Seq[AnyInitTask], key: AttributeKey[Seq[Task[_]]]): Initialize[Task[S]] =
|
||||||
(Initialize.joinAny(tasks), i) { (ts, i) => i.copy(info = i.info.set(key, ts)) }
|
(Initialize.joinAny(tasks), i) { (ts, i) => i.copy(info = i.info.set(key, ts)) }
|
||||||
}
|
}
|
||||||
|
|
@ -231,8 +224,8 @@ object Scoped
|
||||||
def || [T >: S](alt: Task[T]): Initialize[R[T]] = onTask(_ || alt)
|
def || [T >: S](alt: Task[T]): Initialize[R[T]] = onTask(_ || alt)
|
||||||
def && [T](alt: Task[T]): Initialize[R[T]] = onTask(_ && alt)
|
def && [T](alt: Task[T]): Initialize[R[T]] = onTask(_ && alt)
|
||||||
|
|
||||||
def tag(tags: Tags.Tag*): Initialize[R[S]] = onTask(_.tag(tags: _*))
|
def tag(tags: Tag*): Initialize[R[S]] = onTask(_.tag(tags: _*))
|
||||||
def tagw(tags: (Tags.Tag, Int)*): Initialize[R[S]] = onTask(_.tagw(tags : _*))
|
def tagw(tags: (Tag, Int)*): Initialize[R[S]] = onTask(_.tagw(tags : _*))
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnyInitTask = Initialize[Task[T]] forSome { type T }
|
type AnyInitTask = Initialize[Task[T]] forSome { type T }
|
||||||
|
|
@ -308,7 +301,7 @@ object Scoped
|
||||||
}
|
}
|
||||||
|
|
||||||
def combine[D[_],S](c: Combine[D], f: Results[HLv] => D[S]): Initialize[Task[S]] =
|
def combine[D[_],S](c: Combine[D], f: Results[HLv] => D[S]): Initialize[Task[S]] =
|
||||||
Project.app(settings)(hls => c(tasks(hls))(hlt => f(expand(hls, hlt))) )
|
Def.app(settings)(hls => c(tasks(hls))(hlt => f(expand(hls, hlt))) )
|
||||||
}
|
}
|
||||||
type RedHL[HL <: HList] = Reduced[_,_,HL]
|
type RedHL[HL <: HList] = Reduced[_,_,HL]
|
||||||
def reduced[HL <: HList](settings: KList[ScopedTaskable, HL]): Reduced[_,_,HL] =
|
def reduced[HL <: HList](settings: KList[ScopedTaskable, HL]): Reduced[_,_,HL] =
|
||||||
|
|
@ -519,59 +512,59 @@ object Scoped
|
||||||
def mkTuple15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = (a:A,b:B,c:C,d:D,e:E,f:F,g:G,h:H,i:I,j:J,k:K,l:L,n:N,o:O,p:P) => (a,b,c,d,e,f,g,h,i,j,k,l,n,o,p)
|
def mkTuple15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = (a:A,b:B,c:C,d:D,e:E,f:F,g:G,h:H,i:I,j:J,k:K,l:L,n:N,o:O,p:P) => (a,b,c,d,e,f,g,h,i,j,k,l,n,o,p)
|
||||||
|
|
||||||
final class Apply2[A,B](t2: (Initialize[A], Initialize[B])) {
|
final class Apply2[A,B](t2: (Initialize[A], Initialize[B])) {
|
||||||
def apply[T](z: (A,B) => T) = Project.app( k2(t2) )( hf2(z) )
|
def apply[T](z: (A,B) => T) = Def.app( k2(t2) )( hf2(z) )
|
||||||
def identity = apply(mkTuple2)
|
def identity = apply(mkTuple2)
|
||||||
}
|
}
|
||||||
final class Apply3[A,B,C](t3: (Initialize[A], Initialize[B], Initialize[C])) {
|
final class Apply3[A,B,C](t3: (Initialize[A], Initialize[B], Initialize[C])) {
|
||||||
def apply[T](z: (A,B,C) => T) = Project.app( k3(t3) )( hf3(z) )
|
def apply[T](z: (A,B,C) => T) = Def.app( k3(t3) )( hf3(z) )
|
||||||
def identity = apply(mkTuple3)
|
def identity = apply(mkTuple3)
|
||||||
}
|
}
|
||||||
final class Apply4[A,B,C,D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])) {
|
final class Apply4[A,B,C,D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])) {
|
||||||
def apply[T](z: (A,B,C,D) => T) = Project.app( k4(t4) )( hf4(z) )
|
def apply[T](z: (A,B,C,D) => T) = Def.app( k4(t4) )( hf4(z) )
|
||||||
def identity = apply(mkTuple4)
|
def identity = apply(mkTuple4)
|
||||||
}
|
}
|
||||||
final class Apply5[A,B,C,D,E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])) {
|
final class Apply5[A,B,C,D,E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])) {
|
||||||
def apply[T](z: (A,B,C,D,E) => T) = Project.app( k5(t5) )( hf5(z) )
|
def apply[T](z: (A,B,C,D,E) => T) = Def.app( k5(t5) )( hf5(z) )
|
||||||
def identity = apply(mkTuple5)
|
def identity = apply(mkTuple5)
|
||||||
}
|
}
|
||||||
final class Apply6[A,B,C,D,E,F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])) {
|
final class Apply6[A,B,C,D,E,F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F) => T) = Project.app( k6(t6) )( hf6(z) )
|
def apply[T](z: (A,B,C,D,E,F) => T) = Def.app( k6(t6) )( hf6(z) )
|
||||||
def identity = apply(mkTuple6)
|
def identity = apply(mkTuple6)
|
||||||
}
|
}
|
||||||
final class Apply7[A,B,C,D,E,F,G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])) {
|
final class Apply7[A,B,C,D,E,F,G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G) => T) = Project.app( k7(t7) )( hf7(z) )
|
def apply[T](z: (A,B,C,D,E,F,G) => T) = Def.app( k7(t7) )( hf7(z) )
|
||||||
def identity = apply(mkTuple7)
|
def identity = apply(mkTuple7)
|
||||||
}
|
}
|
||||||
final class Apply8[A,B,C,D,E,F,G,H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])) {
|
final class Apply8[A,B,C,D,E,F,G,H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H) => T) = Project.app( k8(t8) )( hf8(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H) => T) = Def.app( k8(t8) )( hf8(z) )
|
||||||
def identity = apply(mkTuple8)
|
def identity = apply(mkTuple8)
|
||||||
}
|
}
|
||||||
final class Apply9[A,B,C,D,E,F,G,H,I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])) {
|
final class Apply9[A,B,C,D,E,F,G,H,I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I) => T) = Project.app( k9(t9) )( hf9(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I) => T) = Def.app( k9(t9) )( hf9(z) )
|
||||||
def identity = apply(mkTuple9)
|
def identity = apply(mkTuple9)
|
||||||
}
|
}
|
||||||
final class Apply10[A,B,C,D,E,F,G,H,I,J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])) {
|
final class Apply10[A,B,C,D,E,F,G,H,I,J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I,J) => T) = Project.app( k10(t10) )( hf10(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I,J) => T) = Def.app( k10(t10) )( hf10(z) )
|
||||||
def identity = apply(mkTuple10)
|
def identity = apply(mkTuple10)
|
||||||
}
|
}
|
||||||
final class Apply11[A,B,C,D,E,F,G,H,I,J,K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])) {
|
final class Apply11[A,B,C,D,E,F,G,H,I,J,K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K) => T) = Project.app( k11(t11) )( hf11(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K) => T) = Def.app( k11(t11) )( hf11(z) )
|
||||||
def identity = apply(mkTuple11)
|
def identity = apply(mkTuple11)
|
||||||
}
|
}
|
||||||
final class Apply12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L])) {
|
final class Apply12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L) => T) = Project.app( k12(t12) )( hf12(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L) => T) = Def.app( k12(t12) )( hf12(z) )
|
||||||
def identity = apply(mkTuple12)
|
def identity = apply(mkTuple12)
|
||||||
}
|
}
|
||||||
final class Apply13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N])) {
|
final class Apply13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N) => T) = Project.app( k13(t13) )( hf13(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N) => T) = Def.app( k13(t13) )( hf13(z) )
|
||||||
def identity = apply(mkTuple13)
|
def identity = apply(mkTuple13)
|
||||||
}
|
}
|
||||||
final class Apply14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O])) {
|
final class Apply14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O) => T) = Project.app( k14(t14) )( hf14(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O) => T) = Def.app( k14(t14) )( hf14(z) )
|
||||||
def identity = apply(mkTuple14)
|
def identity = apply(mkTuple14)
|
||||||
}
|
}
|
||||||
final class Apply15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O], Initialize[P])) {
|
final class Apply15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O], Initialize[P])) {
|
||||||
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O,P) => T) = Project.app( k15(t15) )( hf15(z) )
|
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O,P) => T) = Def.app( k15(t15) )( hf15(z) )
|
||||||
def identity = apply(mkTuple15)
|
def identity = apply(mkTuple15)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,10 +120,14 @@ object Sbt extends Build
|
||||||
classpathSub, completeSub, apiSub, compilerIntegrationSub, compilerIvySub,
|
classpathSub, completeSub, apiSub, compilerIntegrationSub, compilerIvySub,
|
||||||
interfaceSub, ioSub, ivySub, logSub, processSub, runSub, relationSub, stdTaskSub, taskSub, trackingSub, testingSub)
|
interfaceSub, ioSub, ivySub, logSub, processSub, runSub, relationSub, stdTaskSub, taskSub, trackingSub, testingSub)
|
||||||
|
|
||||||
|
// General command support and core commands not specific to a build system
|
||||||
lazy val commandSub = testedBaseProject(commandPath, "Command") dependsOn(interfaceSub, ioSub, launchInterfaceSub, logSub, completeSub, classpathSub)
|
lazy val commandSub = testedBaseProject(commandPath, "Command") dependsOn(interfaceSub, ioSub, launchInterfaceSub, logSub, completeSub, classpathSub)
|
||||||
|
// Fixes scope=Scope for Setting (core defined in collectionSub) to define the settings system used in build definitions
|
||||||
|
lazy val settingsSub = testedBaseProject(settingsPath, "Settings") dependsOn(interfaceSub, ivySub, relationSub, logSub, ioSub, commandSub, completeSub,
|
||||||
|
classpathSub, stdTaskSub, processSub) settings( sbinary )
|
||||||
|
|
||||||
// The main integration project for sbt. It brings all of the subsystems together, configures them, and provides for overriding conventions.
|
// The main integration project for sbt. It brings all of the subsystems together, configures them, and provides for overriding conventions.
|
||||||
lazy val mainSub = testedBaseProject(mainPath, "Main") dependsOn(actionsSub, interfaceSub, ioSub, ivySub, launchInterfaceSub, logSub, processSub, runSub, commandSub)
|
lazy val mainSub = testedBaseProject(mainPath, "Main") dependsOn(actionsSub, settingsSub, interfaceSub, ioSub, ivySub, launchInterfaceSub, logSub, processSub, runSub, commandSub)
|
||||||
|
|
||||||
// Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object
|
// Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object
|
||||||
// technically, we need a dependency on all of mainSub's dependencies, but we don't do that since this is strictly an integration project
|
// technically, we need a dependency on all of mainSub's dependencies, but we don't do that since this is strictly an integration project
|
||||||
|
|
@ -139,6 +143,7 @@ object Sbt extends Build
|
||||||
def compilePath = file("compile")
|
def compilePath = file("compile")
|
||||||
def mainPath = file("main")
|
def mainPath = file("main")
|
||||||
def commandPath = mainPath / "command"
|
def commandPath = mainPath / "command"
|
||||||
|
def settingsPath = mainPath / "settings"
|
||||||
def scriptedPath = file("scripted")
|
def scriptedPath = file("scripted")
|
||||||
|
|
||||||
def sbtSettings = Seq(
|
def sbtSettings = Seq(
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ final case class Attributed[D](data: D)(val metadata: AttributeMap)
|
||||||
}
|
}
|
||||||
object Attributed
|
object Attributed
|
||||||
{
|
{
|
||||||
|
def data[T](in: Seq[Attributed[T]]): Seq[T] = in.map(_.data)
|
||||||
def blankSeq[T](in: Seq[T]): Seq[Attributed[T]] = in map blank
|
def blankSeq[T](in: Seq[T]): Seq[Attributed[T]] = in map blank
|
||||||
def blank[T](data: T): Attributed[T] = Attributed(data)(AttributeMap.empty)
|
def blank[T](data: T): Attributed[T] = Attributed(data)(AttributeMap.empty)
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue