Writing sbt plugin that exports itself to child projects? - scala

I'd like to write a plugin that makes its code available to projects that uses the plugin.
The plugin would be defined as follows:
package mypackage
object MyPlugin extends sbt.Plugin {
...
}
trait MyInterface {
...
}
A client code should be able to export and instantiate mypackage.MyInterface to make possible for plugin distinguish MyInterface instances during parsing Analysis API info.
I should add that I would like to create separate config for doing some code testing (existing test are not suited for me) and plugin would be exported only to this config's classpath.
If someone would like to ask if this approach is legitimate I answer that sbt itself uses this method for working with plugins. I've found almost no documentations for writing sbt plugins and was forced to peek inside the sbt code. There I found similar cases and some hints. But the code is too complicated full of macroses and DSL with lack of documentation strings, so I grasp only part of it.

My rather limited knowledge about sbt lets me argue about the merits of your question and what you're going to achieve.
Since a plugin is a part of the build and should (merely) help the project's artifact(s) see the light of production release, it should in no way be the artifact's dependency as you'd have to release the dependency (that's a sbt plugin in its current form) so others would be able to download it, too.
What you'd rather do is to have a plugin that wraps a dependency and when included in a build makes the dependency a dependency of your project. That's acceptable in my opinion.
How much do I differ from your use case? I'd happy to refine the answer after having heard some additional information.

Related

What is the differences between code injection and sub-classing in Java

I was reading about code-injection at run-time and there are many tools/APIs available like Javassist, GluonJ and AspectJ which provide features to inject code. However, I did not understand purpose for injecting code at run-time while we can do override behaviors by sub-classing in Java. With Javassist and GluonJ, I can create classes at run-time but why does anyone do that, in the first place? Can anyone please help me to understand the difference and purpose of code injection ?
Code injection is usually used into application that are used to modify/check/trace other software. In Java we usually reffer to this kind of library as Bytecode modification libraries so if you look on the internet you will probably find more information under this name.
Here I listed a couple of examples of big and famous projects that I now are using Bytecode modification into their cores:
Evosuite: this project takes an application in input and generates unit test for it. Code injection is used to explore the desired project and dependencies and traceability
JaCoCO: this project is a tool for Java project. It is supposed to be attached to your application and once you run your JUnit tests it is going to generate a report on the coverage achieved. Obviously here code injection is necessary to trace every method call made during test execution.

How do I create a custom scala library using sbt?

Like it says on the tin, how would I go by creating a library using sbt?
I have a set of utilities and convenience functions that I want to be easily distributed between my projects. The easiest way to do this of course, is by having them compile to a library, that I can then include in the build path of any given project that'll use it.
Libraries are often much easier to include in multiple projects than having multiple copies of the same classes. So how would I do this?
Just create a project with the library code, and use the publishLocal command to put it in your local Ivy repo. Then you can include it in other projects.
This next bit may be overkill for your case, but I have this blog post outlining how to do all of this for an open source project. Perhaps you'll use it as inspiration to make it available for us all to enjoy. :)

Play Framework How to Compile Views for Distribution

I have common views that I want to share across multiple Play Framework 2.2.1 applications. I'm thinking packaging them up into a single library and publishing them to our Maven repo is the way to go, but something isn't working correctly during the compile phase.
My project has a single file My/Namespace/myView.scala.html. After compiling my package jar has a file named exactly as my view. My/Namespace/MyView.scala.html I was expecting to see some class files.
The play framework seems to do something very similar https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/views/helper/twitterBootstrap/twitterBootstrapFieldConstructor.scala.html and looking at their Maven package this seems to compile into a twitterBootstrapFieldConstructor class (along with all the meta classes scala generates):
I'm guessing i'm missing something in my SBT configuration that makes it compile scala.html files...but i'm just not seeing it.
Anyone have some insight into what i should be doing?
It appears the best option at this time is to make use of the Twirl library https://github.com/spray/twirl which is the template engine wrapped up into a similar but distinct API.
sbt .13 support is in a testing phase see https://github.com/spray/twirl/issues/15#issuecomment-32272389 as it appears there's going to be some reconciliation of this project & play's templating libraries (one using the other)

How best to structure and build Clojure apps with plugins?

I think (see below) that I would like to structure a Clojure project as multiple modules, with ordered dependencies - just like Maven lets me do with multi-modules projects.
But I can't see how to do this with Leiningen - all I can see is the checkouts fix described in the FAQ which doesn't seem to be as powerful.
Will lein do this? Should I be using Gradle instead? Or is this kind of thing not needed?
Some more context: I am wondering how to architect a modular application that supports plugins (which I imagine means jars dumped on the classpath). And am wondering to what extent I can structure that as a core + plugins (I am thinking I should be able to do something with Clojure's dynamic code loading and not have to go with Java/OSGi). So I guess the driving motivation for a single project comes from wanting some way of packaging everything (the core + default plugins) as a single blob that is easy for the end user, but which can also be divided up (and which is built and tested in fragments, testing the logical independence of each module). More general advice about this is welcome
Update
A possible solution that wasn't mentioned below is using a Maven plugin - I assume that supports everything Maven does, but compiles Clojure, so will work with nested modules, etc.
First, it does not seem like Leiningen supports a module hierarchy like Maven does. The checkouts are the next closest thing it has. It should be sufficient though to develop a modular application in Clojure though.
For the project structure, I would have an API project, a "core" project, the plugins themselves, and a separate packaging project. The core and the plugins should only depend on the API. Which build tool you use to create the packaging project is up to you. Gradle would probably be more effective at handling the packaging, however having the "checkout" functionality Leiningen offers could make development of the system as a whole easier.
I would take a look at the code for Leiningen and Noir to figure out how to effectively handle this.
For dynamically loading the plugins, I would start with looking how Noir handles it in two of their files:
server.clj has namespace loading for all files under a particular namespace. Under the hood it uses tools.namespace, but you can easily see how it's used to require every namespace under a particular base. This is how Leiningen handles custom tasks as well - the base definition for the task should be in the leiningen.$task namespace.
core.clj has what I would use for plugin registration. In summary, use a map under an atom and add plugins to that map. I would advice wrapping the registration with a macro to keep your code cleaner.
What I listed above should be sufficient if you don't need to handle adding plugins at run time. If you don't have every plugin on the classpath during start-up, I would recommend utilizing pomegranite to add entries to the classpath. You can see an example in classpath.clj.

Basic maven issue- building a java/scala library

I'm sure I'm just being obtuse but I've bought the OA book, a couple of others and I'm still just as dense as before....I'm trying to build a scala library with maven and the scala plkugin, but I think this applies to Java as well.
It has no main code module, it's just a library. If I have a class such as com.busygeeks.binklebots and source files under it, I created
src
scala
com
busygeeks
binklebots
sourcefies.....
When I try a maven:compile, it completes successfully, but doesn't actually build anything.
I know it's very basic -- but I'm missing it. How can I say "Take everything under src/scala and build and jar it"
It looks like you might just need a main directory in there between src and scala.
If you really wanted to, you could specify a custom layout with the java and scala directories immediately under src. But you almost certainly don't want to, for the reasons given in the Maven documentation linked above.