Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SBT Compiler Plugin as Transitive Dependency

Tags:

macros

scala

sbt

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.

like image 255
tysonjh Avatar asked May 06 '14 03:05

tysonjh


People also ask

How does sbt resolve dependencies?

Background. update resolves dependencies according to the settings in a build file, such as libraryDependencies and resolvers . Other tasks use the output of update (an UpdateReport ) to form various classpaths. Tasks that in turn use these classpaths, such as compile or run , thus indirectly depend on update .

What is sbt ivy?

sbt (through Ivy) verifies the checksums of downloaded files by default. It also publishes checksums of artifacts by default. The checksums to use are specified by the checksums setting.

Where are sbt dependencies stored?

All new SBT versions (after 0.7. x ) by default put the downloaded JARS into the . ivy2 directory in your home directory. If you are using Linux, this is usually /home/<username>/.


1 Answers

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.

like image 186
tysonjh Avatar answered Sep 21 '22 16:09

tysonjh