Sbt Plugins vs Compiler Plugins - scala

I am trying to understand why Adding sbt plugins in plugins.sbt in the project, works perfectly fine, but if I add the compiler plugins in that file it does not work ?
I thought any .sbt or .scala file in project, is made available for the build definition.
The only place where compiler plugins works is in the build.sbt. Hence i am confused as to why ?
In particular i am working with Kind-Projector
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.3" cross CrossVersion.full)
I see the following alias for the function
/** Adds `dependency` to `libraryDependencies` in the auto-compiler plugin configuration. */
def addCompilerPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
libraryDependencies += compilerPlugin(dependency)
Hence just trying to understanding, what makes it that it can only be added to the build.sbt and not plugins.sbt in project/

Remeber sbt is recursive.
.sbt define things that are available in the current layer.
.scala files define thins that will be available in the next layer.
Adding an sbt plugin in project/bar.sbt is adding that plugin to the meta layer, as such the meta-layer that compiles the sbt you are using to compile your project adds those plugins to the next sbt layer.
So if you add a compiler plugin in project/foo.sbt then you are adding that compiler plugin to the compiler used to compile the project (meta) layer of sbt, but it will not be available in the current layer of sbt. That is the reason why compiler plugins are added in the build.sbt file, so they are added to the compiler used to compile your code.

Related

How to use external dependencies in sbt's .scala files?

This is for Scala 2.11.1 and sbt 0.13.5.
Say I have a Scala/sbt project with the following directory structure:
root/
build.sbt
src/ ..
project/
plugins.sbt
build.properties
LolUtils.scala
and I want to use some external library in LolUtils.scala. How is this generally accomplished in sbt?
If I simply add the libs I need into build.sbt via libraryDependencies += .. then it doesn't find them and fails on the import line with not found: object ...
If I add a separate project/build.sbt, for some reason it starts failing to resolve my plugins, plus I need to manually specify the Scala version in the nested project/build.sbt, which is unnecessary duplication.
What's the best way to accomplish this?
sbt is recursive which means that it uses itself to compile a build definition, i.e. *.sbt files and *.scala files under project directory. To add extra dependencies to use them in the build definition you have to declare them in a project/build.sbt.
There is one caveat to that. You can set any scalaVersion to your project, that is in build.sbt, but you should not modify scalaVersion in the project/build.sbt as it might conflict with the version sbt itself uses (that may or may not lead to binary incompatibility for plugins).
Sbt 0.13.5 is using Scala 2.10.4, and the library you're going to use must be compatible with that particular version of Scala.
> about
[info] This is sbt 0.13.5
...
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4

IntelliJ 13 with SBT plugin does not recognize Scalding dependency

I am trying to add Scalding 2.10 as a managed dependency via build.sbt like so:
name := "ss"
version := "1.0"
libraryDependencies += "com.twitter" % "scalding_2.10" % "0.10.0"
IntelliJ downloads the jar and adds it as an external library (see screen below) but fails to resolve the com.twitter namespace.
I have tried both invalidating the IntelliJ cache and generating project files via sbt gen-idea but neither solutions have worked. Any ideas would be greatly appreciated.
The scalding jar file scalding_2.10 has no code in it to compile against. Its just 300 Bytes in size.
The correct dependency I feel should be
libraryDependencies += "com.twitter" % "scalding-core_2.10" % "0.11.1"
As the comment suggest try rm-ing your ivy2 cache, and try sbt gen-idea. If that doesn't work, other things to check:
makes sure you have indeed got the scala plugin installed.
Most likely you're java SDK is not set or pointing somewhere wrong; right click the project dir, click "Open Module Settings", go to SDK and make sure the path is correctly set to the jdk otherwise syntax highlighting will likely break.
To test your deps have been properly pulled in from tinternet, try sbt compile; if it compiles then you should indeed have downloaded the dependency properly.

How to resolve a non-jar (dll/jnilib) library dependencies in sbt?

In a SBT build.sbt project file, is it possible to retrieve library dependencies which are not bundled as jar?
In my case, I am trying to use QTSampledSP which requires .dll and .jnilib libraries.
To download the artifact, you need to make Ivy (and hence sbt) explicitly aware of the DLL artifact. Add the following to build.sbt in your project.
lazy val QtSampledJniLibArt = Artifact("qtsampledsp-osx", "jnilib", "jnilib")
libraryDependencies += "com.tagtraum" % "qtsampledsp-osx" % "0.9.6" artifacts(QtSampledJniLibArt)
resolvers += "beatunes" at "http://www.beatunes.com/repo/maven2"
Then you need to tell sbt to pay attention to these artifacts (again build.sbt):
classpathTypes ++= Set("jnilib", "dll")
By default, sbt will only add a few types into the classpath (and jnilib and dll are not amongst them).
[sbt-0-13-1]> help classpathTypes
Artifact types that are included on the classpath.
[sbt-0-13-1]> show classpathTypes
[info] Set(eclipse-plugin, bundle, hk2-jar, orbit, jar)
Since these DLLs/jnilibs are needed on the classpath to run correctly, the above setting classpathTypes where you add the additional types will correct things as you can see below (don't forget to reload when in sbt console).
[sbt-0-13-1]> show classpathTypes
[info] Set(eclipse-plugin, bundle, hk2-jar, jnilib, orbit, jar, dll)
If you need to look in more detail at these files, check out the update report (from the update task) where you can inspect all configurations/modules/artifacts. Run show update in sbt console and look at the files in target/resolution-cache/reports.

setting sbt scalafx project

javafx is now in oracle-jdk.
scalafx gives delicious examples in its repository
The main questions I'm not being able to answer is "How to get started with scalafx"?
How can I add scalafx libary dependencies on my sbt project?
ScalaFX is soon to reach a stable release state.
As I write this you can find the published artifacts for version 1.0.0-M2 on the maven central repo
Adding the dependency to your sbt build should suffice
libraryDependencies += "org.scalafx" %% "scalafx" % "1.0.0-M2"
I did it the following way: I cloned the scalafx repository, build the jar using sbt package, then just copied the resulting jar into lib/ directory of my project. Make sure to reference your ${JAVAFX_HOME}/lib/jfxrt.jar as well.
If you want to use local maven, just run sbt publish-local in your scalafx dir, then add the following dependency to your project:
"org.scalafx" % "scalafx" % "1.0-SNAPSHOT"
(Look up that version in scalafx build.sbt, I pasted what was in mine)
#ayvango i have created a giter8 scalafx project template.just use
g8 jugchennai/scalafx.g8
You just need a new version of JDK, Giter8 and SBT. Dependency settings for javafx, scala, scalafx are predefined! IDE support also available.
URL : https://github.com/jugchennai/scalafx.g8

Adding unmanagedJars to proguardLibraryJars in SBT

I am attempting to use sbt with the following plugin https://github.com/siasia/xsbt-proguard-plugin. So far I haven't had any issues with the plugin, apart from the fact that proguard puts all of the unmanaged jars into the final min.jar file (causing problems with multiple jar's that conflict). Proguard has the proguardLibraryJars flag which allows you to specify jars for proguard to exclude
Essentially I want to add all of the jars from the TaskKey unamangedJars to proguardLibraryJars using the plugin, i.e. do something like this
lazy val proguard = proguardSettings ++ Seq(
proguardOptions := Seq(
keepMain("com.test.FacebookPostScheduler"),
keepMain("org.postgresql.Driver")
),
proguardLibraryJars <++= unmanagedClasspath
)
The problem is the above obviously doesn't compile at this line
proguardLibraryJars <++= unmanagedClasspath
with the
No implicit for Append.Values[Seq[java.io.File], sbt.Keys.Classpath] found
error.
How would you code what I am attempting to do using the latest SBT (0.11.3-2) using a Build.scala (not a build.sbt)
I have a public repository of an SBT plugin that manages to pass jars to proguard. It doesn't use the proguard plugin but the code might help you figure how to gather dependencies.
https://github.com/tlazaro/xsbt-plugin-deployer/blob/master/src/main/scala/Deployer.scala
Look for:
private def getDepsJars(project: ProjectRef, bs: BuildStructure) = forAllProjects(project, bs) {p =>
artifactPath in Compile in packageBin in p get bs.data
}
That might give you a way to get started. It gathers every needed jar which is what you usually want, not just the unmanaged.
Alternatively you can just use this plugin and maybe collaborate. The code is a bit sloppy, it not intended to be released yet. The plugin does some other neat stuff like compressing everything with pack200 into a jar and having a custom ClassLoader that loads the compressed classes from there in runtime.
adamw/xsbt-proguard-plugin, which is the successor of siasia/xsbt-proguard-plugin seems to have the very option:
By default Proguard will be instructed to include everything except classes from the Java runtime. To treat additional libraries as external (i.e. to add them to the list of -libraryjars passed to Proguard), do the following. Here comes the example how to select a module named "httpclient" from the library dependencies:
proguardLibraryJars <++= (update) map (_.select(module = moduleFilter(name = "httpclient")))