SBT Compiler Plugin as Transitive Dependency - scala

I have a library that uses the macro paradise plugin (referred to as macro-provider library). In the build.sbt,
addCompilerPlugin("org.scalamacros" % "paradise" % "2.0.0" cross CrossVersion.full)
to gain access to the macro annotations.
When adding the macro library as a libraryDependency to a separate project (referred to as macro-consumer project), the annotations are present, but the macro implementation is never called. Adding the macro paradise compiler plugin to the macro-consumer project libraryDependencies solves the problem.
Is it possible to include compiler plugins as transitive dependencies? This would free consumers of the macro library from adding the required plugin.
Update #1:
The addCompilerPlugin helper adds the dependency to the libraryDependencies and sets the dependency with a configuration = Some("plugin->default(compile)") within the macro-provider library.
Adding the paradise dependency in the libraryDependencies of the macro-provider library causes the artifact to show up in the macro-consumer project. It does not add the dependency as a compiler plugin.
Update #2:
Setting autoCompilerPlugins := true in the macro-consumer project in conjunction with Update #1 does not resolve the issue.

The only way I found to resolve this issue was by adding a sbt-plugin sub-module that includes the settings required. The plugin is very basic,
package fixme
import sbt._
import Keys._
object Plugin extends sbt.Plugin {
val paradiseVersion = "2.0.0"
val fixmeVersion = "1.4"
val fixmeSettings: Seq[Setting[_]] = Seq(
resolvers += "tysonjh releases" at "http://tysonjh.github.io/releases/",
libraryDependencies <++= (scalaVersion) { v: String ⇒
(if (v.startsWith("2.10")) List("org.scalamacros" %% "quasiquotes" % paradiseVersion % "compile")
else Nil) :+
"org.scala-lang" % "scala-reflect" % v % "compile" :+
"com.tysonjh" %% "fixme" % fixmeVersion % "compile"
},
addCompilerPlugin("org.scalamacros" % "paradise" % paradiseVersion cross CrossVersion.full))
}
This can be used by including in your project/plugins.sbt,
resolvers += "tysonjh releases" at "http://tysonjh.github.io/releases/"
addSbtPlugin("com.tysonjh" % "sbt-fixme" % "1.4")
and the build.sbt file,
fixmeSettings
The sbt-plugin settings add the macro paradise plugin as a compiler dependency and the macro implementation as a library dependency.

Related

Intellij Scala classpath not found

I am trying to use json4s but I keep getting the error below when I compile. I thought the library would have the class internally. I am using json4s-ast_2.11-4.0.0-M1.jar, json4s-core_2.12.3.5.3.jar and json4s-jackson_2.9.1-3.0.0.jar.
Error:(64, 25) Symbol 'type org.json4s.JsonAST.JValue' is missing from the classpath.
This symbol is required by 'type org.json4s.JValue'.
Make sure that type JValue is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
A full rebuild may help if 'package.class' was compiled against an incompatible version of org.json4s.JsonAST.
Imports:
import org.json4s.jackson.JsonMethods._
import org.json4s._
build.sbt
scalaVersion := "2.12.4"
libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.0.0"
libraryDependencies += "org.json4s" %% "json4s-ast" % "4.0.0-M1"
libraryDependencies += "org.json4s" %% "json4s-core" % "3.5.3"
You can't use libraries compiled for different versions of scala in other versions. You need to fix the versioning of your JSON4s. Look at:
http://www.scala-sbt.org/0.13/docs/Cross-Build.html#Using+Cross-Built+Libraries

Can't use imports inside sbt build definition code

I tried importing JSON libraries in sbt, so that my custom sbt task can write a json file using a JSON api. However it seems like sbt can't import those libraries, but rather it can only import "standard" libraries like scala.io.Source, java.io.File, etc...
Both commented out lines below would each fail sbt:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.3.7"
libraryDependencies += "io.argonaut" %% "argonaut" % "6.0.4"
compile in Compile <<= (compile in Compile) map { c =>
import scala.io.Source
//import play.api.libs.json.Json
//import argonaut._, Argonaut._
What might it be? Must I write a plugin to circumvent this?
$ about
[info] This is sbt 0.13.6
[info] The current project is built against Scala 2.11.6
[info] Available Plugins: ...
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4
Of course I can just string interpolate my json bare-handed but I wonder what might it be...
Thanks!
According to this snippet from the plugin documentation, you just need to include the dependency in plugins.sbt instead of your build definition (ie., no plugin is required).
// [within plugins.sbt]
// plain library (not an sbt plugin) for use in the build definition
libraryDependencies += "org.example" % "utilities" % "1.3"
So you should be able to just add these to plugins.sbt:
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.3.7"
libraryDependencies += "io.argonaut" %% "argonaut" % "6.0.4"

Explain Build.scala in play framework

Can somebody explain the syntax for Build.scala in detail? For example, I have the following Build.scala:
import sbt._
import Keys._
import play.Project._
object Build extends sbt.Build {
val appName = "myapp"
val appVersion = "1.0"
val appDependencies = Seq(
"postgresql" % "postgresql" % "9.1-901-1.jdbc4",
javaCore,
javaJdbc,
javaEbean,
"org.json" %"org.json" % "chargebee-1.0",
"org.reflections" % "reflections" % "0.9.8",
"org.mockito" % "mockito-all" % "1.9.5" % "test"
)
val main = play.Project(appName, appVersion, appDependencies).settings(
libraryDependencies += "com.jolbox" % "bonecp" % "0.8.0-rc2-SNAPSHOT",
resolvers += Resolver.url("sbt-plugin-snapshots", new URL("http://repo.scala-sbt.org/scalasbt/sbt-plugin-snapshots/"))(Resolver.ivyStylePatterns),
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"
)
}
How do I match the appDependencies with the resolvers? Or how do I know what resolvers I need to add for what appDependencies? Where do I look in the resolver's repo? What is libraryDependencies? How are they different from appDependencies?
Thanks.
There are a few things we need to disentangle here.
Let's first distinguish between an sbt build file and Build.scala. While the build file is exactly like a Maven pom or a Gradle build file, think of Build.scala as a build capability with the full power and expressiveness of Scala because it is a Scala class like any other. I believe the gap between the two has narrowed though with the latest version of sbt.
Now in both sbt and Build.scala, you have the notion of library dependencies, which are the jar libraries containing code you can use for your projects. These libraries can be found in lots of places--Maven repositories, the local file system, etc. You use resolvers to specify those locations.
So you tell both which jars you need and where to find them.
As for appDependencies, that's not actually a thing. As I said, Build.scala is a class like any other, and appDependencies is just a variable name. It just makes sense to use that name because that Seq is what you will pass to the Project constructor.

Scala & XSBT - share part of build classpath with project classpath

First of all I'm very new to Scala, SBT and Vaadin.
I'm trying to make an Scala & Vaadin application with Timeline addon. I had to put Timeline jar (unmanaged dependency) and Vaadin dependency under build project (project/) so I can compile it during build (well, by calling vaadin task). How can I merge vaadin-timeline-agpl-3.0-1.2.3.jar and Vaadin dependency into vaadinTest project without duplicating jar and dependency? Below is my project structure. Thank you. By the way, I already tried existing Vaadin plugins but they suck (all I need to do is to compile widgetset).
This is my project structure:
vaadinTest/
project/
lib/vaadin-timeline-agpl-3.0-1.2.3.jar
build.sbt
ProjectBuild.scala
src/
vaadinTest/project/build.sbt:
libraryDependencies ++= Seq(
"com.google.gwt" % "gwt-user" % "2.4.0",
"com.google.gwt" % "gwt-dev" % "2.4.0",
"com.vaadin" % "vaadin" % "6.7.4"
)
vaadinTest/project/ProjectBuild.scala:
import com.google.gwt.dev.Compiler
import sbt._
import Keys._
object ProjectBuild extends Build {
val deps = Seq(
"org.eclipse.jetty" % "jetty-server" % "8.1.0.RC5",
"org.eclipse.jetty" % "jetty-webapp" % "8.1.0.RC5",
"org.eclipse.jetty" % "jetty-servlet" % "8.1.0.RC5",
)
val vaadinTest = Project(
"vaadinTest", file("."), Defaults.defaultSettings
++ Seq(libraryDependencies ++= deps)
++ Seq(vaadinTask)
)
val vaadin = TaskKey[Unit]("vaadin")
val vaadinTask = vaadin := {
Compiler.main(Array("-war", "src/main/webapp/VAADIN/widgetsets",
"com.vaadin.addon.timeline.gwt.TimelineWidgetSet"))
}
}
Your question mentions a "plugin" project, but I can't see that project in your project structure or ProjectBuild.scala?
In any case, you can add additional directories to your classpath by modifying the dependencyClasspath setting. This is documented here (see the "Unmanaged dependencies" section).

LIFT setup for web project: generate with mvn, and manage with sbt

I am new to LIFT, and I am trying to find a reliable instructions how to generate and manage LIFT web project with maven and sbt respectively. Can someone please direct me (or provide here) to the up to date instructions how to setup sbt for the maven generated project? From every post what I've red, it looks like the best setup for the LIFT projects: generate with mvn, manage with sbt. Will you agree? (I cannot generate LIFT/web project with sbt. Right? SBT is only good for managing it. Right? ) Every instructions I tried are out of date though. (I obviously can simply download and un-tar the archetype project, but I want to find a more fundamental approach for managing the environment ) Thanks.
While I'm using lift I don't need a maven at all, just SBT. So, it is very useful to read SBT Getting Started section. Also lift wiki contains some information. But be sure that you read material related to the proper SBT version. And finally, you can pay attention to my lift project template on github.
Good Luck with Lift! It's awesome ;)
By following question in you comment I put here some common config from my projects.
So, that is ./project/build.scala as alternative to ./build.sbt
import sbt._
import Keys._
import com.github.siasia._
import PluginKeys._
import WebPlugin._
import WebappPlugin._
object LiftProjectBuild extends Build {
override lazy val settings = super.settings ++ buildSettings
lazy val buildSettings = Seq(
organization := "com.yourorganization",
version := "0.1-SNAPSHOT",
scalaVersion := "2.9.1")
def yourWebSettings = webSettings ++ Seq(
// If you are using jrebel
scanDirectories in Compile := Nil
)
lazy val shade = Project(
id = "project-name",
base = file("."),
settings = defaultSettings ++ yourWebSettings)
lazy val defaultSettings = Defaults.defaultSettings ++ Seq(
name := "project-name",
resolvers ++= Seq(
"Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases",
"Java.net Maven2 Repository" at "http://download.java.net/maven/2/"),
libraryDependencies ++= {
val liftVersion = "2.4-M5"
Seq(
"net.liftweb" %% "lift-webkit" % liftVersion % "compile",
"org.eclipse.jetty" % "jetty-webapp" % "7.5.4.v20111024" % "container",
"org.squeryl" %% "squeryl" % "0.9.5-SNAPSHOT" % "compile",
"ch.qos.logback" % "logback-classic" % "1.0.0" % "compile",
"org.scalatest" %% "scalatest" % "1.6.1" % "test",
"junit" % "junit" % "4.10" % "test")
},
// compile options
scalacOptions ++= Seq("-encoding", "UTF-8", "-deprecation", "-unchecked"),
javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
// show full stack traces
testOptions in Test += Tests.Argument("-oF")
)
}
./project/build.properties
#Project properties
sbt.version=0.11.1
./project/plugins.sbt
resolvers += Classpaths.typesafeResolver
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse" % "1.5.0")
libraryDependencies <+= sbtVersion(v => "com.github.siasia" %% "xsbt-web-plugin" % (v+"-0.2.10"))
Having these three files are enough to configure sbt.
And of course you can run your application by calling container:start
Your mileage may vary, but my experience with sbt has been less than stellar (out-of-date docs, breakage on version changes, etc). The recent improvements to the eclipse scala IDE and corresponding maven and jrebel plugins make it a clear winner compared to using sbt.
If you follow the instructions, you'll get the ability to build/package at the command line, but superior support for eclipse features and fast development.
See the sample project setup at:
https://github.com/awkay/lift_squeryl_demo