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

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.

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.

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

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.

Scala "not found: object com" - should i really add entry in build.sbt if there are no other dependencies?

I have created basic Scala Play application with https://www.playframework.com/getting-started play-scala-seed. This project compiles and runs with sbt run. But I have another Scala project that compiles and runs and which I have submitted to my local Ivy repository with command sbt publishLocal. This other project was saved at C:\Users\tomr\.ivy2\local\com.agiintelligence\scala-isabelle_2.13\master-SNAPSHOT as a result of this command.
Then I imported (exactly so - imported, no just opened) my Play project in IntelliJ and I used Project - Open Module Settings - Project Settings - Libraries to add com.agiintelligence jar from my ivy2 location. After such operations IntelliJ editor recognizes com.agiintelligence classes. That is fine.
But when I am trying to run my Play application with sbt run, I experience the error message not found: object com that is exactly when compiling import com.agiintelligence line in my Scala controller file of Play application.
Of course - such error has been reported and resolved with, e.g. object play not found in scala application
But that solution suggests to append build.sbt file. My build.sbt file is pretty bare:
name := """agiintelligence"""
organization := "com.agiintelligence"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.13.5"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
// Adds additional packages into Twirl
//TwirlKeys.templateImports += "com.skaraintelligence.controllers._"
// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.skaraintelligence.binders._"
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries' (it shows my com.agiintelligence jar as well), but why should I add my own ivy2 library in build.sbt file if no other libraries are listed here? What is different with my library? It is on my computer, in the repository as expected already?
Of course, I can try to add it build.sbt and issue sbt update and see what happens, but I can not understand this logic? Can someone explain it and provide some clue to intelligible solution of my error message?
My Play application contains (as can bee seen from the IntelliJ project pane) some tens of 'external libraries'
Those are probably just transitive dependencies of your Play dependency, that is why sbt downloaded all of them and put them in your classpath so you could use them without you needing to tell it about them; because the pom of Play already did.
It is not that the build tool or the IDE magically added all those dependencies for you because they read your mind and magically understood you wanted them. And that for some reason the magic stopped working for your own library.
Why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
That is sufficient for the IDE to work, but not for the build tool. The build tool is independent of the IDE; it doesn't know about it. sbt just knows about the dependencies you configured in your definition file.
Even more, you should always configure your dependencies on your build tool and then import that in the IDE; rather than the opposite. IDEs are graphical tools, so their state can not be committed, can not be shared, can not keep track of changes, can not be used in CI / CD environments; additionally, different teammates may want to use different IDEs.
I resolved the error message by adding line in build.sbt file
libraryDependencies += "de.unruh" %% "scala-isabelle" % "master-SNAPSHOT"
and by subsequent run of sbt update.
Error is solved, but the main question still stand - why I had to do this? Why there are tens of dependencies that are not listed in build.sbt and why should I list my dependency in build.sbt and why it is not sufficient to list it Project-Setting--External Libraries in IntelliJ only?
OK, comment by #Luis_Miguel_Mejía_Suárez gave the explanation, that comment is the actual and expected answer to my question.

Trouble adding tensorflow dependency for scala 2.12.11

I am following a tutorial to perform object detection in scala. I am
having issues adding the tensorFlow dependency. I have followed the instructions on the official Tensorflow for Scala website http://platanios.org/tensorflow_scala/installation.html, but that doesn't seem to work. I also made sure to use the Java 11 JDK for the project. However, whenever I try to add the sbt dependency
libraryDependencies += "org.platanios" % "tensorflow" % "0.4.0" classifier "linux-cpu-x86_64", I get a "No dependencies found for given import" error in IntelliJ. Any idea on how to set this up properly ?
Try to replace one % in your dependency line to twice %%:
libraryDependencies += "org.platanios" %% "tensorflow" % "0.4.0" classifier "linux-cpu-x86_64"
On top of what the previous answer already suggested, I believe it's probably worth mentioning that (until 2.12) libraries in the 2.x are not binary-compatible across versions. The convention for Scala libraries is to append a _2.x to the published library JAR's artifact identifier. Since SBT was built around Scala (and it's its de facto standard build tool) it acknowledges this conventions and the %% operator will automatically append that extra "qualifier" based on the Scala version you are using.
Notice here on mvnrepository.com how the artifact identifier changes between the Maven and the SBT dependency declaration (in Maven, the artifact identifier is tensorflow_2.12, in SBT the %% allows you to not have to specify that).
The single % is generally used for Java dependencies (that are not affected by the aforementioned convention).
As an alternative (that I would suggest just to play around and see that there's no magic involved), you can also use % to specify a Scala dependency and explicitly mention the Scala version in the artifact identifier, as follows:
libraryDependencies += "org.platanios" % "tensorflow_2.12" % "0.4.0" classifier "linux-cpu-x86_64"
The good news is that starting from Scala 2.13 this issue was tackled at the very root using an intermediate representation that was also introduced to make sure the interoperability between Scala 2.13 and Scala 3.x compiled code.
EDIT
What you have found was actually an issue in the documentation that was already reported, I opened a PR to fix it.

Necessary to export Quasiquotes dependency for exported macro libraries on Scala 2.10?

I just updated a project which was using macro-paradise 2.0 snapshot under 2.10; with the final version of macro-paradise 2.0 it tells me the following when I compile under 2.10 (not 2.11):
Quasiquotes in macro paradise for Scala 2.10 require a dependency on a supporting library. Add the following line to your SBT build: libraryDependencies += "org.scalamacros" %% "quasiquotes" % "2.0.0"
Now I'm worried because that dependency turns up as a regular dependency of my published Maven artifact. Is this really so? Or isn't Quasiquotes perhaps just a compile-time dependency that should not be needed for the published artifact?
If so, should I go through these hoops to get rid of the artifact, i.e. % "compileonly"?
Macros that use quasiquotes provided by recent versions of paradise for Scala 2.10, i.e. 2.0.0-M4+, including 2.0.0 and later ones, will almost always require the supporting library to be on classpath when expanding (very simple quasiquotes don't require the library, but that's quite rare).
Therefore if you want users of your library to also use macros that you've written with quasiquotes, you'll need to export "org.scalamacros" %% "quasiquotes" % "2.x.y" in your pom file or rely on someone else to provide this dependency for your users.
Well, I just tried the approach in the linked question to create a special "compileonly" configuration and thus remove it from the exported POM. It was possible to use the library in Scala 2.10 even with Quasiquotes absent.