为什么在 SBT Play 框架项目中调用 "run" 时 "compile" 被调用了 2 次
Why is "compile" called 2 times when calling "run" in SBT Play Framework Project
在我使用 SBT 的游戏框架项目中,我试图在 compile
任务之前 运行 自定义任务。这可以通过在 build.sbt
.
中添加来轻松完成
lazy val hello = taskKey[Unit]("says hello to everybody :)")
hello := {
println("hello, world")
}
(compile in Compile) := ((compile in Compile) dependsOn hello).value
当我执行 sbt compile
时,它 运行 执行 hello
任务 一次 然后它编译代码。正如预期的那样!
奇怪的是,当我运行sbt run
时,hello
的任务是运行2次。像这样
(Server started, use Enter to stop and go back to the console...)
hello, world
[info] Compiling 1 Java source to C:\dev\CS\CSBackEnd\target\scala-2.12\classes ...
hello, world
[info] p.a.d.DefaultDBApi - Database [default] initialized
[info] p.a.d.HikariCPConnectionPool - Creating Pool for datasource 'default'
知道如何防止这种情况或至少了解幕后发生的事情吗?在这个例子中,它只是打印一个字符串,但在现实生活中,一个复杂的验证将被调用,它不能 运行 2 次,因为它会花费太多时间。
谢谢
** 编辑 **
这是我执行 sbt inspect tree run
.
时的输出
[info] welcome to sbt 1.3.13 (Oracle Corporation Java 1.8.0_201)
[info] loading global plugins from C:\Users\jcote\.sbt.0\plugins
[info] loading settings for project csbackend-build from plugins.sbt ...
[info] loading project definition from C:\dev\CS\CSBackEnd\project
[info] loading settings for project root from build.sbt ...
[info] set current project to S360ControlSite (in build file:/C:/dev/CS/CSBackEnd/)
[info] Compile / run = InputTask[Unit]
[info] +-Compile / run / mainClass = Task[scala.Option[java.lang.String]]
[info] +-Global / javaOptions = Task[scala.collection.Seq[java.lang.String]]
[info] +-baseDirectory =
[info] | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapistylevalidator..
[info] |
[info] +-fileWatchService = play.dev.filewatch.DefaultFileWatchService@205b0b3a
[info] | +-Global / pollInterval = 500 milliseconds
[info] | +-Global / sLog = sbt.internal.LogManager$$anon@6531d251
[info] | +-target = target
[info] | +-baseDirectory =
[info] | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapistylevalid..
[info] |
[info] +-playAssetsClassloader = Task[scala.Function1[java.lang.ClassLoader, java.lang.ClassLoader]]
[info] | +-playAllAssets = Task[scala.collection.Seq[scala.Tuple2[java.lang.String, java.io.File]]]
[info] | +-playPrefixAndAssets = Task[scala.Tuple2[java.lang.String, java.io.File]]
[info] | +-Web-assets / webPublic = target\web\public\main
[info] | | +-assetsTarget = target\web
[info] | | +-target = target
[info] | | +-baseDirectory =
[info] | | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapist..
[info] | |
[info] | +-assetsPrefix = public/
[info] |
[info] +-playCommonClassloader = Task[java.lang.ClassLoader]
[info] | +-Compile / dependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | +-Compile / dependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Compile / externalDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | | +-Compile / externalDependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | |
[info] | | | +-Compile / managedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | | | +-Global / appConfiguration = xsbt.boot.AppConfiguration@5f22d8ea
[info] | | | | +-Compile / classpathConfiguration = Task[sbt.librarymanagement.Configuration]
[info] | | | | | +-Compile / configuration = compile
[info] | | | | | +-Global / internalConfigurationMap = sbt.Defaults$$$Lambda62/1187225933@797c8f80
[info] | | | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | | | |
[info] | | | | +-Global / classpathTypes = Set(eclipse-plugin, maven-plugin, bundle, scala-jar, hk2-jar, orbit, test-jar, jar)
[info] | | | | +-Global / isMetaBuild = false
[info] | | | | +-Compile / managedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | | |
[info] | | | | +-Global / reresolveSbtArtifacts = false
[info] | | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | | | +-Global / useCoursier = true
[info] | | | |
[info] | | | +-Compile / unmanagedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | | +-Global / buildDependencies = sbt.internal.BuildDependencies@6c0a821a
[info] | | | +-Compile / configuration = compile
[info] | | | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | | | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] | | | +-Compile / unmanagedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Compile / internalDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | +-Global / buildDependencies = sbt.internal.BuildDependencies@6c0a821a
[info] | | +-Compile / classpathConfiguration = Task[sbt.librarymanagement.Configuration]
[info] | | | +-Compile / configuration = compile
[info] | | | +-Global / internalConfigurationMap = sbt.Defaults$$$Lambda62/1187225933@797c8f80
[info] | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | |
[info] | | +-Compile / configuration = compile
[info] | | +-Compile / exportedProductJars / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductJarsIfMissing / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductJarsNoTracking / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProducts / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductsIfMissing / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductsNoTracking / transitiveClasspathDependency = ()
[info] | | +-Compile / internalDependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] | | +-Global / trackInternalDependencies = TrackAlways
[info] | |
[info] | +-playCommonClassloader / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] |
[info] +-playDefaultAddress = 0.0.0.0
[info] +-playDefaultPort = 9000
[info] +-playDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | +-Runtime / externalDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | +-Runtime / externalDependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | |
[info] | +-Runtime / managedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | +-Global / appConfiguration = xsbt.boot.AppConfiguration@5f22d8ea
[info] | | +-Runtime / classpathConfiguration = Task[sbt.librarymanagement.Configuration]
[info] | | | +-Runtime / configuration = runtime
[info] | | | +-Global / internalConfigurationMap = sbt.Defaults$$$Lambda62/1187225933@797c8f80
[info] | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | |
[info] | | +-Global / classpathTypes = Set(eclipse-plugin, maven-plugin, bundle, scala-jar, hk2-jar, orbit, test-jar, jar)
[info] | | +-Global / isMetaBuild = false
[info] | | +-Runtime / managedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Global / reresolveSbtArtifacts = false
[info] | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | +-Global / useCoursier = true
[info] | |
[info] | +-Runtime / unmanagedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | +-Global / buildDependencies = sbt.internal.BuildDependencies@6c0a821a
[info] | +-Runtime / configuration = runtime
[info] | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] | +-Runtime / unmanagedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] |
[info] +-playDevSettings = List()
[info] +-playInteractionMode = Console Interaction Mode
[info] +-playMonitoredFiles = Task[scala.collection.Seq[java.io.File]]
[info] | +-Compile / twirlCompileTemplates / sourceDirectories = List(C:\dev\CS\CSBackEnd\app)
[info] | | +-Compile / sourceDirectory = app
[info] | | +-baseDirectory =
[info] | | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapistyleval..
[info] | |
[info] | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] |
[info] +-playRunHooks = Task[scala.collection.Seq[play.sbt.PlayRunHook]]
[info] +-Global / sbtVersion = 1.3.13
[info] +-Global / state = Task[sbt.State]
我不能告诉你为什么你会看到你正在观察的行为。我可以用 SBT 1.3.13 重现错误。当我使用 SBT 1.4.9 时,自定义任务只运行一次,正如您所期望的那样。
在我使用 SBT 的游戏框架项目中,我试图在 compile
任务之前 运行 自定义任务。这可以通过在 build.sbt
.
lazy val hello = taskKey[Unit]("says hello to everybody :)")
hello := {
println("hello, world")
}
(compile in Compile) := ((compile in Compile) dependsOn hello).value
当我执行 sbt compile
时,它 运行 执行 hello
任务 一次 然后它编译代码。正如预期的那样!
奇怪的是,当我运行sbt run
时,hello
的任务是运行2次。像这样
(Server started, use Enter to stop and go back to the console...)
hello, world
[info] Compiling 1 Java source to C:\dev\CS\CSBackEnd\target\scala-2.12\classes ...
hello, world
[info] p.a.d.DefaultDBApi - Database [default] initialized
[info] p.a.d.HikariCPConnectionPool - Creating Pool for datasource 'default'
知道如何防止这种情况或至少了解幕后发生的事情吗?在这个例子中,它只是打印一个字符串,但在现实生活中,一个复杂的验证将被调用,它不能 运行 2 次,因为它会花费太多时间。
谢谢
** 编辑 **
这是我执行 sbt inspect tree run
.
[info] welcome to sbt 1.3.13 (Oracle Corporation Java 1.8.0_201)
[info] loading global plugins from C:\Users\jcote\.sbt.0\plugins
[info] loading settings for project csbackend-build from plugins.sbt ...
[info] loading project definition from C:\dev\CS\CSBackEnd\project
[info] loading settings for project root from build.sbt ...
[info] set current project to S360ControlSite (in build file:/C:/dev/CS/CSBackEnd/)
[info] Compile / run = InputTask[Unit]
[info] +-Compile / run / mainClass = Task[scala.Option[java.lang.String]]
[info] +-Global / javaOptions = Task[scala.collection.Seq[java.lang.String]]
[info] +-baseDirectory =
[info] | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapistylevalidator..
[info] |
[info] +-fileWatchService = play.dev.filewatch.DefaultFileWatchService@205b0b3a
[info] | +-Global / pollInterval = 500 milliseconds
[info] | +-Global / sLog = sbt.internal.LogManager$$anon@6531d251
[info] | +-target = target
[info] | +-baseDirectory =
[info] | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapistylevalid..
[info] |
[info] +-playAssetsClassloader = Task[scala.Function1[java.lang.ClassLoader, java.lang.ClassLoader]]
[info] | +-playAllAssets = Task[scala.collection.Seq[scala.Tuple2[java.lang.String, java.io.File]]]
[info] | +-playPrefixAndAssets = Task[scala.Tuple2[java.lang.String, java.io.File]]
[info] | +-Web-assets / webPublic = target\web\public\main
[info] | | +-assetsTarget = target\web
[info] | | +-target = target
[info] | | +-baseDirectory =
[info] | | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapist..
[info] | |
[info] | +-assetsPrefix = public/
[info] |
[info] +-playCommonClassloader = Task[java.lang.ClassLoader]
[info] | +-Compile / dependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | +-Compile / dependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Compile / externalDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | | +-Compile / externalDependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | |
[info] | | | +-Compile / managedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | | | +-Global / appConfiguration = xsbt.boot.AppConfiguration@5f22d8ea
[info] | | | | +-Compile / classpathConfiguration = Task[sbt.librarymanagement.Configuration]
[info] | | | | | +-Compile / configuration = compile
[info] | | | | | +-Global / internalConfigurationMap = sbt.Defaults$$$Lambda62/1187225933@797c8f80
[info] | | | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | | | |
[info] | | | | +-Global / classpathTypes = Set(eclipse-plugin, maven-plugin, bundle, scala-jar, hk2-jar, orbit, test-jar, jar)
[info] | | | | +-Global / isMetaBuild = false
[info] | | | | +-Compile / managedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | | |
[info] | | | | +-Global / reresolveSbtArtifacts = false
[info] | | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | | | +-Global / useCoursier = true
[info] | | | |
[info] | | | +-Compile / unmanagedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | | +-Global / buildDependencies = sbt.internal.BuildDependencies@6c0a821a
[info] | | | +-Compile / configuration = compile
[info] | | | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | | | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] | | | +-Compile / unmanagedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Compile / internalDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | +-Global / buildDependencies = sbt.internal.BuildDependencies@6c0a821a
[info] | | +-Compile / classpathConfiguration = Task[sbt.librarymanagement.Configuration]
[info] | | | +-Compile / configuration = compile
[info] | | | +-Global / internalConfigurationMap = sbt.Defaults$$$Lambda62/1187225933@797c8f80
[info] | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | |
[info] | | +-Compile / configuration = compile
[info] | | +-Compile / exportedProductJars / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductJarsIfMissing / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductJarsNoTracking / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProducts / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductsIfMissing / transitiveClasspathDependency = ()
[info] | | +-Compile / exportedProductsNoTracking / transitiveClasspathDependency = ()
[info] | | +-Compile / internalDependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] | | +-Global / trackInternalDependencies = TrackAlways
[info] | |
[info] | +-playCommonClassloader / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] |
[info] +-playDefaultAddress = 0.0.0.0
[info] +-playDefaultPort = 9000
[info] +-playDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | +-Runtime / externalDependencyClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | +-Runtime / externalDependencyClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | |
[info] | +-Runtime / managedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | | +-Global / appConfiguration = xsbt.boot.AppConfiguration@5f22d8ea
[info] | | +-Runtime / classpathConfiguration = Task[sbt.librarymanagement.Configuration]
[info] | | | +-Runtime / configuration = runtime
[info] | | | +-Global / internalConfigurationMap = sbt.Defaults$$$Lambda62/1187225933@797c8f80
[info] | | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | |
[info] | | +-Global / classpathTypes = Set(eclipse-plugin, maven-plugin, bundle, scala-jar, hk2-jar, orbit, test-jar, jar)
[info] | | +-Global / isMetaBuild = false
[info] | | +-Runtime / managedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | | |
[info] | | +-Global / reresolveSbtArtifacts = false
[info] | | +-update = Task[sbt.librarymanagement.UpdateReport]
[info] | | +-Global / useCoursier = true
[info] | |
[info] | +-Runtime / unmanagedClasspath = Task[scala.collection.Seq[sbt.internal.util.Attributed[java.io.File]]]
[info] | +-Global / buildDependencies = sbt.internal.BuildDependencies@6c0a821a
[info] | +-Runtime / configuration = runtime
[info] | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] | +-Runtime / unmanagedClasspath / streams = Task[sbt.std.TaskStreams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] | +-Global / streamsManager = Task[sbt.std.Streams[sbt.internal.util.Init$ScopedKey[_ <: Any]]]
[info] |
[info] +-playDevSettings = List()
[info] +-playInteractionMode = Console Interaction Mode
[info] +-playMonitoredFiles = Task[scala.collection.Seq[java.io.File]]
[info] | +-Compile / twirlCompileTemplates / sourceDirectories = List(C:\dev\CS\CSBackEnd\app)
[info] | | +-Compile / sourceDirectory = app
[info] | | +-baseDirectory =
[info] | | +-thisProject = Project(id root, base: C:\dev\CS\CSBackEnd, configurations: List(compile, runtime, test, provided, optional, web-assets, web-assets-test, web-plugin, universal, universal-docs, universal-src, windows, docker, linux, rpm, debian), plugins: List(org.openapitools.openapistyleval..
[info] | |
[info] | +-Global / settingsData = Task[sbt.internal.util.Settings[sbt.Scope]]
[info] | +-thisProjectRef = ProjectRef(file:/C:/dev/CS/CSBackEnd/,root)
[info] |
[info] +-playRunHooks = Task[scala.collection.Seq[play.sbt.PlayRunHook]]
[info] +-Global / sbtVersion = 1.3.13
[info] +-Global / state = Task[sbt.State]
我不能告诉你为什么你会看到你正在观察的行为。我可以用 SBT 1.3.13 重现错误。当我使用 SBT 1.4.9 时,自定义任务只运行一次,正如您所期望的那样。