From fd2823e827007e16190a4011c0fccffe5aef573b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 12 Mar 2013 14:51:09 -0400 Subject: [PATCH] clean up 'inspect' command and limit Related section to 10 keys --- main/command/src/main/scala/sbt/Command.scala | 10 ---- main/src/main/scala/sbt/Inspect.scala | 56 +++++++++++++++++++ main/src/main/scala/sbt/Main.scala | 54 ++++++------------ main/src/main/scala/sbt/Project.scala | 19 ++++--- 4 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 main/src/main/scala/sbt/Inspect.scala diff --git a/main/command/src/main/scala/sbt/Command.scala b/main/command/src/main/scala/sbt/Command.scala index af0b7c505..7aef382cc 100644 --- a/main/command/src/main/scala/sbt/Command.scala +++ b/main/command/src/main/scala/sbt/Command.scala @@ -110,16 +110,6 @@ object Command ( (c & opOrIDSpaced(name)) ~ c.+) map { case (f, rem) => (f +: rem).mkString } } -sealed trait InspectOption -object InspectOption -{ - final case class Details(actual: Boolean) extends InspectOption - private[this] final class Opt(override val toString: String) extends InspectOption - val DependencyTree: InspectOption = new Opt("tree") - val Uses: InspectOption = new Opt("inspect") - val Definitions: InspectOption = new Opt("definitions") -} - trait Help { def detail: Map[String, String] diff --git a/main/src/main/scala/sbt/Inspect.scala b/main/src/main/scala/sbt/Inspect.scala new file mode 100644 index 000000000..6533e5c32 --- /dev/null +++ b/main/src/main/scala/sbt/Inspect.scala @@ -0,0 +1,56 @@ +package sbt + + import complete.{DefaultParsers,Parser} + import DefaultParsers._ + import Def.ScopedKey + import Types.idFun + import java.io.File + +object Inspect +{ + sealed trait Mode + final case class Details(actual: Boolean) extends Mode + private[this] final class Opt(override val toString: String) extends Mode + val DependencyTree: Mode = new Opt("tree") + val Uses: Mode = new Opt("inspect") + val Definitions: Mode = new Opt("definitions") + + def parser: State => Parser[(Inspect.Mode,ScopedKey[_])] = (s: State) => spacedModeParser(s) flatMap { + case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Def.ScopedKey(Global, key))) + case opt @ (DependencyTree | Details(_)) => spacedKeyParser(s).map(key => (opt, key)) + } + val spacedModeParser: (State => Parser[Mode]) = (s: State) => { + val actual = "actual" ^^^ Details(true) + val tree = "tree" ^^^ DependencyTree + val uses = "uses" ^^^ Uses + val related = "related" ^^^ Related + val definitions = "definitions" ^^^ Definitions + token(Space ~> (tree | actual | uses | related | definitions)) ?? Details(false) + } + + def allKeyParser(s: State): Parser[AttributeKey[_]] = + { + val keyMap = Project.structure(s).index.keyMap + token(Space ~> (ID !!! "Expected key" examples keyMap.keySet)) flatMap { key => Act.getKey(keyMap, key, idFun) } + } + val spacedKeyParser: State => Parser[ScopedKey[_]] = (s: State) => Act.requireSession(s, token(Space) ~> Act.scopedKeyParser(s)) + + def output(s: State, option: Mode, sk: Def.ScopedKey[_]): String = + { + val extracted = Project.extract(s) + import extracted._ + option match + { + case Details(actual) => + Project.details(structure, actual, sk.scope, sk.key) + case DependencyTree => + val basedir = new File(Project.session(s).current.build) + Project.settingGraph(structure, basedir, sk).dependsAscii + case Uses => + Project.showUses(Project.usedBy(structure, true, sk.key)) + case Definitions => + Project.showDefinitions(sk.key, Project.definitions(structure, true, sk.key)) + } + } + +} diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 6b7efcc6d..0bd63c109 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -232,27 +232,14 @@ object BuiltinCommands // @deprecated("Use SettingCompletions.setThis", "0.13.0") def setThis(s: State, extracted: Extracted, settings: Seq[Def.Setting[_]], arg: String) = SettingCompletions.setThis(s, extracted, settings, arg) - def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(inspectParser) { case (s, (option, sk)) => - s.log.info(inspectOutput(s, option, sk)) + def inspect = Command(InspectCommand, inspectBrief, inspectDetailed)(Inspect.parser) { case (s, (option, sk)) => + s.log.info(Inspect.output(s, option, sk)) s } - def inspectOutput(s: State, option: InspectOption, sk: Def.ScopedKey[_]): String = - { - val extracted = Project.extract(s) - import extracted._ - option match - { - case InspectOption.Details(actual) => - Project.details(structure, actual, sk.scope, sk.key) - case InspectOption.DependencyTree => - val basedir = new File(Project.session(s).current.build) - Project.settingGraph(structure, basedir, sk).dependsAscii - case InspectOption.Uses => - Project.showUses(Project.usedBy(structure, true, sk.key)) - case InspectOption.Definitions => - Project.showDefinitions(sk.key, Project.definitions(structure, true, sk.key)) - } - } + + @deprecated("Use Inspect.output", "0.13.0") + def inspectOutput(s: State, option: Inspect.Mode, sk: Def.ScopedKey[_]): String = Inspect.output(s, option, sk) + def lastGrep = Command(LastGrepCommand, lastGrepBrief, lastGrepDetailed)(lastGrepParser) { case (s, (pattern,Some(sks))) => val (str, ref, display) = extractLast(s) @@ -275,25 +262,18 @@ object BuiltinCommands SettingCompletions.settingParser(structure.data, structure.index.keyMap, currentProject ) } - import InspectOption._ - def inspectParser = (s: State) => spacedInspectOptionParser(s) flatMap { - case opt @ (Uses | Definitions) => allKeyParser(s).map(key => (opt, Def.ScopedKey(Global, key))) - case opt @ (DependencyTree | Details(_)) => spacedKeyParser(s).map(key => (opt, key)) - } - val spacedInspectOptionParser: (State => Parser[InspectOption]) = (s: State) => { - val actual = "actual" ^^^ Details(true) - val tree = "tree" ^^^ DependencyTree - val uses = "uses" ^^^ Uses - val definitions = "definitions" ^^^ Definitions - token(Space ~> (tree | actual | uses | definitions)) ?? Details(false) - } - def allKeyParser(s: State): Parser[AttributeKey[_]] = - { - val keyMap = Project.structure(s).index.keyMap - token(Space ~> (ID !!! "Expected key" examples keyMap.keySet)) flatMap { key => Act.getKey(keyMap, key, idFun) } - } + @deprecated("Use Inspect.parser", "0.13.0") + def inspectParser: State => Parser[(Inspect.Mode, Def.ScopedKey[_])] = Inspect.parser + + @deprecated("Use Inspect.spacedModeParser", "0.13.0") + val spacedModeParser: State => Parser[Inspect.Mode] = Inspect.spacedModeParser + + @deprecated("Use Inspect.allKeyParser", "0.13.0") + def allKeyParser(s: State): Parser[AttributeKey[_]] = Inspect.allKeyParser(s) + + @deprecated("Use Inspect.spacedKeyParser", "0.13.0") + val spacedKeyParser: State => Parser[Def.ScopedKey[_]] = Inspect.spacedKeyParser - val spacedKeyParser = (s: State) => Act.requireSession(s, token(Space) ~> Act.scopedKeyParser(s)) val spacedAggregatedParser = (s: State) => Act.requireSession(s, token(Space) ~> Act.aggregatedKeyParser(s)) val aggregatedKeyValueParser: State => Parser[Option[AnyKeys]] = (s: State) => spacedAggregatedParser(s).map(x => Act.keyValues(s)(x) ).? diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 8c3b4d855..b89709256 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -280,7 +280,7 @@ object Project extends ProjectExtra "Some of the defining occurrences:" header + (posDefined.distinct mkString ("\n\t", "\n\t", "\n")) } else "" - } getOrElse "" + } getOrElse "" val cMap = Def.flattenLocals(comp) @@ -288,8 +288,12 @@ object Project extends ProjectExtra 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.apply).mkString(label + ":\n\t", "\n\t", "\n") + def printScopes(label: String, scopes: Iterable[ScopedKey[_]], max: Int = Int.MaxValue) = + if(scopes.isEmpty) "" + else { + val (limited, more) = if(scopes.size <= max) (scopes, "\n") else (scopes.take(max), "\n...\n") + limited.map(display.apply).mkString(label + ":\n\t", "\n\t", more) + } data + "\n" + description + @@ -298,7 +302,7 @@ object Project extends ProjectExtra printScopes("Dependencies", depends) + printScopes("Reverse dependencies", reverse) + printScopes("Delegates", delegates(structure, scope, key)) + - printScopes("Related", related) + printScopes("Related", related, 10) } def settingGraph(structure: BuildStructure, basedir: File, scoped: ScopedKey[_])(implicit display: Show[ScopedKey[_]]): SettingGraph = SettingGraph(structure, basedir, scoped, 0) @@ -324,15 +328,16 @@ object Project extends ProjectExtra } def showDefinitions(key: AttributeKey[_], defs: Seq[Scope])(implicit display: Show[ScopedKey[_]]): String = - defs.map(scope => display(ScopedKey(scope, key))).sorted.mkString("\n\t", "\n\t", "\n\n") + showKeys(defs.map(scope => ScopedKey(scope, key))) def showUses(defs: Seq[ScopedKey[_]])(implicit display: Show[ScopedKey[_]]): String = - defs.map(display.apply).sorted.mkString("\n\t", "\n\t", "\n\n") + showKeys(defs) + private[this] def showKeys(s: Seq[ScopedKey[_]])(implicit display: Show[ScopedKey[_]]): String = + s.map(display.apply).sorted.mkString("\n\t", "\n\t", "\n\n") def definitions(structure: BuildStructure, actual: Boolean, key: AttributeKey[_])(implicit display: Show[ScopedKey[_]]): Seq[Scope] = relation(structure, actual)(display)._1s.toSeq flatMap { sk => if(sk.key == key) sk.scope :: Nil else Nil } def usedBy(structure: BuildStructure, actual: Boolean, key: AttributeKey[_])(implicit display: Show[ScopedKey[_]]): Seq[ScopedKey[_]] = relation(structure, actual)(display).all.toSeq flatMap { case (a,b) => if(b.key == key) List[ScopedKey[_]](a) else Nil } - def reverseDependencies(cMap: Map[ScopedKey[_],Flattened], scoped: ScopedKey[_]): Iterable[ScopedKey[_]] = for( (key,compiled) <- cMap; dep <- compiled.dependencies if dep == scoped) yield key