In sbt, how to make cross-version plugin to fail smoothly? - scala

Assuming that if I used the sbt cross-version with may scala versions:
crossScalaVersions ++= List(
// "2.13.6",
"2.13.4",
"2.13.3",
"2.13.2",
"2.13.1",
"2.12.6",
"2.12.7",
"2.12.8",
"2.12.9",
"2.12.10",
"2.12.11",
"2.12.12",
"2.12.13",
"2.12.14",
)
Some of the versions are not compatible (this is an expected behaviour). When I run "sbt +test", the build process always fails early on the first compatibility error. Thus, it won't give 100% information on which versions are compatible.
Is there a way to instruct sbt to only throw a warning in this case, and keep trying all other versions, such that the programmer can get a compatibility matrix afterwards?
To give you more context of this question. The project which I'd like to try this is:
https://github.com/tek/splain
... with github actions as the primary CI for compatibility validation

You could use the sbt-projectmatrix plugin (https://github.com/sbt/sbt-projectmatrix) to define each version as a (sub)project.
It is widely used to deal with complex scenarios involving cross versions.
You would then have a quick view of which (sub)project are failing just by running sbt test.

Related

Can scalameter be imported to scala3 projects (and how)?

I tried to use scalameter 0.21 (and some other versions) with scala 3.1.2.
I added some configurations from the scalameter web-page in my build.sbt file and tried serveral things to make this work, but sbt was not able to find the desired packages.
I would have concluded that scalameter is simply not available for scala3, but there is a question here where somebody somehow got it to work.
The problem seemed to bee that sbt added a 3 in all the sources, as in:
https://repo1.maven.org/maven2/com/storm-enroute/scalameter_3/0.21/scalameter_3-0.21.pom
but the path with scalameter_3 did not exist. If I change the scalaversion to 2.13.8, sbt is able to download all the nesessary files without error. Starting with scala version 3.0.0 the problem exists.
If somebody could post a build.sbt file where scalameter and scala3 are used together, I would apreciate it.
Otherwise, if somebody knows a different library for benchmarking with scala 3...
Thanks very much
As #maxkar mentioned, using crossVersion should do the job:
("com.storm-enroute" %% "scalameter" % "0.21").cross(CrossVersion.for3Use2_13) % Test
However, doing so, you may encounter a problem with conflicting dependencies, e.g.:
[error] Modules were resolved with conflicting cross-version suffixes in ProjectRef(...
[error] org.scala-lang.modules:scala-xml _2.13, _3
In such a case, dependency exclusion, as described in sbt documentation, should solve the issue:
("com.storm-enroute" %% "scalameter" % "0.21").cross(CrossVersion.for3Use2_13) % Test exclude("org.scala-lang.modules", "scala-xml_2.13")
I'm not sure if this cannot backfire in certain situations, but it worked perfectly in my case.

Scala, Sbt - download wrong version of library even if it is set in build.sbt

I have a weird problem with Sbt. I have a Scala zio version set to 1.0.12 in build.sbt:
val zio = "1.0.12"
But when I ran application with sbt it downloaded zio in version 2.x (screen):
I have no idea why. I removed .ivy2 and .sbt directories from user directory. I restarted intellij many times, invalided cached. Even with clear project it always downloads version 2.0.0. Whole code is inspected with this version.
Other zio related lib's versions I use:
val scalaVersion = "2.13.8"
val zio = "1.0.12"
val zioInteropCats = "3.2.9.0"
val zioInteropLog = "1.0.1"
Do you have any ideas why it works like this? I do not need to use ZIO in newest version.
I see in your comment you already solved this, but here's how you'd solve it in general:
This kind of thing is caused when two of your dependencies require different versions of a library. Your explicitly-set version is being "evicted" in favor of a higher version that something else requires
You can find this info by running sbt evicted. If your sbt version is recent (as of 2022), it should be able to use the versionScheme for scala libraries (if they are versions published after the feature was added) in order to alert you with an error when an eviction is likely to be incompatible.
The solution as you've found is to locate the dependency which is bringing in the incompatible version and then resolve the conflict by changing the version of either that dependency or the others

sbt use diverging scalaVersion for dependencies and compiler (Dotty nightly)

I want to test a project against latest Dotty 0.28 nightly builds, while it requires many dependencies that have last been published for Dotty 0.27.0-RC1. Without going into the question of binary compatibility, is there—for testing purposes, to see if a fix in Dotty applies to the project that previously crashed dotc—a way to specify in build.sbt diverging scala versions for the compiler that's used (I want 0.28.0-...-NIGHTLY) and the dependencies looked up (I want 0.27.0-RC1)?
I do not wish to edit all of libraryDependencies to change % "foo" for % "foo_0.27.0-RC1", but want a global way to enable this behaviour.

Scala and Scala.js version included in artifact id

I just successfully released my first Scala & Scala.js cross-building library to Sonatype and can now use the following two artifacts in my applicatons:
https://search.maven.org/artifact/com.github.fbaierl/scala-tarjan_2.12/0.1.1/jar
https://search.maven.org/artifact/com.github.fbaierl/scala-tarjan_sjs0.6_2.12/0.1.1/jar
My question now is: Why is the Scala and Scala.js version included in the artifact id? I don't think I have seen such a thing before so I was wondering if I did something wrong. Here is my build.sbt: https://github.com/fbaierl/scalajs-cross-compile-tarjan/blob/03954a3e2d1442ad339298a986209c1403c9692e/build.sbt
That's the way that Scala artifacts work. Pretty much all artifacts look like this -- it just isn't obvious when you use those artifacts in sbt, because (IIRC) the _2.12 is implied by the %% operator in sbt. (And the _sjs0.6 is implied by the %%% operator.)
The underlying reason for it is that artifacts compiled by different major versions of the Scala compiler (Scala versions are epoch.major.minor) aren't binary compatible (because otherwise the language and standard library couldn't evolve). You can't mix e.g. _2.12 and _2.11 artifacts on the classpath, so the “same” version of the same library must be published separately for both Scala versions, so the suffix is needed to distinguish them.

Conflicting cross-version suffixes in: org.scalamacros:quasiquotes

I am trying to use scala-pickling in one of my projects. I tried to mimic the build file of macroid which seems to use pickling too but I keep getting this error on sbt test:
[error] Modules were resolved with conflicting cross-version suffixes in dijon:
[error] org.scalamacros:quasiquotes _2.10, _2.10.3
java.lang.RuntimeException: Conflicting cross-version suffixes in: org.scalamacros:quasiquotes
at scala.sys.package$.error(package.scala:27)
at sbt.ConflictWarning$.processCrossVersioned(ConflictWarning.scala:47)
at sbt.ConflictWarning$.apply(ConflictWarning.scala:30)
at sbt.Classpaths$$anonfun$61.apply(Defaults.scala:1044)
at sbt.Classpaths$$anonfun$61.apply(Defaults.scala:1044)
Full build log is here. What am I doing wrong? What should I change in my build.sbt to fix this? I also should be able to cross compile and release my library against both 2.10.x and 2.11.x.
Starting from 2.0.0-M7, org.scalamacros % quasiquotes are cross-versioned as binary (i.e. _2.10) and not as full (i.e. _2.10.x): http://scalamacros.org/news/2014/04/03/macro-paradise-2.0.0-M7.html. Looks like one of your dependencies uses pre-M7 quasiquotes and another one uses post-M7 quasiquotes.
I don't think this can fixed in any way other than upgrading all the dependencies that use the old quasiquote library, because pre-M7 and post-M7 quasiquote libraries are incompatible.
The problem is that you are using two different versions of the quasiquotes module that allows defining Scala macros. You should make sure that only a single version is used, and that this single version is matched by all your dependencies that use macros.
Also, are you sure that scala-pickling was released for Scala 2.11.x? Judging, from their build file, they released only for 2.10.3 - https://github.com/scala/pickling/blob/2.10.x/project/Build.scala#L10.
First, try to remove:
crossScalaVersions := Seq("2.10.4", "2.11.0-RC4")
And try again. After that, set the Scala version to 2.10.3, so that it matches the one in scala-pickling.
scalaVersion := "2.10.3"
EDIT: See Eugene's answer below for a more detailed explanation.
According to my dependencyGraph from pulling in spray-testkit_2.10-1.3.2, specs2_2.10 v1.3.10 is still using a milestone release of quasiquotes. I ran the cross version error issue because of this.