-
Notifications
You must be signed in to change notification settings - Fork 949
Description
relates to Add forceUpdatePeriod
@ajsquared
Steps
sbt.version = 1.5.2
Part 1 (publish some SNAPSHOT
library)
- Create some dummy sbt project as a library.
Note, that it should be published to some artifactory (thus no viapublishLocal
)
name := "my-library-3"
ThisBuild / scalaVersion := "2.13.5"
ThisBuild / organization := "org.example"
ThisBuild / version := "0.1-SNAPSHOT"
// Configure your own repository here
credentials += Credentials(Path.userHome / ".sbt" / "my.credentials")
resolvers += MyResolvers.myRepository
publishTo := Some(MyResolvers.myRepository)
- In the library sources create some test object with method
foo1
object MyObject3 {
def foo1(): Unit = {
println(s"hello from: ${this.getClass}")
}
}
- Publish the library with
publish
command
Part 2 (use the library in another project)
- Create another sbt project which will use the library:
import scala.concurrent.duration.DurationInt
name := "library-reindex"
version := "0.1"
scalaVersion := "2.13.5"
ThisBuild / forceUpdatePeriod := Some(0.seconds) // doesn't help :(
libraryDependencies ++= Seq(
"org.example" %% "my-library-3" % "0.1-SNAPSHOT" /*withSources()*/,
)
myTask2 := myTaskDef2.value
// TODO: provide same resolvers as in library project
credentials += ???
resolvers += ???
- In this project create some task which depends on
update
task:
inbuild.sbt
add:
myTask2 := myTaskDef2.value
in project/commons.scala
:
import org.jetbrains.sbt.CreateTasks.`enrich TaskKey`
import org.jetbrains.sbt.{Options, StructureKeys, UpdateReportAdapter}
import sbt.Def.Initialize
import sbt._
object commons {
def myTaskDef2: Initialize[Task[String]] = Def.task {
val result = Keys.update.value
println(s"! $result")
"done task 2"
}
}
-
Run
sbt
for the second project -
Run
update
just in case -
Ensure that the library was resolved by courier.
Go to something like:
.../Coursier/cache/v1/https/<repository_path>/org/example//my-library-3_2.13/0.1-SNAPSHOT
and ensure thatmy-library-3_2.13-0.1-SNAPSHOT.jar
exits
Part 3 (modify the snapshot library, republish, and see that it's not updated when update
is called indirectly)
-
First, ensure that you disable Coursier TTL.
Without this, whatever you do in SBT, Coursier will not update the library from the server.
According to https://get-coursier.io/docs/ttl you can disable TTL usingCOURSIER_TTL=0
environment variable.
Also you can use JVM property-Dlmcoursier.internal.shaded.coursier.ttl=0
.
(BTW, it should be-Dcoursier.ttl=0
according to the coursier sources, but for some reason, in SBT it's different (I inferred it from the bytecode). Probably this is due to the shading rules: https://github.com/coursier/sbt-coursier/blob/master/build.sbt#L57) -
Change method from
foo1
tofoo2
in the library project, and republish it usingpublish
-
Go to the second project, open sbt and do
update
-
See that library jar was updated.
Class contains methodfoo2
now.
This is the expected behaviour according to the docs:
Directly running the update task (as opposed to a task that depends on it) will force resolution to run, whether or not configuration changed.
You can use this bash script to quickly check the .jar
in the coursier cache folder:
stat my-library-3_2.13-0.1-SNAPSHOT.jar ; \echo "" ; \
unzip -p my-library-3_2.13-0.3-SNAPSHOT.jar MyObject3$.class > temp.class ; javap temp.class | grep foo
- Change method from
foo2
tofoo3
in the library project, and republish it usingpublish
- Go to the second project, open sbt and run
myTask2
.
Note 1:myTask2
depends onupdate
Note 2: the project hasThisBuild / forceUpdatePeriod := Some(0.seconds)
setting - See that the library jar WAS NOT updated. The class still contains
foo2
- Close sbt in the second project , remove all
target
folders, restart sbt - Again, run
myTask2
- See that the library jar WAS updated. The class now contains
foo3
problem
When you have a non-fresh SBT context
(you already run some commands and caches in target
folder are poluted)
forceUpdatePeriod
setting doesn't work as expected.
expectation
forceUpdatePeriod
should force update in any circumstances
After step 13 and 14 the class should contain method foo3
notes
The code responsible for that is located in
sbt.Classpaths.updateTask0
Looks like some wrong folder is used to detect the last update timestamp:
val fullUpdateOutput = cacheDirectory / "out"
in the debugger fullUpdateOutput.exists()
returned false
when I was doing myTask2