diff --git a/main-settings/src/main/scala/sbt/Scope.scala b/main-settings/src/main/scala/sbt/Scope.scala index bdf026b3e..fe8f261f3 100644 --- a/main-settings/src/main/scala/sbt/Scope.scala +++ b/main-settings/src/main/scala/sbt/Scope.scala @@ -178,6 +178,20 @@ 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") /** diff --git a/main-settings/src/test/scala/sbt/ScopeDisplaySpec.scala b/main-settings/src/test/scala/sbt/ScopeDisplaySpec.scala new file mode 100644 index 000000000..6c7798d67 --- /dev/null +++ b/main-settings/src/test/scala/sbt/ScopeDisplaySpec.scala @@ -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") + } +}