Split setting query things out into SettingQuery.scala

This commit is contained in:
Dale Wijnand 2017-03-17 13:19:01 +00:00
parent 4566c615c7
commit aa69d0d042
No known key found for this signature in database
GPG Key ID: 4F256E3D151DF5EF
2 changed files with 102 additions and 93 deletions

View File

@ -7,7 +7,6 @@ package server
import java.net.{ Socket, SocketTimeoutException, URI }
import java.util.concurrent.atomic.AtomicBoolean
import scala.util.{ Left, Right }
import sbt.protocol._
import sjsonnew._
@ -88,95 +87,3 @@ final class NetworkChannel(val name: String, connection: Socket, structure: Buil
out.close()
}
}
object SettingQuery {
import sbt.internal.util.{ AttributeKey, Settings }
import sbt.internal.util.complete.{ DefaultParsers, Parser }, DefaultParsers._
import sbt.Def.{ showBuildRelativeKey, ScopedKey }
// Similar to Act.ParsedAxis / Act.projectRef / Act.resolveProject except you can't omit the project reference
sealed trait ParsedExplicitAxis[+T]
final object ParsedExplicitGlobal extends ParsedExplicitAxis[Nothing]
final class ParsedExplicitValue[T](val value: T) extends ParsedExplicitAxis[T]
def explicitValue[T](t: Parser[T]): Parser[ParsedExplicitAxis[T]] = t map { v => new ParsedExplicitValue(v) }
def projectRef(index: KeyIndex, currentBuild: URI): Parser[ParsedExplicitAxis[ResolvedReference]] = {
val global = token(Act.GlobalString ~ '/') ^^^ ParsedExplicitGlobal
val trailing = '/' !!! "Expected '/' (if selecting a project)"
global | explicitValue(Act.resolvedReference(index, currentBuild, trailing))
}
def resolveProject(parsed: ParsedExplicitAxis[ResolvedReference]): Option[ResolvedReference] = parsed match {
case ParsedExplicitGlobal => None
case pv: ParsedExplicitValue[_] => Some(pv.value)
}
def scopedKeyFull(
index: KeyIndex,
currentBuild: URI,
defaultConfigs: Option[ResolvedReference] => Seq[String],
keyMap: Map[String, AttributeKey[_]]
): Parser[Seq[Parser[ParsedKey]]] = {
for {
rawProject <- projectRef(index, currentBuild)
proj = resolveProject(rawProject)
confAmb <- Act.config(index configs proj)
partialMask = ScopeMask(true, confAmb.isExplicit, false, false)
} yield Act.taskKeyExtra(index, defaultConfigs, keyMap, proj, confAmb, partialMask)
}
def scopedKeySelected(
index: KeyIndex,
currentBuild: URI,
defaultConfigs: Option[ResolvedReference] => Seq[String],
keyMap: Map[String, AttributeKey[_]],
data: Settings[Scope]
): Parser[ParsedKey] =
scopedKeyFull(index, currentBuild, defaultConfigs, keyMap) flatMap { choices =>
Act.select(choices, data)(showBuildRelativeKey(currentBuild, index.buildURIs.size > 1))
}
def scopedKey(
index: KeyIndex,
currentBuild: URI,
defaultConfigs: Option[ResolvedReference] => Seq[String],
keyMap: Map[String, AttributeKey[_]],
data: Settings[Scope]
): Parser[ScopedKey[_]] =
scopedKeySelected(index, currentBuild, defaultConfigs, keyMap, data).map(_.key)
def scopedKeyParser(structure: BuildStructure, currentBuild: URI): Parser[ScopedKey[_]] =
scopedKey(
structure.index.keyIndex,
currentBuild,
structure.extra.configurationsForAxis,
structure.index.keyMap,
structure.data
)
def handleSettingQuery(req: SettingQuery, structure: BuildStructure, currentBuild: URI): SettingQueryResponse = {
val key = Parser.parse(req.setting, scopedKeyParser(structure, currentBuild))
def getSettingValue[A](key: Def.ScopedKey[A]): Either[String, A] =
structure.data.get(key.scope, key.key)
.toRight(s"Key ${Def displayFull key} not found")
.flatMap {
case _: Task[_] => Left(s"Key ${Def displayFull key} is a task, can only query settings")
case _: InputTask[_] => Left(s"Key ${Def displayFull key} is an input task, can only query settings")
case x => Right(x)
}
val values: Either[String, Any] = key match {
case Left(msg) => Left(s"Invalid programmatic input: $msg")
case Right(key) => getSettingValue(key)
}
val jsonValues: String = values match {
case Left(errors) => errors
case Right(value) => value.toString
}
SettingQueryResponse(jsonValues)
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2016-2017 Lightbend Inc. <http://www.lightbend.com>
*/
package sbt
package internal
package server
import java.net.URI
import scala.util.{ Left, Right }
import sbt.protocol._
object SettingQuery {
import sbt.internal.util.{ AttributeKey, Settings }
import sbt.internal.util.complete.{ DefaultParsers, Parser }, DefaultParsers._
import sbt.Def.{ showBuildRelativeKey, ScopedKey }
// Similar to Act.ParsedAxis / Act.projectRef / Act.resolveProject except you can't omit the project reference
sealed trait ParsedExplicitAxis[+T]
final object ParsedExplicitGlobal extends ParsedExplicitAxis[Nothing]
final class ParsedExplicitValue[T](val value: T) extends ParsedExplicitAxis[T]
def explicitValue[T](t: Parser[T]): Parser[ParsedExplicitAxis[T]] = t map { v => new ParsedExplicitValue(v) }
def projectRef(index: KeyIndex, currentBuild: URI): Parser[ParsedExplicitAxis[ResolvedReference]] = {
val global = token(Act.GlobalString ~ '/') ^^^ ParsedExplicitGlobal
val trailing = '/' !!! "Expected '/' (if selecting a project)"
global | explicitValue(Act.resolvedReference(index, currentBuild, trailing))
}
def resolveProject(parsed: ParsedExplicitAxis[ResolvedReference]): Option[ResolvedReference] = parsed match {
case ParsedExplicitGlobal => None
case pv: ParsedExplicitValue[_] => Some(pv.value)
}
def scopedKeyFull(
index: KeyIndex,
currentBuild: URI,
defaultConfigs: Option[ResolvedReference] => Seq[String],
keyMap: Map[String, AttributeKey[_]]
): Parser[Seq[Parser[ParsedKey]]] = {
for {
rawProject <- projectRef(index, currentBuild)
proj = resolveProject(rawProject)
confAmb <- Act.config(index configs proj)
partialMask = ScopeMask(true, confAmb.isExplicit, false, false)
} yield Act.taskKeyExtra(index, defaultConfigs, keyMap, proj, confAmb, partialMask)
}
def scopedKeySelected(
index: KeyIndex,
currentBuild: URI,
defaultConfigs: Option[ResolvedReference] => Seq[String],
keyMap: Map[String, AttributeKey[_]],
data: Settings[Scope]
): Parser[ParsedKey] =
scopedKeyFull(index, currentBuild, defaultConfigs, keyMap) flatMap { choices =>
Act.select(choices, data)(showBuildRelativeKey(currentBuild, index.buildURIs.size > 1))
}
def scopedKey(
index: KeyIndex,
currentBuild: URI,
defaultConfigs: Option[ResolvedReference] => Seq[String],
keyMap: Map[String, AttributeKey[_]],
data: Settings[Scope]
): Parser[ScopedKey[_]] =
scopedKeySelected(index, currentBuild, defaultConfigs, keyMap, data).map(_.key)
def scopedKeyParser(structure: BuildStructure, currentBuild: URI): Parser[ScopedKey[_]] =
scopedKey(
structure.index.keyIndex,
currentBuild,
structure.extra.configurationsForAxis,
structure.index.keyMap,
structure.data
)
def handleSettingQuery(req: SettingQuery, structure: BuildStructure, currentBuild: URI): SettingQueryResponse = {
val key = Parser.parse(req.setting, scopedKeyParser(structure, currentBuild))
def getSettingValue[A](key: Def.ScopedKey[A]): Either[String, A] =
structure.data.get(key.scope, key.key)
.toRight(s"Key ${Def displayFull key} not found")
.flatMap {
case _: Task[_] => Left(s"Key ${Def displayFull key} is a task, can only query settings")
case _: InputTask[_] => Left(s"Key ${Def displayFull key} is an input task, can only query settings")
case x => Right(x)
}
val values: Either[String, Any] = key match {
case Left(msg) => Left(s"Invalid programmatic input: $msg")
case Right(key) => getSettingValue(key)
}
val jsonValues: String = values match {
case Left(errors) => errors
case Right(value) => value.toString
}
SettingQueryResponse(jsonValues)
}
}