In my play framework project using SBT, I'm trying to run a custom task before the compile
task. This is easily done by adding this in the build.sbt
.
lazy val hello = taskKey[Unit]("says hello to everybody :)")
hello := {
println("hello, world")
}
(compile in Compile) := ((compile in Compile) dependsOn hello).value
When I do sbt compile
, it runs the hello
task once then it compiles the code. Like it was expected!
Strangely, when I run sbt run
, the hello
task is run 2 times. Like this
(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'
Any idea how to prevent this or at least understand what is going on under the hood? In this example, it's only to print a string but in real life, a complex validation will be called instead and it can't run 2 times because it will take too much time.
Thanks
** EDIT **
Here is the output when I do 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\1.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$1@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$$$Lambda$1562/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$$$Lambda$1562/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$$$Lambda$1562/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]
CodePudding user response:
I can't tell you why you're seeing the behaviour you're observing. I can reproduce the error with SBT 1.3.13. When I use SBT 1.4.9 the custom task only runs once as you would expect.