Fix key selection for build level keys

PR #2469 added build keys to tab completion, with the side effect of
considering as available candidate in key selection, thus making sbt
think that some inputs were ambiguous (e.g. `baseDirectory`): should it
apply to the current project or to the build level key?

This commit fixes this issue by improving the key selection:
 - If there's no candidate, we return the default key
 - If there's a single possible project level key, and zero or more
   build level keys, then we select the project level key.
 - If there are zero project level key, and a single build level key,
   then we select the build level key
 - If there are multiple candidates, sbt says that the input is
   ambiguous.

Fixes #2707
This commit is contained in:
Martin Duhem 2016-08-24 11:13:08 +02:00
parent e94147456c
commit 60bcc58852
1 changed files with 10 additions and 5 deletions

View File

@ -77,11 +77,16 @@ 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)) match {
case Seq() => default
case Seq(single) => success(single)
case multi => failure("Ambiguous keys: " + showAmbiguous(keys(multi)))
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)))
}
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 {
@ -310,4 +315,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) }
}
}