diff --git a/main/Project.scala b/main/Project.scala index c8ff698e5..ad92ddfc2 100644 --- a/main/Project.scala +++ b/main/Project.scala @@ -251,24 +251,14 @@ 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 scopedKeyData(structure: BuildStructure, scope: Scope, key: AttributeKey[_]): Option[ScopedKeyData[_]] = + structure.data.get(scope, key) map { v => ScopedKeyData(ScopedKey(scope, key), v) } + 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 - lazy val firstType = key.manifest.typeArguments.head - val value = - structure.data.get(scope, key) match - { - case None => "No entry for key." - case Some(v) => - if(clazz == classOf[Task[_]]) - "Task: " + firstType.toString - else if(clazz == classOf[InputTask[_]]) - "Input task: " + firstType.toString - else - "Setting: " + key.manifest.toString + " = " + v.toString - } - + + val data = scopedKeyData(structure, scope, key) map {_.description} getOrElse {"No entry for key."} val description = key.description match { case Some(desc) => "Description:\n\t" + desc + "\n"; case None => "" } val definedIn = structure.data.definingScope(scope, key) match { case Some(sc) => "Provided by:\n\t" + Scope.display(sc, key.label) + "\n" @@ -281,7 +271,7 @@ object Project extends Init[Scope] with ProjectExtra def printScopes(label: String, scopes: Iterable[ScopedKey[_]]) = if(scopes.isEmpty) "" else scopes.map(display.apply).mkString(label + ":\n\t", "\n\t", "\n") - value + "\n" + + data + "\n" + description + definedIn + printScopes("Dependencies", depends) + @@ -356,6 +346,22 @@ object Project extends Init[Scope] with ProjectExtra 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) +{ + 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 _ +} + trait ProjectExtra { implicit def configDependencyConstructor[T <% ProjectReference](p: T): Constructor = new Constructor(p) diff --git a/main/SettingGraph.scala b/main/SettingGraph.scala index d133a73ba..dda05d482 100644 --- a/main/SettingGraph.scala +++ b/main/SettingGraph.scala @@ -16,46 +16,37 @@ object SettingGraph { val key = scoped.key val scope = scoped.scope - - lazy val clazz = key.manifest.erasure - lazy val firstType = key.manifest.typeArguments.head - val (typeName: String, value: Option[_]) = - structure.data.get(scope, key) match { - case None => ("", None) - case Some(v) => - if(clazz == classOf[Task[_]]) ("Task[" + firstType.toString + "]", None) - else if(clazz == classOf[InputTask[_]]) ("InputTask[" + firstType.toString + "]", None) - else (key.manifest.toString, Some(v)) - } - val definedIn = structure.data.definingScope(scope, key) map { sc => display(ScopedKey(sc, key)) } val cMap = flattenLocals(compiled(structure.settings, false)(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) - SettingGraph(display(scoped), definedIn, typeName, value, key.description, basedir, + SettingGraph(display(scoped), definedIn, + Project.scopedKeyData(structure, scope, key), + key.description, basedir, depends map { apply(structure, basedir, _, generation + 1) }) } } case class SettingGraph(name: String, definedIn: Option[String], - typeName: String, - value: Option[Any], + data: Option[ScopedKeyData[_]], description: Option[String], basedir: File, depends: Set[SettingGraph]) { - def valueString: String = - value map { - case f: File => IO.relativize(basedir, f) getOrElse {f.toString} - case x => x.toString - } getOrElse {typeName} - + def dataString: String = + data map { d => + d.settingValue map { + case f: File => IO.relativize(basedir, f) getOrElse {f.toString} + case x => x.toString + } getOrElse {d.typeName} + } getOrElse {""} + def dependsAscii: String = Graph.toAscii(this, (x: SettingGraph) => x.depends.toSeq, - (x: SettingGraph) => "%s = %s" format(x.definedIn getOrElse {""}, x.valueString)) + (x: SettingGraph) => "%s = %s" format(x.definedIn getOrElse {""}, x.dataString)) } object Graph