Can you put SBT code inside a scala script? - scala

I'm sure I've seen a page that shows how to put SBT instructions inside a scala file, instead of build.sbt. The advantage is that everything then lives in a single file, which makes it easier to use Scala as a scripting language.
But I can't now find the example... can anyone help?
BTW, I know about ammonite, but it has limitations compared to SBT.

I think you're looking for this page of the sbt docs: Scripts, REPL, and Dependencies. There are also some other resources on the topic:
an example project by Eric Richardson with detailed instructions: ekrich/sbt-scripting
a post by Eugene Yokota (maintainer of sbt): scripting with Scala (it's from 2014, so I'm not sure if it's still relevant)
an example script gist by Seth Tisue

You can create your customize scala file under project/ directory and import it in build.sbt, like:
├── build.sbt
└── project
└── Settings.scala
so you can import it in build.sbt:
import Settings._

Related

IntelliJ SBT directory structure

I created a new SBT project HelloScala, then I created a package called week6 and then a Scala worksheet under it. Eventually, I got the following directory structure:
~/HelloScala/.idea
~/HelloScala/project
~/HelloScala/src/main/scala
~/HelloScala/src/main/scala-2.12/week6/hello.sc
However, when I put package week6 in the worksheet hello.sc, IntelliJ warns that Project names doesn't correspond to directories structure. My questions are:
What should be the correct directory structure IntelliJ/SBT expects? Is it specified in some .xml file?
Notice that IntelliJ created two scala subdirectories, scala and scala-2.12. Is it correct? Or IntelliJ somehow failed to recognize the scala which had already existed but download and install another scala?
Thank you!
I don not use IntelliJ that often, but usually Scala packages should go into src/main/scala.
The structure of a Scala project is nothing too different from a Java one. Minimally you will need:
myproject
├── build.sbt
└── src
└── main
└── scala
└── mypackage
which is a project with a single package, a SBT script and nothing else.
For a more complex example, a Scala project could look like:
project
├── build.sbt
├── project
├── target
└── src
├── main
│ ├── java
│ ├── resource
│ └── scala
└── test
├── java
├── resource
└── scala
in which the project folder is used by SBT for various purposes, the target folder contains the compiled .class files and .jar packages.
To answer your questions:
The above structure is used implicitly by the SBT plugin. Maybe it is customizable, but in most cases it is suggested against doing this.
Your Scala source code should go into src/main/scala. I have no idea where does the other directory come from.
#sgu It seems I misunderstood your question and unfortunately I cannot leave a comment. The file "hello.sc" you are trying to deal with is treated by IntelliJ as a "Scala worksheet". I guess it is a REPL behind IntelliJ which evaluates as you edit. However it is not treated the same as a "Scala source file", so adding package xxx gives you the warning. If you want to create a package, the source files should be in ".scala" extension.
You should put all your source code under "main/scala" directory. "Scala-2.12" is the directory, that would be created with sbt under "project/target" after you compile/build it.
Have you tried clicking the Make project option on top of the scala sheet in Intellij Idea? I use that option when I need to import oher packages into one scala worksheet.

How do I execute Scrooge from commandline?

I was able to include scrooge in my SBT project (the scrooge-sbt-plugin in my plugins.sbt as well as the library dependencies in my build.sbt), but I haven't been able to figure out how to execute scrooge from the commandline as listed here http://twitter.github.io/scrooge/CommandLine.html.
A bit late to the party.
#partycoder was indeed right, however a bit more may help those
who like myself aren't too sure.
Assuming your *.thrift files are located in src/main/thrift simply running sbt scrooge-gen will pick up the files and deposit them in target/src_managed/.
If your *.thrift files are not located in src/main/thrift and perhaps in src/main/resources/thrift, you can setscroogeThriftSourceFolder in you build.sbt using this example:
scroogeThriftSourceFolder in Compile <<= baseDirectory {
base => base / "src/main/resources/thrift/"
}
This setting and others can be found here.

How do I use shared configurations across SBT (Play) multi-projects?

I have several SBT 0.13 / Play 2.2 projects (websites). They are all multi-module as they share some common functionality. This makes their project configuration files both complex and almost identical, but not quite.
I would like to be able to share as much as possible of these configuration files across the projects (frequent play updates makes keeping 5+ websites up to date a royal pain, not to mention all the almost-identical-but-evolving dependency lists across the projects).
build.properties and plugins.sbt are identical across projects and can be overwritten by a simple script. Great.
Build.scala is trickier - I would like to introduce a shared base class like so:
abstract class MyBuildBase extends Build { ... }
that in Build.scala do:
object ApplicationBuild extends MyBuildBuild { ... }
In order for this to make any sense at all, MyBuildBase.scala needs to be shared across projects. This can be done with svn:external, which operates on directories. Which means I need to somehow make this shared directory accessible when Build.scala is compiled (otherwise sbt complains loudly).
Reading http://www.scala-sbt.org/0.13.0/docs/Detailed-Topics/Classpaths.html and http://www.scala-sbt.org/0.13.0/docs/Getting-Started/Full-Def.html it seems like this should be possible.
However, it is exceptionally unclear to me what to actually put in the project/project/Build.scala file to actually achieve this - I can't find an example of "an sbt build file that's intended to build an sbt build file and include some extra source files in the build".
Any suggestions?
What you probably want to do is create a plugin, or shared library.
You can make an sbt project with a build like follows:
build.sbt
sbtPlugin := true
organization := "you"
name := "common-build"
version := "1.0"
Then create in src/main/scala your abstract class "MyBuildBase". Release this project as an sbt plugin.
Then in your other projects, you can use this as a library/plugin. In project/plugins.sbt add:
addSbtPlugin("you" % "common-build" % "1.0")
And this will resolve your common build library when building your build.
If you need more information, look up more about sbt plugins and ignore the part about making something that extends a Plugin. Plugins are just libraries versioned with sbt's version number and your own. You should be able to put whatever code you want in there to share between builds.
Note: in 2016, Build.scala is deprecated for Build.sbt.
Here is the new (Dec. 2016) multi-module with App Scala sbt template by Michael Lewis.
Usage
sbt new lewismj/sbt-template.g8
You can then run:
sbt compile
sbt publish-local
sbt assembly
It is based on Scala SBT template (Library)
This giter8 template will write SBT build files for a Scala library.

Compile scala files from a sbt plugin

I am developing a sbt plugin. In this plugin I generate some new scala sources packaged in a sbt project. Then I need to compile these new files programaticaly so that I could add the generated class in my classLoader.
I do not find any way to compile programaticaly sources from a given sbt project path (and eventually from a classLoader) in the sbt API, something as simple as the sbt command (sbt compile) line would be very convenient, something like:
XXX.compile(path/to/sbt/project)
Thanks
I suggest you have a look at sbt-boilerplate which is an sbt plugin that generates code, works well and is really simple.
Here's a link to the file that you probably want to take a look at

I can't use sbt.Process inside /src?

I'm currently using sbt to build and run my scala programs. I'm trying to use sbt.Process to execute system commands. I must be missing something because when I try to import sbt.Process in one of my files in src/ I get this error.
not found: value sbt
[error] import sbt.Process._
So it looks like I can't access the sbt package inside my src/ files. What do I need to do to access it? Thanks.
SBT's environment (v 0.7.x) is only available in your build file or a Plugin.
The easiest way to use sbt.Process library (until 0.9.x which will have Process as an independent library) is to copy (BSD License) Process.scala and ProcessImpl.scala into your project
There are different classpaths for running sbt and compiling your source files.
One classpath is for compilation of files in directory project/build (that one contains sbt jars and usually scala library 2.7.7) and the other one is for building source files of your project (that one contains your dependencies from lib and lib_managed and usually scala library 2.8.*). If you'd like to use sbt.Process in your source files you can do two things:
add sbt jar to lib or lib_managed for it to be available on your project's classpath
use snapshot version of scala 2.9, it would have sbt Process built-in as sys.process package
Wait for Scala 2.9, and then just use it out of scala.sys.process.
sbt package has became an integral part of the Scala standard library since version 2.9
...this API has been included in the Scala standard library for version 2.9.
quoted from sbt wiki
Here's the link (scroll down)
well, in order to use it, all you have to do (assuming you are using sbt for build), is to add in build.sbt file the following line of code: sbtPlugin := true it will add the needed dependencies to your project.
of course, this solution is only to get your imports with sbt package to work. you should refactor your code to use the new package scala.sys.process like Daniel C. Sobral suggested.