mirror of https://github.com/sbt/sbt.git
try out simplified display of scoped keys
This commit is contained in:
parent
70113c88fa
commit
a19d5a799c
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
package sbt
|
||||
|
||||
import Project.ScopedKey
|
||||
import Project.{ScopedKey, showContextKey}
|
||||
import Keys.{sessionSettings, thisProject}
|
||||
import Load.BuildStructure
|
||||
import complete.{DefaultParsers, Parser}
|
||||
|
|
@ -143,8 +143,9 @@ object Act
|
|||
private[this] def actParser0(state: State) =
|
||||
{
|
||||
val extracted = Project extract state
|
||||
import extracted.{showKey, structure}
|
||||
showParser.flatMap { show =>
|
||||
scopedKeyParser(extracted) flatMap Aggregation.valueParser(state, extracted.structure, show)
|
||||
scopedKeyParser(extracted) flatMap Aggregation.valueParser(state, structure, show)
|
||||
}
|
||||
}
|
||||
def showParser = token( ("show" ~ Space) ^^^ true) ?? false
|
||||
|
|
|
|||
|
|
@ -60,21 +60,21 @@ final object Aggregation
|
|||
case Some(current) => Scope.resolveBuildOnly(current, ref)
|
||||
}
|
||||
|
||||
def printSettings[T](xs: Seq[KeyValue[T]], log: Logger) =
|
||||
def printSettings[T](xs: Seq[KeyValue[T]], log: Logger)(implicit display: Show[ScopedKey[_]]) =
|
||||
xs match
|
||||
{
|
||||
case KeyValue(_,x) :: Nil => log.info(x.toString)
|
||||
case _ => xs foreach { case KeyValue(key, value) => log.info(Project.display(key) + "\n\t" + value.toString) }
|
||||
case _ => xs foreach { case KeyValue(key, value) => log.info(display(key) + "\n\t" + value.toString) }
|
||||
}
|
||||
type Values[T] = Seq[KeyValue[T]]
|
||||
def seqParser[T](ps: Values[Parser[T]]): Parser[Seq[KeyValue[T]]] = seq(ps.map { case KeyValue(k,p) => p.map(v => KeyValue(k,v) ) })
|
||||
|
||||
def applyTasks[T](s: State, structure: BuildStructure, ps: Values[Parser[Task[T]]], show: Boolean): Parser[() => State] =
|
||||
def applyTasks[T](s: State, structure: BuildStructure, ps: Values[Parser[Task[T]]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
Command.applyEffect(seqParser(ps)) { ts =>
|
||||
runTasks(s, structure, ts, Dummies(KNil, HNil), show)
|
||||
s
|
||||
}
|
||||
def runTasks[HL <: HList, T](s: State, structure: Load.BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)
|
||||
def runTasks[HL <: HList, T](s: State, structure: Load.BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]])
|
||||
{
|
||||
import EvaluateTask._
|
||||
import std.TaskExtra._
|
||||
|
|
@ -129,7 +129,7 @@ final object Aggregation
|
|||
}
|
||||
|
||||
final case class Dummies[HL <: HList](tasks: KList[Task,HL], values: HL)
|
||||
def applyDynamicTasks[I](s: State, structure: BuildStructure, inputs: Values[InputDynamic[I]], show: Boolean): Parser[() => State] =
|
||||
def applyDynamicTasks[I](s: State, structure: BuildStructure, inputs: Values[InputDynamic[I]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
{
|
||||
val parsers = inputs.map { case KeyValue(k,t) => KeyValue(k, t parser s) }
|
||||
Command.applyEffect(seqParser(parsers)) { parseds =>
|
||||
|
|
@ -141,10 +141,10 @@ final object Aggregation
|
|||
s
|
||||
}
|
||||
}
|
||||
def valueParser(s: State, structure: BuildStructure, show: Boolean)(key: ScopedKey[_]): Parser[() => State] =
|
||||
def valueParser(s: State, structure: BuildStructure, show: Boolean)(key: ScopedKey[_])(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
|
||||
getTasks(key, structure, true).toList match
|
||||
{
|
||||
case Nil => failure("No such setting/task: " + (Project display key))
|
||||
case Nil => failure("No such setting/task: " + display(key))
|
||||
case xs @ KeyValue(_, _: InputStatic[t]) :: _ => applyTasks(s, structure, maps(xs.asInstanceOf[Values[InputStatic[t]]])(_.parser(s)), show)
|
||||
case xs @ KeyValue(_, _: InputDynamic[t]) :: _ => applyDynamicTasks(s, structure, xs.asInstanceOf[Values[InputDynamic[t]]], show)
|
||||
case xs @ KeyValue(_, _: Task[t]) :: _ => applyTasks(s, structure, maps(xs.asInstanceOf[Values[Task[t]]])(x => success(x)), show)
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ object Index
|
|||
object BuildStreams
|
||||
{
|
||||
import Load.{BuildStructure, LoadedBuildUnit}
|
||||
import Project.display
|
||||
import Project.displayFull
|
||||
import std.{TaskExtra,Transform}
|
||||
import Path._
|
||||
import BuildPaths.outputDirectory
|
||||
|
|
@ -209,7 +209,7 @@ object BuildStreams
|
|||
final val StreamsDirectory = "streams"
|
||||
|
||||
def mkStreams(units: Map[URI, LoadedBuildUnit], root: URI, data: Settings[Scope]): Streams =
|
||||
std.Streams( path(units, root, data), display, LogManager.construct(data) )
|
||||
std.Streams( path(units, root, data), displayFull, LogManager.construct(data) )
|
||||
|
||||
def path(units: Map[URI, LoadedBuildUnit], root: URI, data: Settings[Scope])(scoped: ScopedKey[_]): File =
|
||||
resolvePath( projectPath(units, root, scoped, data), nonProjectPath(scoped) )
|
||||
|
|
@ -221,7 +221,7 @@ object BuildStreams
|
|||
axis match
|
||||
{
|
||||
case Global => GlobalPath
|
||||
case This => error("Unresolved This reference for " + label + " in " + display(scoped))
|
||||
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] =
|
||||
|
|
@ -240,8 +240,8 @@ object BuildStreams
|
|||
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 " + display(scoped))
|
||||
case This => error("Unresolved project reference (This) in " + display(scoped))
|
||||
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 =
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ object Defaults extends BuildCommon
|
|||
override def watchPaths(s: State) = EvaluateTask.evaluateTask(Project structure s, key, s, base) match {
|
||||
case Some(Value(ps)) => ps
|
||||
case Some(Inc(i)) => throw i
|
||||
case None => error("key not found: " + Project.display(key))
|
||||
case None => error("key not found: " + Project.displayFull(key))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -244,14 +244,16 @@ object Defaults extends BuildCommon
|
|||
definedTests <<= TaskData.writeRelated(detectTests)(_.map(_.name).distinct) triggeredBy compile,
|
||||
testListeners in GlobalScope :== Nil,
|
||||
testOptions in GlobalScope :== Nil,
|
||||
executeTests <<= (streams in test, loadedTestFrameworks, parallelExecution in test, testOptions in test, testLoader, definedTests, resolvedScoped) flatMap {
|
||||
(s, frameworkMap, par, options, loader, discovered, scoped) => Tests(frameworkMap, loader, discovered, options, par, noTestsMessage(ScopedKey(scoped.scope, test.key)), s.log)
|
||||
executeTests <<= (streams in test, loadedTestFrameworks, parallelExecution in test, testOptions in test, testLoader, definedTests, resolvedScoped, state) flatMap {
|
||||
(s, frameworkMap, par, options, loader, discovered, scoped, st) =>
|
||||
implicit val display = Project.showContextKey(st)
|
||||
Tests(frameworkMap, loader, discovered, options, par, noTestsMessage(ScopedKey(scoped.scope, test.key)), s.log)
|
||||
},
|
||||
test <<= (executeTests, streams) map { (results, s) => Tests.showResults(s.log, results) },
|
||||
testOnly <<= testOnlyTask
|
||||
)
|
||||
private[this] def noTestsMessage(scoped: ScopedKey[_]): String =
|
||||
"No tests to run for " + Project.display(scoped)
|
||||
private[this] def noTestsMessage(scoped: ScopedKey[_])(implicit display: Show[ScopedKey[_]]): String =
|
||||
"No tests to run for " + display(scoped)
|
||||
|
||||
lazy val TaskGlobal: Scope = ThisScope.copy(task = Global)
|
||||
def testTaskOptions(key: Scoped): Seq[Setting[_]] = inTask(key)( Seq(
|
||||
|
|
@ -276,10 +278,11 @@ object Defaults extends BuildCommon
|
|||
|
||||
def testOnlyTask =
|
||||
InputTask( TaskData(definedTests)(testOnlyParser)(Nil) ) { result =>
|
||||
(streams, loadedTestFrameworks, parallelExecution in testOnly, testOptions in testOnly, testLoader, definedTests, resolvedScoped, result) flatMap {
|
||||
case (s, frameworks, par, opts, loader, discovered, scoped, (tests, frameworkOptions)) =>
|
||||
(streams, loadedTestFrameworks, parallelExecution in testOnly, testOptions in testOnly, testLoader, definedTests, resolvedScoped, result, state) flatMap {
|
||||
case (s, frameworks, par, opts, loader, discovered, scoped, (tests, frameworkOptions), st) =>
|
||||
val filter = selectedFilter(tests)
|
||||
val modifiedOpts = Tests.Filter(filter) +: Tests.Argument(frameworkOptions : _*) +: opts
|
||||
implicit val display = Project.showContextKey(st)
|
||||
Tests(frameworks, loader, discovered, modifiedOpts, par, noTestsMessage(scoped), s.log) map { results =>
|
||||
Tests.showResults(s.log, results)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ object EvaluateTask
|
|||
case _ => c.toString
|
||||
}
|
||||
def name(node: Task[_]): String =
|
||||
node.info.name orElse transformNode(node).map(Project.display) getOrElse ("<anon-" + System.identityHashCode(node).toHexString + ">")
|
||||
node.info.name orElse transformNode(node).map(Project.displayFull) getOrElse ("<anon-" + System.identityHashCode(node).toHexString + ">")
|
||||
def liftAnonymous: Incomplete => Incomplete = {
|
||||
case i @ Incomplete(node, tpe, None, causes, None) =>
|
||||
causes.find( inc => !inc.node.isDefined && (inc.message.isDefined || inc.directCause.isDefined)) match {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ object Load
|
|||
lazy val rootEval = lazyEval(loaded.units(loaded.root).unit)
|
||||
val settings = finalTransforms(buildConfigurations(loaded, getRootProject(projects), rootEval, config.injectSettings))
|
||||
val delegates = config.delegates(loaded)
|
||||
val data = Project.makeSettings(settings, delegates, config.scopeLocal)
|
||||
val data = Project.makeSettings(settings, delegates, config.scopeLocal)( Project.showLoadingKey( loaded ) )
|
||||
val index = structureIndex(data, settings)
|
||||
val streams = mkStreams(projects, loaded.root, data)
|
||||
(rootEval, new BuildStructure(projects, loaded.root, settings, data, index, streams, delegates, config.scopeLocal))
|
||||
|
|
@ -150,7 +150,7 @@ object Load
|
|||
case resolvedScoped.key => Some(defining.asInstanceOf[T])
|
||||
case parseResult.key =>
|
||||
import std.TaskExtra._
|
||||
val getResult = InputTask.inputMap map { m => m get defining getOrElse error("No parsed value for " + Project.display(defining) + "\n" + m) }
|
||||
val getResult = InputTask.inputMap map { m => m get defining getOrElse error("No parsed value for " + Project.displayFull(defining) + "\n" + m) }
|
||||
Some(getResult.asInstanceOf[T])
|
||||
case _ => None
|
||||
}
|
||||
|
|
@ -169,7 +169,7 @@ object Load
|
|||
}
|
||||
|
||||
// Reevaluates settings after modifying them. Does not recompile or reload any build components.
|
||||
def reapply(newSettings: Seq[Setting[_]], structure: BuildStructure): BuildStructure =
|
||||
def reapply(newSettings: Seq[Setting[_]], structure: BuildStructure)(implicit display: Show[ScopedKey[_]]): BuildStructure =
|
||||
{
|
||||
val transformed = finalTransforms(newSettings)
|
||||
val newData = Project.makeSettings(transformed, structure.delegates, structure.scopeLocal)
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ object BuiltinCommands
|
|||
def reapply(newSession: SessionSettings, structure: Load.BuildStructure, s: State): State =
|
||||
{
|
||||
logger(s).info("Reapplying settings...")
|
||||
val newStructure = Load.reapply(newSession.mergeSettings, structure)
|
||||
val newStructure = Load.reapply(newSession.mergeSettings, structure)( Project.showContextKey(newSession, structure) )
|
||||
Project.setProject(newSession, newStructure, s)
|
||||
}
|
||||
def set = Command.single(SetCommand, setBrief, setDetailed) { (s, arg) =>
|
||||
|
|
@ -327,14 +327,14 @@ object BuiltinCommands
|
|||
reapply(newSession, structure, s)
|
||||
}
|
||||
def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s,(actual,sk)) =>
|
||||
val detailString = Project.details(Project.structure(s), actual, sk.scope, sk.key)
|
||||
val detailString = Project.details(Project.structure(s), actual, sk.scope, sk.key)( Project.showContextKey(s) )
|
||||
logger(s).info(detailString)
|
||||
s
|
||||
}
|
||||
def lastGrep = Command(LastGrepCommand, lastGrepBrief, lastGrepDetailed)(lastGrepParser) {
|
||||
case (s, (pattern,Some(sk))) =>
|
||||
val (str, ref) = extractLast(s)
|
||||
Output.lastGrep(sk, str, pattern)
|
||||
val (str, ref, display) = extractLast(s)
|
||||
Output.lastGrep(sk, str, pattern)(display)
|
||||
s
|
||||
case (s, (pattern, None)) =>
|
||||
Output.lastGrep(CommandSupport.globalLogging(s).backing, pattern)
|
||||
|
|
@ -342,7 +342,7 @@ object BuiltinCommands
|
|||
}
|
||||
def extractLast(s: State) = {
|
||||
val ext = Project.extract(s)
|
||||
(ext.structure, Select(ext.currentRef))
|
||||
(ext.structure, Select(ext.currentRef), ext.showKey)
|
||||
}
|
||||
def inspectParser = (s: State) => token((Space ~> ("actual" ^^^ true)) ?? false) ~ spacedKeyParser(s)
|
||||
val spacedKeyParser = (s: State) => Act.requireSession(s, token(Space) ~> Act.scopedKeyParser(s))
|
||||
|
|
@ -350,8 +350,8 @@ object BuiltinCommands
|
|||
def lastGrepParser(s: State) = Act.requireSession(s, (token(Space) ~> token(NotSpace, "<pattern>")) ~ optSpacedKeyParser(s))
|
||||
def last = Command(LastCommand, lastBrief, lastDetailed)(optSpacedKeyParser) {
|
||||
case (s,Some(sk)) =>
|
||||
val (str, ref) = extractLast(s)
|
||||
Output.last(sk, str)
|
||||
val (str, ref, display) = extractLast(s)
|
||||
Output.last(sk, str)(display)
|
||||
s
|
||||
case (s, None) =>
|
||||
Output.last( CommandSupport.globalLogging(s).backing )
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ object Output
|
|||
}
|
||||
final val DefaultTail = "> "
|
||||
|
||||
def last(key: ScopedKey[_], structure: BuildStructure): Unit = printLines( flatLines(lastLines(key, structure))(idFun) )
|
||||
def last(key: ScopedKey[_], structure: BuildStructure)(implicit display: Show[ScopedKey[_]]): Unit = printLines( flatLines(lastLines(key, structure))(idFun) )
|
||||
def last(file: File, tailDelim: String = DefaultTail): Unit = printLines(tailLines(file, tailDelim))
|
||||
|
||||
def lastGrep(key: ScopedKey[_], structure: BuildStructure, patternString: String): Unit =
|
||||
def lastGrep(key: ScopedKey[_], structure: BuildStructure, patternString: String)(implicit display: Show[ScopedKey[_]]): Unit =
|
||||
{
|
||||
val pattern = Pattern compile patternString
|
||||
val lines = flatLines( lastLines(key, structure) )(_ flatMap showMatches(pattern))
|
||||
|
|
@ -44,12 +44,12 @@ object Output
|
|||
def grep(lines: Seq[String], patternString: String): Seq[String] =
|
||||
lines flatMap showMatches(Pattern compile patternString)
|
||||
|
||||
def flatLines(outputs: Seq[KeyValue[Seq[String]]])(f: Seq[String] => Seq[String]): Seq[String] =
|
||||
def flatLines(outputs: Seq[KeyValue[Seq[String]]])(f: Seq[String] => Seq[String])(implicit display: Show[ScopedKey[_]]): Seq[String] =
|
||||
{
|
||||
val single = outputs.size == 1
|
||||
outputs flatMap { case KeyValue(key, lines) =>
|
||||
val flines = f(lines)
|
||||
if(!single) bold(Project.display(key)) +: flines else flines
|
||||
if(!single) bold(display(key)) +: flines else flines
|
||||
}
|
||||
}
|
||||
def printLines(lines: Seq[String]) = lines foreach println
|
||||
|
|
|
|||
|
|
@ -61,14 +61,14 @@ sealed trait Project extends ProjectDefinition[ProjectReference]
|
|||
}
|
||||
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef]
|
||||
|
||||
final case class Extracted(structure: BuildStructure, session: SessionSettings, currentRef: 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: ScopedTask[T]): Task[T] = get(key.task)
|
||||
def get[T](key: ScopedSetting[T]): T = getOrError(inCurrent(key), key.key)
|
||||
def get[T](key: ScopedSetting[T]) = getOrError(inCurrent(key), key.key)
|
||||
def getOpt[T](key: ScopedSetting[T]): Option[T] = structure.data.get(inCurrent(key), key.key)
|
||||
private[this] def inCurrent[T](key: ScopedSetting[T]): Scope = if(key.scope.project == This) key.scope.copy(project = Select(currentRef)) else key.scope
|
||||
def evalTask[T](key: ScopedTask[T], state: State): T =
|
||||
|
|
@ -80,10 +80,10 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings,
|
|||
val result = getOrError(rkey.scope, rkey.key, value)
|
||||
processResult(result, ConsoleLogger())
|
||||
}
|
||||
private def getOrError[T](scope: Scope, key: AttributeKey[_], value: Option[T]): T =
|
||||
value getOrElse error(Project.display(ScopedKey(scope, key)) + " is undefined.")
|
||||
private def getOrError[T](scope: Scope, key: AttributeKey[T]): T =
|
||||
structure.data.get(scope, key) getOrElse error(Project.display(ScopedKey(scope, key)) + " is undefined.")
|
||||
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 =
|
||||
{
|
||||
|
|
@ -99,6 +99,21 @@ final case class ClasspathDependency(project: ProjectReference, configuration: O
|
|||
|
||||
object Project extends Init[Scope] with ProjectExtra
|
||||
{
|
||||
lazy val showFullKey: Show[ScopedKey[_]] = new Show[ScopedKey[_]] { def apply(key: ScopedKey[_]) = displayFull(key) }
|
||||
def showContextKey(state: State): Show[ScopedKey[_]] =
|
||||
if(isProjectLoaded(state)) showContextKey( session(state), structure(state) ) else showFullKey
|
||||
def showContextKey(session: SessionSettings, structure: BuildStructure): Show[ScopedKey[_]] = showRelativeKey(session.current, structure.allProjects.size > 1)
|
||||
def showLoadingKey(loaded: Load.LoadedBuild): Show[ScopedKey[_]] = showRelativeKey( ProjectRef(loaded.root, loaded.units(loaded.root).rootProjects.head), loaded.allProjectRefs.size > 1 )
|
||||
def showRelativeKey(current: ProjectRef, multi: Boolean): Show[ScopedKey[_]] = new Show[ScopedKey[_]] {
|
||||
def apply(key: ScopedKey[_]) = Scope.display(key.scope, key.key.label, 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]], delegates0: => Seq[PR],
|
||||
settings0: => Seq[Setting[_]], val configurations: Seq[Configuration]) extends ProjectDefinition[PR]
|
||||
{
|
||||
|
|
@ -130,7 +145,7 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
def isProjectLoaded(state: State): Boolean = (state has sessionSettings) && (state has stateBuildStructure)
|
||||
|
||||
def extract(state: State): Extracted = extract( session(state), structure(state) )
|
||||
def extract(se: SessionSettings, st: BuildStructure): Extracted = Extracted(st, se, se.current)
|
||||
def extract(se: SessionSettings, st: BuildStructure): Extracted = Extracted(st, se, se.current)( showContextKey(se, st) )
|
||||
|
||||
def getProjectForReference(ref: Reference, structure: BuildStructure): Option[ResolvedProject] =
|
||||
ref match { case pr: ProjectRef => getProject(pr, structure); case _ => None }
|
||||
|
|
@ -172,10 +187,10 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
}
|
||||
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) }
|
||||
def makeSettings(settings: Seq[Setting[_]], delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]]) =
|
||||
translateCyclic( make(settings)(delegates, scopeLocal) )
|
||||
def makeSettings(settings: Seq[Setting[_]], delegates: Scope => Seq[Scope], scopeLocal: ScopedKey[_] => Seq[Setting[_]])(implicit display: Show[ScopedKey[_]]) =
|
||||
translateCyclic( make(settings)(delegates, scopeLocal, display) )
|
||||
|
||||
def display(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)
|
||||
def displayFull(scoped: ScopedKey[_]): String = Scope.display(scoped.scope, scoped.key.label)
|
||||
def display(ref: Reference): String =
|
||||
ref match
|
||||
{
|
||||
|
|
@ -219,7 +234,7 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
def delegates(structure: BuildStructure, scope: Scope, key: AttributeKey[_]): Seq[ScopedKey[_]] =
|
||||
structure.delegates(scope).map(d => ScopedKey(d, key))
|
||||
|
||||
def details(structure: BuildStructure, actual: Boolean, scope: Scope, key: AttributeKey[_]): String =
|
||||
def details(structure: BuildStructure, actual: Boolean, scope: Scope, key: AttributeKey[_])(implicit display: Show[ScopedKey[_]]): String =
|
||||
{
|
||||
val scoped = ScopedKey(scope,key)
|
||||
lazy val clazz = key.manifest.erasure
|
||||
|
|
@ -242,12 +257,12 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
case Some(sc) => "Provided by:\n\t" + Scope.display(sc, key.label) + "\n"
|
||||
case None => ""
|
||||
}
|
||||
val cMap = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal)
|
||||
val cMap = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display)
|
||||
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 reverse = reverseDependencies(cMap, scoped)
|
||||
def printScopes(label: String, scopes: Iterable[ScopedKey[_]]) =
|
||||
if(scopes.isEmpty) "" else scopes.map(display).mkString(label + ":\n\t", "\n\t", "\n")
|
||||
if(scopes.isEmpty) "" else scopes.map(display.apply).mkString(label + ":\n\t", "\n\t", "\n")
|
||||
|
||||
value + "\n" +
|
||||
description +
|
||||
|
|
@ -257,22 +272,22 @@ object Project extends Init[Scope] with ProjectExtra
|
|||
printScopes("Delegates", delegates(structure, scope, key)) +
|
||||
printScopes("Related", related)
|
||||
}
|
||||
def graphSettings(structure: BuildStructure, basedir: File)
|
||||
def graphSettings(structure: BuildStructure, basedir: File)(implicit display: Show[ScopedKey[_]])
|
||||
{
|
||||
def graph(actual: Boolean, name: String) = graphSettings(structure, actual, name, new File(basedir, name + ".dot"))
|
||||
graph(true, "actual_dependencies")
|
||||
graph(false, "declared_dependencies")
|
||||
}
|
||||
def graphSettings(structure: BuildStructure, actual: Boolean, graphName: String, file: File)
|
||||
def graphSettings(structure: BuildStructure, actual: Boolean, graphName: String, file: File)(implicit display: Show[ScopedKey[_]])
|
||||
{
|
||||
val rel = relation(structure, actual)
|
||||
val keyToString = (key: ScopedKey[_]) => Project display key
|
||||
val keyToString = display.apply _
|
||||
DotGraph.generateGraph(file, graphName, rel, keyToString, keyToString)
|
||||
}
|
||||
def relation(structure: BuildStructure, actual: Boolean) =
|
||||
def relation(structure: BuildStructure, actual: Boolean)(implicit display: Show[ScopedKey[_]]) =
|
||||
{
|
||||
type Rel = Relation[ScopedKey[_], ScopedKey[_]]
|
||||
val cMap = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal)
|
||||
val cMap = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display)
|
||||
((Relation.empty: Rel) /: cMap) { case (r, (key, value)) =>
|
||||
r + (key, value.dependencies)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,16 +98,17 @@ object Scope
|
|||
}
|
||||
|
||||
def display(config: ConfigKey): String = config.name + ":"
|
||||
def display(scope: Scope, sep: String): String =
|
||||
def display(scope: Scope, sep: String): String = display(scope, sep, ref => Project.display(ref) + "/")
|
||||
def display(scope: Scope, sep: String, showProject: Reference => String): String =
|
||||
{
|
||||
import scope.{project, config, task, extra}
|
||||
val projectPrefix = project.foldStrict(Project.display, "*", ".")
|
||||
val projectPrefix = project.foldStrict(showProject, "*/", "./")
|
||||
val configPrefix = config.foldStrict(display, "*:", ".:")
|
||||
val taskPostfix = task.foldStrict(x => ("for " + x.label) :: Nil, Nil, Nil)
|
||||
val extraPostfix = extra.foldStrict(_.entries.map( _.toString ).toList, Nil, Nil)
|
||||
val extras = taskPostfix ::: extraPostfix
|
||||
val postfix = if(extras.isEmpty) "" else extras.mkString("(", ", ", ")")
|
||||
projectPrefix + "/" + configPrefix + sep + postfix
|
||||
projectPrefix + configPrefix + sep + postfix
|
||||
}
|
||||
|
||||
def parseScopedKey(command: String): (Scope, String) =
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ private final class Settings0[Scope](val data: Map[Scope, AttributeMap], val del
|
|||
// this trait is intended to be mixed into an object
|
||||
trait Init[Scope]
|
||||
{
|
||||
def display(skey: ScopedKey[_]): String
|
||||
/** The Show instance used when a detailed String needs to be generated. It is typically used when no context is available.*/
|
||||
def showFullKey: Show[ScopedKey[_]]
|
||||
|
||||
final case class ScopedKey[T](scope: Scope, key: AttributeKey[T])
|
||||
|
||||
|
|
@ -72,23 +73,23 @@ trait Init[Scope]
|
|||
def asTransform(s: Settings[Scope]): ScopedKey ~> Id = new (ScopedKey ~> Id) {
|
||||
def apply[T](k: ScopedKey[T]): T = getValue(s, k)
|
||||
}
|
||||
def getValue[T](s: Settings[Scope], k: ScopedKey[T]) = s.get(k.scope, k.key) getOrElse error("Internal settings error: invalid reference to " + display(k))
|
||||
def getValue[T](s: Settings[Scope], k: ScopedKey[T]) = s.get(k.scope, k.key) getOrElse error("Internal settings error: invalid reference to " + showFullKey(k))
|
||||
def asFunction[T](s: Settings[Scope]): ScopedKey[T] => T = k => getValue(s, k)
|
||||
|
||||
def compiled(init: Seq[Setting[_]], actual: Boolean = true)(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopeLocal): CompiledMap =
|
||||
def compiled(init: Seq[Setting[_]], actual: Boolean = true)(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopeLocal, display: Show[ScopedKey[_]]): CompiledMap =
|
||||
{
|
||||
// prepend per-scope settings
|
||||
val withLocal = addLocal(init)(scopeLocal)
|
||||
// group by Scope/Key, dropping dead initializations
|
||||
val sMap: ScopedMap = grouped(withLocal)
|
||||
// delegate references to undefined values according to 'delegates'
|
||||
val dMap: ScopedMap = if(actual) delegate(sMap)(delegates) else sMap
|
||||
val dMap: ScopedMap = if(actual) delegate(sMap)(delegates, display) else sMap
|
||||
// merge Seq[Setting[_]] into Compiled
|
||||
compile(dMap)
|
||||
}
|
||||
def make(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopeLocal): Settings[Scope] =
|
||||
def make(init: Seq[Setting[_]])(implicit delegates: Scope => Seq[Scope], scopeLocal: ScopeLocal, display: Show[ScopedKey[_]]): Settings[Scope] =
|
||||
{
|
||||
val cMap = compiled(init)(delegates, scopeLocal)
|
||||
val cMap = compiled(init)(delegates, scopeLocal, display)
|
||||
// order the initializations. cyclic references are detected here.
|
||||
val ordered: Seq[Compiled] = sort(cMap)
|
||||
// evaluation: apply the initializations.
|
||||
|
|
@ -116,7 +117,7 @@ trait Init[Scope]
|
|||
def addLocal(init: Seq[Setting[_]])(implicit scopeLocal: ScopeLocal): Seq[Setting[_]] =
|
||||
init.flatMap( _.dependsOn flatMap scopeLocal ) ++ init
|
||||
|
||||
def delegate(sMap: ScopedMap)(implicit delegates: Scope => Seq[Scope]): ScopedMap =
|
||||
def delegate(sMap: ScopedMap)(implicit delegates: Scope => Seq[Scope], display: Show[ScopedKey[_]]): ScopedMap =
|
||||
{
|
||||
def refMap(refKey: ScopedKey[_], isFirst: Boolean) = new ValidateRef { def apply[T](k: ScopedKey[T]) =
|
||||
delegateForKey(sMap, k, delegates(k.scope), refKey, isFirst)
|
||||
|
|
@ -156,7 +157,7 @@ trait Init[Scope]
|
|||
map.set(key.scope, key.key, value)
|
||||
}
|
||||
|
||||
def showUndefined(u: Undefined, sMap: ScopedMap, delegates: Scope => Seq[Scope]): String =
|
||||
def showUndefined(u: Undefined, sMap: ScopedMap, delegates: Scope => Seq[Scope])(implicit display: Show[ScopedKey[_]]): String =
|
||||
{
|
||||
val guessed = guessIntendedScope(sMap, delegates, u.referencedKey)
|
||||
display(u.referencedKey) + " from " + display(u.definingKey) + guessed.map(g => "\n Did you mean " + display(g) + " ?").toList.mkString
|
||||
|
|
@ -178,7 +179,7 @@ trait Init[Scope]
|
|||
final class Uninitialized(val undefined: Seq[Undefined], msg: String) extends Exception(msg)
|
||||
final class Undefined(val definingKey: ScopedKey[_], val referencedKey: ScopedKey[_])
|
||||
def Undefined(definingKey: ScopedKey[_], referencedKey: ScopedKey[_]): Undefined = new Undefined(definingKey, referencedKey)
|
||||
def Uninitialized(sMap: ScopedMap, delegates: Scope => Seq[Scope], keys: Seq[Undefined]): Uninitialized =
|
||||
def Uninitialized(sMap: ScopedMap, delegates: Scope => Seq[Scope], keys: Seq[Undefined])(implicit display: Show[ScopedKey[_]]): Uninitialized =
|
||||
{
|
||||
assert(!keys.isEmpty)
|
||||
val suffix = if(keys.length > 1) "s" else ""
|
||||
|
|
@ -187,7 +188,7 @@ trait Init[Scope]
|
|||
}
|
||||
final class Compiled(val key: ScopedKey[_], val dependencies: Iterable[ScopedKey[_]], val eval: Settings[Scope] => Settings[Scope])
|
||||
{
|
||||
override def toString = display(key)
|
||||
override def toString = showFullKey(key)
|
||||
}
|
||||
|
||||
sealed trait Initialize[T]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package sbt
|
||||
|
||||
trait Show[T] {
|
||||
def apply(t: T): String
|
||||
}
|
||||
Loading…
Reference in New Issue