Is there a plugin for sbt available which automatically installs JRuby and adds some hooks to automatically run scripts at certain points (e.g. before compilation).
Background: For a (lift) project, I want to use sass, or more specifically, compass as a tool for generating the css. A Java or Scala clone of sass would not be enough, unfortunately.
Of course, It wouldn’t be a problem at all to just generate the css manually and then put both inside the repository and no-one ever needs to care about it.
On the other hand, to ease development on several systems, I’d rather have a clear dependency inside sbt which simply does the work.
Is there any way to achieve this?
Or generally: Is there a way to run JRuby scripts from inside Scala?
Edit Added maven-2 to the tags. Maybe there is a maven repo for JRuby which allows me to deliver and use it somehow.
While it's perhaps not the most elegant solution, you can always call external scripts using the Process support in SBT.
import sbt._
import Process._
class Project(info: ProjectInfo) extends DefaultProject(info) {
lazy val runSomething = task {
"ruby somescript.rb" ! log
None
}
}
There's a bit more info about the external process support available here: http://code.google.com/p/simple-build-tool/wiki/Process
Try my sbt plugin from github. It's very bare-bones for now, but it should download the jruby jar and allow you to call a .rb file before compiling.
The guts of the plugin are really simple:
import sbt._
object SbtJRuby extends Plugin {
object SbtJRubySettings {
lazy val settings = Seq(Keys.commands += jirb, tx, jrubyFile := file("fnord.rb"))
}
def jirb = Command.args("jirb", "<launch jirb>") { (state, args) =>
org.jruby.Main.main(List("-S", "jirb").toArray[String])
state
}
val jruby = TaskKey[Unit]("jruby", "run a jruby file")
val jrubyFile = SettingKey[File]("jruby-file", "path to file to run with JRuby")
val tx = jruby <<= (jrubyFile, Keys.baseDirectory) map { (f: File, b: File) =>
val rb = (b / f.toString).toString
// println("jruby with " + rb)
org.jruby.Main.main(List(rb).toArray[String])
}
}
Really all it's doing is calling the jruby jar file with the name of the rb file you've passed in. And of course adding jruby itself as a managed dependency:
libraryDependencies ++= Seq(
"org.jruby" % "jruby-complete" % "1.6.5"
)
It also adds a "jirb" command to the Scala console that puts you into a jirb session.
Related
The version of Node.js that KotlinJS downloads (as of 1.3.40+) seems not to work in Alpine Linux. The docker image I'm using already has Node baked into it, so there's no reason not to use that one.
However, I'm having trouble figuring out how to set download to false (which should cause KotlinJS to build using the node on the PATH).
The relevant section of my build.gradle looks like this:
kotlin {
target {
useCommonJs()
browser()
}
}
Any help would be appreciated!
Looks like it's pretty similar to #talalUcef's answer:
kotlinNodeJs {
download = false
}
Using the KotlinBrowserJs plugin applies the NodeJsRoot plugin.
The NodeJsRoot plugin applies itself, which causes the NodeJsRootExtension to be included under the name kotlinNodeJs.
Thus, I believe, any of the vars here can be set inside a kotlinNodeJs block.
You can add
node {
download = false
}
on your build.gradle file
For my Android project I want to run a test HTTP server for my integration tests. I've created a Configuration and have written a task to run my Groovy script the sets up the HTTP server
configurations {
stubs {
description = "Classpath for HTTP server for stubbed data"
visible = false
}
}
dependencies {
compile "com.android.support:support-v13:+"
stubs "org.codehaus.groovy:groovy:2.3.4"
stubs "com.github.tomakehurst:wiremock:1.46"
}
When I edit the Groovy script IntelliJ tells me that the Groovy SDK hasn't been configured.
How can I have IntelliJ use the Groovy SDK that is part of the stubs Configuration? I can't create a Groovy SDK configuration using the Gradle fetched libraries as IntelliJ tells me that the Groovy distribution is broken because the version number can't be determined.
Am I forced to have to download the distribution manually?
The solution was to separate out the project for the HTTP server into a separate project and use Gradle's multiproject's ability to set up the Android tests to depend on the HTTP server being started. Because the separate project is a Groovy project, IntelliJ reads the Groovy version to use from the project's dependencies and all is well.
dependencies {
compile "com.android.support:support-v13:+"
stubs project(":integration-server")
}
/*
* The android plugin defers creation of tasks in such a way that they can't be accessed eagerly as usual
* #see http://stackoverflow.com/questions/16853130/run-task-before-compilation-using-android-gradle-plugin
*/
gradle.projectsEvaluated {
connectedAndroidTest.dependsOn(":integration-server:startBackgroundServer")
// Note: finalizedBy is still #Incubating
connectedAndroidTest.finalizedBy(":integration-server:stopBackgroundServer")
}
integration-server/build.gradle
apply plugin: "groovy"
apply plugin: "spawn"
dependencies {
compile "org.codehaus.groovy:groovy:2.3.4"
compile "org.codehaus.groovy:groovy-ant:2.3.4"
compile "com.github.tomakehurst:wiremock:1.46"
}
task startBackgroundServer(type: SpawnProcessTask, dependsOn: "build") {
def cp = sourceSets.main.runtimeClasspath.asPath
command "java -cp $cp server"
ready "Started DelayableSocketConnector#0.0.0.0:8089"
}
task stopBackgroundServer(type: KillProcessTask)
To prevent the Gradle build blocking I'm using a Gradle Spawn Plugin to launch the HTTP server in the background.
I'm using scripted test framework to test a sbt plugin. As part of that test it needs to download artifacts from a private artifact store. Scripted seems to ignore the credentials in the ~/.sbt/0.13 directory. How can I get my test to use those credentials?
It would be good if I didn't have to hard code any path.
I assume you have followed the official Publishing document and have a .credentials file containing realm, host, user, password:
realm=Sonatype Nexus Repository Manager
host=nexus.scala-tools.org
user=admin
password=admin123
Then in the build.sbt of your test add
credentials += Credentials(BuildPaths.defaultVersionedGlobalBase(sbtVersion.value) / "credentials")
This is my hack/workaround for the problem.
In scripted.sbt I add the following code.
credentials ++= {
val out = credentials.value.map {
case c: FileCredentials => s"""Credentials(new java.io.File("${c.path.getAbsolutePath}"))"""
case c: DirectCredentials => s"Credentials(${c.realm}, ${c.host}, ${c.userName}, ${c.passwd})"
}.mkString(" credentials ++= Seq(", ",", ")")
sbtTestDirectory.value.listFiles.flatMap(_.listFiles).map(f => IO.writeLines(f / "credentials.sbt", Seq(out)))
List()
}
This takes the existing sbt credentials and writes a credentials.sbt into each of the scriptet tests, e.g sbt-test/test-group/test-name/credentials.sbt. This is then used by the scripted tests.
My sbt knowledge is somewhat limited so this is a bit ugly.
I am using Intellij Idea version 12 (ultimate). Just installed Team City (version 8). One default agent, running in linux.
I've created a very simple test application:
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
}
public int sum(int x, int y) {
return x+y;
}
}
... and a very simple test...
import junit.framework.Assert;
import org.junit.Test;
public class MainTest {
#Test
public void testSum() throws Exception {
Main test=new Main();
Assert.assertEquals("Sum should be 7",7,test.sum(4,4));
}
}
If I run this in IntelliJ, the test gets run and fails just like it should.
If instead I commit this project and push it up to github, TeamCity sees the change and begins a build. The build fails fairly quickly with the following errors:
/home/ctb/TeamCity/buildAgent/work/742505fa88794219/test/MainTest.java:1: package junit.framework does not exist
import junit.framework.Assert;
^
/home/ctb/TeamCity/buildAgent/work/742505fa88794219/test/MainTest.java:2: package org.junit does not exist
import org.junit.Test;
^
/home/ctb/TeamCity/buildAgent/work/742505fa88794219/test/MainTest.java:12: cannot find symbol
symbol : class Test
location: class MainTest
#Test
^
/home/ctb/TeamCity/buildAgent/work/742505fa88794219/test/MainTest.java:15: cannot find symbol
symbol : variable Assert
location: class MainTest
Assert.assertEquals("Sum should be 7. Loser!!",7,test.sum(4,4));
^
So yeah, I see that TeamCity is not seeing JUnit.
On the TeamCity Discussion forum, one respondent to my question there asked me if junit.jar was added as a dependency (module or library) in the build. It was listed as a module dependency, but for kicks I tried it as a library dependency. I also tried checking and unchecking export and trying the compile and test scopes, but each time I get the same errors. My run configuration is shared.
I am not using Ant or Maven. Perhaps someday, but I'd like to start as simple as possible.
Clearly, I'm missing something, but the documentation on the subject is sparse.
Thank you.
So I heard back from Jetbrains tech support this and, in the interest of completeness and saving someone else the trouble, here's the response I received:
Seems the problem is that junit.jar is not placed in version control
under your project. In order to build your project on TeamCity agent,
the project ideally should be self contained. In your case junit.jar
only exists on your local machine, I suppose there is no such file on
agent at required location. So you have two options actually: put
junit.jar under version control into your project, or define global
library in IDEA and configure this global library on IDEA Project
runner page (Check/Reparse must be started), after that put library
files on all of the agents where your build will be executed.
Personally, I think the first approach is much simpler and better.
I added junit to version control and now the build works properly in TeamCity.
I'm trying to configure a play framework 2.1.1 project to work in Idea with some plugins.
For instance I want to use Mailer plugin from here:
https://github.com/typesafehub/play-plugins/tree/master/mailer
My configuration:
Build.scala
object ApplicationBuild extends Build {
val appName = "testplay"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
// Add your project dependencies here,
javaCore,
javaJdbc,
javaEbean,
"com.typesafe" % "play-plugins-mailer_2.10" % "2.1-SNAPSHOT"
)
val main = play.Project(appName, appVersion, appDependencies).settings(
// Add your own project settings here
)
}
plugins.sbt
// Comment to get more information during initialization
logLevel := Level.Warn
// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// Use the Play sbt plugin for Play projects
addSbtPlugin("play" % "sbt-plugin" % "2.1.1")
build.properties
sbt.version=0.12.2
app is generated by play idea and I've just added Mailer dependency.
Code which uses plugin to send email is not recognized by idea as valid.
Is there a way to fix this? May be I need to add some dependencies manually?
Code is working on server, but it is quite annoying as I cannot validate code in IDE without deploying it.
Thanks for responses.
You just need to relaunch the idea command, after sbt has refreshed your dependencies
Add a dependency in Build.Scala
sbt> reload
sbt> idea
Open idea, a popup will alert you to reload the project.