Merge pull request #4956 from eatkins/custom-show

Allow custom show for a scope
This commit is contained in:
eugene yokota 2019-08-19 16:37:11 -04:00 committed by GitHub
commit 740936e156
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 20 deletions

View File

@ -54,12 +54,14 @@ object Def extends Init[Scope] with TaskMacroExtra {
keyNameColor: Option[String] = None,
): Show[ScopedKey[_]] =
Show[ScopedKey[_]](
key =>
Scope.display(
key.scope,
withColor(key.key.label, keyNameColor),
ref => displayRelative2(current, ref)
)
key => {
val color: String => String = withColor(_, keyNameColor)
key.scope.extra.toOption
.flatMap(_.get(Scope.customShowString).map(color))
.getOrElse {
Scope.display(key.scope, color(key.key.label), ref => displayRelative2(current, ref))
}
}
)
private[sbt] def showShortKey(

View File

@ -178,6 +178,22 @@ object Scope {
): String =
displayMasked(scope, sep, showProject, mask, false)
/**
* Allows the user to override the result of `Scope.display` or `Scope.displayMasked` for a
* particular scope. This can be used to enhance super shell and/or error reporting for tasks
* that use mangled names. For example, one might have:
* {{{
* val mangledKey = TaskKey[Unit]("foo_slash_bar")
* val attributeMap = AttributeMap.empty.put(Scope.customShowString("foo/bar"))
* val sanitizedKey = mangledKey.copy(scope = mangledKey.copy(extra = Select(attributeMap)))
* sanitizedKey := { ... }
* }}}
*
* Now whenever the `foo_slash_bar` task specified by sanitizedKey is evaluated, it will display
* "foo/bar" in super shell progress and in the error message if an error is thrown.
*/
val customShowString = AttributeKey[String]("scope-custom-show-string")
/**
* unified slash style introduced in sbt 1.1.0.
* By default, sbt will no longer display the Zero-config,
@ -193,20 +209,22 @@ object Scope {
showZeroConfig: Boolean
): String = {
import scope.{ project, config, task, extra }
val zeroConfig = if (showZeroConfig) "Zero /" else ""
val configPrefix = config.foldStrict(display, zeroConfig, "./")
val taskPrefix = task.foldStrict(_.label + " /", "", "./")
val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil)
val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")")
if (scope == GlobalScope) "Global / " + sep + postfix
else
mask.concatShow(
appendSpace(projectPrefix(project, showProject)),
appendSpace(configPrefix),
appendSpace(taskPrefix),
sep,
postfix
)
extra.toOption.flatMap(_.get(customShowString)).getOrElse {
val zeroConfig = if (showZeroConfig) "Zero /" else ""
val configPrefix = config.foldStrict(display, zeroConfig, "./")
val taskPrefix = task.foldStrict(_.label + " /", "", "./")
val extras = extra.foldStrict(_.entries.map(_.toString).toList, Nil, Nil)
val postfix = if (extras.isEmpty) "" else extras.mkString("(", ", ", ")")
if (scope == GlobalScope) "Global / " + sep + postfix
else
mask.concatShow(
appendSpace(projectPrefix(project, showProject)),
appendSpace(configPrefix),
appendSpace(taskPrefix),
sep,
postfix
)
}
}
private[sbt] def appendSpace(s: String): String =

View File

@ -0,0 +1,50 @@
/*
* sbt
* Copyright 2011 - 2018, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
import org.scalatest.FlatSpec
import sbt.internal.util.{ AttributeKey, AttributeMap }
import sbt.io.syntax.file
class ScopeDisplaySpec extends FlatSpec {
val project = ProjectRef(file("foo/bar"), "bar")
val mangledName = "bar_slash_blah_blah_blah"
val scopedKey = Def.ScopedKey(Scope.Global in project, AttributeKey[Task[String]](mangledName))
val am = AttributeMap.empty.put(Scope.customShowString, "blah")
val sanitizedKey = scopedKey.copy(scope = scopedKey.scope.copy(extra = Select(am)))
"Def.displayRelative2" should "display mangled name" in {
assert(Def.showRelativeKey2(project, None).show(scopedKey) == mangledName)
}
it should "display sanitized name with extra setting" in {
assert(Def.showRelativeKey2(project, None).show(sanitizedKey) == "blah")
}
"Scope.display" should "display the full scope" in {
val full = Scope.display(
scopedKey.scope,
"/",
(ref: Reference) =>
ref match {
case ProjectRef(_, n) => n
case _ => ???
}
)
assert(full == "bar /")
}
it should "display the sanitized scope" in {
val string = Scope.display(
sanitizedKey.scope,
"/",
(ref: Reference) =>
ref match {
case ProjectRef(_, n) => n
case _ => ???
}
)
assert(string == "blah")
}
}