SNAPSHOT artifacts behaviour in 0.13.15

264 views
Skip to first unread message

Nicolas Rinaudo

unread,
Apr 28, 2017, 7:46:06 AM4/28/17
to sbt-dev
Hi,

I'm posting this here at the suggestion of Dale Wijnand.

I've recently starting to notice a new SBT behaviour that I feel might be a bug / regression, but haven't been able to confirm one way or another.
Here's my scenario, and how I think SBT used to work:

1/ library A depends on library B's 1.0.0-SNAPSHOT
2/ library B publishes new 1.0.0-SNAPSHOT
3/ running sbt update in library A (maybe after a reload / restart of SBT) would stop that change and refresh the artifacts

With SBT 0.13.15, step 3 never occurs and I have to manually go in my local cache to delete the artifacts. I've reproduced that with and without coursier as a dependency resolver.

It's also entirely possible that I *think* I remember step 3 happening, but it never actually did. So far, I'm just trying to understand what the expected SBT behaviour is regarding SNAPSHOT artifacts, and I haven't been able to find a conclusive answer (or what I've found seems to imply my expectations are correct - SNAPSHOT artifacts are automatically marked as changing(), which should for refreshes).

Does anyone know for a fact? Is this something I should open an issue about?

Cheers,
Nicolas

Dale Wijnand

unread,
Apr 28, 2017, 8:20:58 AM4/28/17
to sbt...@googlegroups.com
I've tried to reproduce this issue, particularly comparing 0.13.13 with 0.13.15 and I can't reproduce it - they both behave identically and as expected.

Here's my setup.

Library B

build.sbt

val libb = project in file(".")

organization := "com.dwijnand"
     version := "1.0.0-SNAPSHOT"
scalaVersion := "2.12.1"

def buildTimestampSuffix = ";build.timestamp=" + new java.util.Date().getTime

def localArtifactorySnapshotLocal = "local-artifactory-snapshot-local" at "http://localhost:8081/artifactory/libs-snapshot-local" + buildTimestampSuffix

val localArtifactoryCreds = Credentials("Artifactory Realm", "localhost", "admin", "password")

credentials += localArtifactoryCreds
  publishTo := Some(localArtifactorySnapshotLocal)

LibB.scala

package libb

object LibB {
  def foo = 1
}

I ran "publish" to publish it to my local Artifactory repository.

Library A

build.sbt

val liba = project in file(".")

organization := "com.dwijnand"
     version := "1.0.0-SNAPSHOT"
scalaVersion := "2.12.1"

libraryDependencies += "com.dwijnand" %% "libb" % "1.0.0-SNAPSHOT"

Main.scala

package liba

object Main {
  def main(args: Array[String]): Unit = {
    println(libb.LibB.foo)
  }
}

I ran "run" to confirm it prints "1".

When in library A I modify foo return "2" and publish it again,
then in library A if I run "update" and then "run" I see "2" printed.

Tested on both 0.13.13 and 0.13.15.

@Nicolas, could you try and see if you can produce a (minimised) reproduction of the change in behaviour you're noticing?

Thanks,
Dale

--
You received this message because you are subscribed to the Google Groups "sbt-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sbt-dev+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sbt-dev/348c5fda-f270-4359-8cde-3cfe114b972f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

eugene yokota

unread,
Apr 28, 2017, 8:31:48 AM4/28/17
to sbt-dev
Hi,

The semantics around how we should treat SNAPSHOT is so complicated that my general recommendation is
keep the use of SNAPSHOT only to the testing using local machines, and use other strategy like Git sha versioning
the moment your artifact leaves your machine.

We can think of a few goals around sbt's dependency resolution:
  1. Do not run dependency resolution unless we need to, so running `compile` should not result to full resolution each time.
      b. Variant here is starting up sbt from terminal repeatedly, which might result to sbt itself or plugin getting resolved.
  2. -SNAPSHOT versioned module should resolve to the latest artifact based on its publish date.

If we are ambitious, we can even throw in:
  3. sbt should have build-wide or machine-wide knowledge of the freshness so 100 subprojects should not result to 100 checks.

In any case, `update` task by default caches the result of resolution in `target` for goal 1.
It behaves differently when `update` is called transitively via `compile` or if you explicitly invoked `update`.
Try running `clean` to clear out task caching to double check around this.

The second and more tricky part is goal 2. Where is your library B published to?
Is it published to both local and remote repositories? If it's Maven repository, is the meta data up to date?
Also have you made sure that UpdateOptions.withLatestSnapshots is not set to false?

Towards goal 3, we can think of putting TTL (time to live) around SNAPSHOT cache, and cached resolution.
Coursier sets TTL to 24h by default if I understand correctly. cached resolution bumps the clock every time you call `update`,
so subproject re-resolution doesn't occur.

-eugene
Reply all
Reply to author
Forward
Message has been deleted
0 new messages