Merge pull request #2926 from eed3si9n/fport/2855

[fport] Add build-level keys to the tab completion
This commit is contained in:
eugene yokota 2017-01-16 18:24:03 -05:00 committed by GitHub
commit 4201a6ecdd
6 changed files with 77 additions and 29 deletions

View File

@ -49,22 +49,12 @@ object Act {
new ParsedKey(makeScopedKey(proj, conf, task, extra, key), mask)
}
val projectKeys =
for {
rawProject <- optProjectRef(index, current)
proj = resolveProject(rawProject, current)
confAmb <- config(index configs proj)
partialMask = ScopeMask(rawProject.isExplicit, confAmb.isExplicit, false, false)
} yield taskKeyExtra(proj, confAmb, partialMask)
val build = Some(BuildRef(current.build))
val buildKeys =
for {
confAmb <- config(index configs build)
partialMask = ScopeMask(false, confAmb.isExplicit, false, false)
} yield taskKeyExtra(build, confAmb, partialMask)
buildKeys combinedWith projectKeys map (_.flatten)
for {
rawProject <- optProjectRef(index, current)
proj = resolveProject(rawProject, current)
confAmb <- config(index configs proj)
partialMask = ScopeMask(rawProject.isExplicit, confAmb.isExplicit, false, false)
} yield taskKeyExtra(proj, confAmb, partialMask)
}
def makeScopedKey(proj: Option[ResolvedReference], conf: Option[String], task: Option[AttributeKey[_]], extra: ScopeAxis[AttributeMap], key: AttributeKey[_]): ScopedKey[_] =
ScopedKey(Scope(toAxis(proj, Global), toAxis(conf map ConfigKey.apply, Global), toAxis(task, Global), extra), key)
@ -78,16 +68,11 @@ object Act {
selectFromValid(ss filter isValid(data), default)
}
def selectFromValid(ss: Seq[ParsedKey], default: Parser[ParsedKey])(implicit show: Show[ScopedKey[_]]): Parser[ParsedKey] =
selectByTask(selectByConfig(ss)) partition isBuildKey match {
case (_, Seq(single)) => success(single)
case (Seq(single), Seq()) => success(single)
case (Seq(), Seq()) => default
case (buildKeys, projectKeys) => failure("Ambiguous keys: " + showAmbiguous(keys(buildKeys ++ projectKeys)))
selectByTask(selectByConfig(ss)) match {
case Seq() => default
case Seq(single) => success(single)
case multi => failure("Ambiguous keys: " + showAmbiguous(keys(multi)))
}
private def isBuildKey(parsed: ParsedKey): Boolean = parsed.key.scope.project match {
case Select(_: BuildReference) => true
case _ => false
}
private[this] def keys(ss: Seq[ParsedKey]): Seq[ScopedKey[_]] = ss.map(_.key)
def selectByConfig(ss: Seq[ParsedKey]): Seq[ParsedKey] =
ss match {
@ -149,7 +134,16 @@ object Act {
token(ID !!! "Expected key" examples dropHyphenated(keys)) flatMap { keyString =>
getKey(keyMap, keyString, idFun)
}
keyParser(index.keys(proj, conf, task))
// Fixes sbt/sbt#2460 and sbt/sbt#2851
// The parser already accepts build-level keys.
// This queries the key index so tab completion will list the build-level keys.
val buildKeys: Set[String] =
proj match {
case Some(ProjectRef(uri, id)) => index.keys(Some(BuildRef(uri)), conf, task)
case _ => Set()
}
val keys: Set[String] = index.keys(proj, conf, task) ++ buildKeys
keyParser(keys)
}
def getKey[T](keyMap: Map[String, AttributeKey[_]], keyString: String, f: AttributeKey[_] => T): Parser[T] =
@ -315,4 +309,4 @@ object Act {
final object Omitted extends ParsedAxis[Nothing]
final class ParsedValue[T](val value: T) extends ParsedAxis[T]
def value[T](t: Parser[T]): Parser[ParsedAxis[T]] = t map { v => new ParsedValue(v) }
}
}

View File

@ -31,7 +31,7 @@ object ParseKey extends Properties("Key parser test") {
parseExpected(structure, string, expected, mask)
}
property("An unspecified project axis resolves to the current project or the build of the current project") =
property("An unspecified project axis resolves to the current project") =
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
import skm.{ structure, key }
@ -43,7 +43,7 @@ object ParseKey extends Properties("Key parser test") {
("Current: " + structure.current) |:
parse(structure, string) {
case Left(err) => false
case Right(sk) => sk.scope.project == Select(structure.current) || sk.scope.project == Select(BuildRef(structure.current.build))
case Right(sk) => sk.scope.project == Select(structure.current)
}
}

View File

@ -0,0 +1,9 @@
### Bug fixes
- Fixes regressions in sbt 0.13.11 - 0.13.13 that processed build-level keys incorrectly. [#2851][2851]/[#2460][2460] by [@eed3si9n]
[#2851]: https://github.com/sbt/sbt/issues/2851
[#2460]: https://github.com/sbt/sbt/issues/2460
[@eed3si9n]: https://github.com/eed3si9n
[@dwijnand]: https://github.com/dwijnand
[@Duhemm]: https://github.com/Duhemm

View File

@ -0,0 +1,29 @@
import complete.{ Completion, Completions, DefaultParsers, Parser }
import DefaultParsers._
import Command.applyEffect
import CommandUtil._
lazy val root = (project in file(".")).
enablePlugins(FooPlugin).
settings(
commands += checkCompletionsCommand
)
// This checks the tab completion lists build-level keys
def checkCompletionsCommand = Command.make("checkCompletions")(completionsParser)
def completionsParser(state: State) =
{
val notQuoted = (NotQuoted ~ any.*) map { case (nq, s) => (nq +: s).mkString }
val quotedOrUnquotedSingleArgument = Space ~> (StringVerbatim | StringEscapable | notQuoted)
applyEffect(token(quotedOrUnquotedSingleArgument ?? "" examples ("", " ")))(runCompletions(state))
}
def runCompletions(state: State)(input: String): State = {
val xs = Parser.completions(state.combinedParser, input, 9).get map {
c => if (c.isEmpty) input else input + c.append
} map { c =>
c.replaceAll("\n", " ")
}
println(xs)
assert(xs == Set("myTask"))
state
}

View File

@ -0,0 +1,15 @@
import sbt._
import syntax._
object FooPlugin extends AutoPlugin {
override def trigger = noTrigger
object autoImport {
val myTask = taskKey[Unit]("My task")
}
import autoImport._
override def buildSettings = super.buildSettings ++ Seq(
myTask := println("Called my task")
)
}

View File

@ -0,0 +1 @@
> checkCompletions my