is Root
Вот мой ответ.
ThisBuild / scalaVersion := "2.13.1"
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.example"
ThisBuild / organizationName := "example"
lazy val foo = taskKey[Int]("")
def whereAmI: Seq[Setting[_]] = Seq(
foo := (Def.taskDyn {
val r = resolvedScoped.value
val st = state.value
val structure = Project.extract(st).structure
val isRoot = r.scope.project match {
case Select(ref: ProjectRef) =>
structure.rootProject(ref.build) == ref.project
case _ => false
}
if (isRoot) Def.task { 0 }
else Def.task { 1 }
}).value
)
lazy val root = (project in file("."))
.settings(
name := "hello",
whereAmI,
)
lazy val app = project
.settings(
name := "app",
whereAmI,
)
resolvedScoped
ключ будет соответствовать разрешенной области ключа Def.ScopedKey[_]
. Поле области действия имеет тип Scope , который содержит project: ScopeAxis[Reference]
. Как правило, он содержит ProjectRef
.
final case class ProjectRef(build: URI, project: String)
extends ProjectReference
with ResolvedReference
. Мы можем проверить значения build: URI
и project: String
, чтобы увидеть, соответствуют ли они значениям root проекта или нет.
Как проверить это
sbt:hello> show root/foo
[info] 0
[success] Total time: 0 s, completed Jan 22, 2020 2:50:34 PM
sbt:hello> show app/foo
[info] 1
[success] Total time: 0 s, completed Jan 22, 2020 2:50:39 PM
Это динамически возвращается 0
для root проекта, но 1
для приложения.
isCurrent вариант
После разговора с Дэниелом, он сказал, что может быть заинтересован в текущем проекте:
Во-первых, в API много «корня», но, более конкретно, есть проект, в котором вы находитесь, когда вы запускаете sbt.
Вот вариант, который проверяет, выполняется ли в текущем проекте динамическая задача c foo или нет.
ThisBuild / scalaVersion := "2.13.1"
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.example"
ThisBuild / organizationName := "example"
lazy val foo = taskKey[Int]("")
def whereAmI: Seq[Setting[_]] = Seq(
foo := (Def.taskDyn {
val r = resolvedScoped.value
val st = state.value
val isCurrent = r.scope.project match {
case Select(ref: ProjectRef) =>
ref == Project.extract(st).currentRef
case _ => false
}
if (isCurrent) Def.task { 2 }
else Def.task { 3 }
}).value
)
lazy val root = (project in file("."))
.settings(
name := "hello",
whereAmI,
)
lazy val app = project
.settings(
name := "app",
whereAmI,
)
Вот как это выглядит в sbt shell:
sbt:hello> show root/foo
[info] 2
[success] Total time: 0 s, completed Jan 22, 2020 3:04:17 PM
sbt:hello> show app/foo
[info] 3
[success] Total time: 0 s, completed Jan 22, 2020 3:04:22 PM
Посмотрим, что произойдет, если вы измените текущий проект на app
:
sbt:hello> project app
[info] Set current project to app (in build file:/private/tmp/hello/)
sbt:app> show root/foo
[info] 3
[success] Total time: 0 s, completed Jan 22, 2020 3:04:28 PM
sbt:app> show app/foo
[info] 2
[success] Total time: 0 s, completed Jan 22, 2020 3:04:34 P