Exclude all dependencies matching pattern - scala

I am upgrading one of the my Scala projects to Scala 2.11.7, but it has some dependent projects. They are using 2.10 so it is referring to a lot of dependent libraries with 2.10 Scala version (ex: com.novus:salat-core_2.10:1.9.9). I want to exclude which and all having "_2.10-" instead of writing one by one.
Is this possible?

1: Using scala version and providing sbt to choose correct version with %%
scalaVersion := "2.11.7"
val scalaz = "org.scalaz" %% "scalaz-core" % "7.1.0"
2: To exclude explicitly dependencies which has 2.10 build version use custom methods
// exclude from all with rule which check whether artifact name contains 2.10
def excludeFromAll(items: Seq[ModuleID], group: String, artifact: String) =
items.map(x => if(x.name.contains("_2.10")) x.exclude(group, artifact))
//all your dependencies
val deps = Seq(dependencies) //library Dependencies.
//exlusion
val appDependencies = excludeFromAll(deps, _, _)

Related

Is it possible to enforce different scala version for a specific dependency using SBT

I'm pretty new to scala. While upgrading a multi-module project to Scala 2.13, I found this dependency that is compiled in Scala 2.12 which throws class not found exception during runtime
java.lang.NoClassDefFoundError: scala/collection/mutable/ArrayOps$ofRef
This class is removed in 2.13. It is available only until 2.12. I am looking for a way to enforce v2.12 to compile only this dependency.
I tried to use cross-building but that does not work for a core library, because the dependency url constructed using:
"org.scala-lang" % "scala-library" % scalaVersion.value
looks like
https://repo1.maven.org/maven2/org/scala-lang/scala-library_2.12.15/2.12.15/scala-library_2.12.15-2.12.15.pom
Also, cross-building seems to be the way to allow compiling sub-modules with different scala versions with their compatible dependency versions, not meant for enforcing scala versions on individual dependencies.
Edit 1:
This is the build definition:
root
|
main
|---dependency w/o 2.13 build
|
acceptanceTests
|---dependency w/o 2.13 build
|
(other modules)
The dependency is an internal commons library. This uses the class scala/collection/mutable/ArrayOps during compile time. From scala-lang -> scala-library.
My questions:
Is it even possible to do this? Or is my only option to downgrade to 2.12 as mentioned here
Why 'core' libraries do not follow the url patters of external libraries like:
[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision].
`Instead it looks like https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.15/scala-library-2.12.15.pom
You can do stuff like this:
libraryDependencies ++= {
CrossVersion.partialVersion(Keys.scalaVersion.value) match {
case Some((2, 12)) => Seq(
"com.typesafe.play" %% "play-json" % "2.6.13"
)
case Some((2, 11)) => Seq(
"com.typesafe.play" %% "play-json" % "2.5.18"
)
case _ => Seq (
"com.typesafe.play" %% "play-json" % "2.4.11"
)
}
}

Reflect Toolbox worked in Scala 2.11 not working in Scala 2.12

This code that works in Scala 2.11 doesn't work in 2.12:
import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
tb.eval(tb.parse("""println("hello!")"""))
I get the error below, what changed in 2.12?
Exception in thread "main" java.lang.AbstractMethodError:
scala.reflect.internal.SymbolPairs$Cursor.matches(Lscala/reflect/internal/Symbols$Symbol;)Z
Note: I had to add to the classpath scala-compiler-2.12.2.jar
Is it possible, that you updated your project to Scala 2.12 but left a dependency on scala-compiler 2.11 on your classpath ?
Nothing changed in 2.12, with relation to your code. In order for your code to work, you must have a dependency on scala-compiler.
Here is a SBT project with Scala 2.11, without scala-compiler dependency:
name := "q53391593"
organization := "sk.ygor.stackoverflow"
version := "1.0-SNAPSHOT"
scalaVersion := "2.11.12"
Your code does not compile: object runtime is not a member of package reflect, object tools is not a member of package scala, not found: value universe
You need to add the dependency on scala-compiler:
name := "q53391593"
organization := "sk.ygor.stackoverflow"
version := "1.0-SNAPSHOT"
scalaVersion := "2.12.6"
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
This will put two additional jars on your classpat: scala-compiler:2.12.6:jar and scala-reflect:2.12.6:jar. If you are not using SBT, make sure, that you include them by yourself.
Also, note the usage of scalaVersion.value to specify the version of the library. This prevents from mixing together incompatible versions of Scala libraries.
The scala minor version number in the pom must also be the same as the scala version number in the environment

Aggregate different modules based on scala binary version

I'm trying to cross build a project for (2.11, 2.12) where some of the subprojects should not be built for 2.12 because their transitive dependencies are not yet released for 2.12. Specifically Spark for Scala 2.12. The root project's aggregate looks like
lazy val root = (project in file(".")).
aggregate(vegas, spark, flink, macros).
settings(commonSettings: _*).
settings(noPublishSettings: _*)
Is there some way to detect the scalaBinaryVersion in the #aggregate and aggregate a different set of projects if the crossbuild is trying to produce a 2.12 artifact?
There appears to be no direct way to do it. As a workaround, you may want to get a similar effect by making spark's libraryDependencies empty and skipping compile and publish when scalaBinaryVersion is 2.12:
// tested on sbt 1.1.0
lazy val spark = (project in file("spark"))
.settings(
// ... other settings ...
// Empty out libraryDependencies when scalaBinaryVersion is 2.12.
libraryDependencies :=
(if (scalaBinaryVersion.value == "2.12") Seq.empty else libraryDependencies.value),
// Skip compilation and publishing when scalaBinaryVersion is 2.12.
skip in compile := scalaBinaryVersion.value == "2.12",
skip in publish := scalaBinaryVersion.value == "2.12"
)
The skip task key allows us to skip some task. From inspect skip:
Task: Boolean
For tasks that support it (currently only compile, update, and publish), setting skip to true will force the task to not to do its work. This exact semantics may vary by task.
However, in contrast to compile and publish, skip in update := scalaBinaryVersion.value == "2.12" does not work here. From sbt Reference Manual:
Overriding all of the above, skip in update := true will tell sbt to never perform resolution. ... Also, (note that) update itself will immediately fail if resolution has not been allowed to run since the last clean.

SBT: Cross build project for two Scala versions with different dependencies

I have the following use case. I would like to build the same Scala project for scala 2.10 and 2.12. When doing so I would like to specify some of the dependencies for the 2.10 version as provided whereas I'd like to have those compiled in the jar for 2.12.
I was looking at SBT's docs and found how I can split a build.sbt into separate declarations but those always get mentioned as sub-modules. In my case I'd like to cross-build the whole app - not specific parts of it.
Any hints or resources will be appreciated.
You can assemble the libraryDependencies depending on the Scala version. Simplified example, may not build..:
libraryDependencies := {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, scalaMajor)) if scalaMajor == 12 =>
libraryDependencies.value ++ Seq(
"your.org" %% "your-lib" % "1.0")
case Some((2, scalaMajor)) if scalaMajor == 10 =>
libraryDependencies.value ++ Seq(
"your.org" %% "your-lib" % "1.0" % provided)
case _ => Seq()
}
}
For a full example, see http://github.com/scala/scala-module-dependency-sample

How can I resolve dependencies when cross-compiling in Scala with sbt?

I want to build a 2.11 and 2.12 version of my project, so I have something like this in my Build.scala file:
val scalaVer12 = "2.12.1"
val scalaVer = "2.11.8"
lazy val basicSettings = Seq(
// lots of other settings
scalaVersion := scalaVer
)
The fly in the soup is I have a dependency on scala reflection, which is based on the scala version. Before I did this:
val scala_reflect = "org.scala-lang" % "scala-reflect" % Build.scalaVer
How can I modify this dependency line so that sbt will use either the 2.11 or 2.12 dependency based upon the version it's currently building?
lazy val bla = project in file("bla")
.settings(
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value
)
)
Never alias dependencies like that, it's clean to have an object to store version numbers, but not more, it's just a smell, especially since deps are often Scala version dependent and you can apply all sorts of rules to them.