How to compile just some files with sbt? - scala

I've come pretty well along with sbt, the Scala Build Tool. If you only have small problems in the code, it's easy.
Now, after a major feature add, much of my code is broken and I sbt seems to be confused as to how the dependencies are. I could help it, compiling the fundamental modules first, but it does not seem to let me.
It's help system is... notorious.
> help compile
Compiles sources.
Yeah, well. I guessed that.
What I wanted to hear was: how do I compile only - say - src/module/A.scala.
This might not even be possible (hello again, make, never abandoned you!). At least I cannot find any reference on the Internet to applying sbt compile just to a single file.
I'm using sbt from the command line prompt, not an IDE.
UPDATE:
It was my fault. :/ Had split a source file into multiple, but forgot to copy a package clause to each of the new ones. Oooops.
Will keep this open for a while, since compiling just a single file (i.e. something like sbt compile filename) would imho not be a bad thing.

You could define a Multi-Project Build where the files you want to compile separately are encapsulated in a project. According to the docs, the following is then possible:
At the sbt interactive prompt, type projects to list your projects and project to select a current project. When you run a task like compile, it runs on the current project. So you don't necessarily have to compile the root project, you could compile only a subproject.

I just wanted to mention here that I came across sbt-compile-quick-plugin (https://github.com/etsy/sbt-compile-quick-plugin). It does what it says on the tin, just add addSbtPlugin("com.etsy" % "sbt-compile-quick-plugin" % "1.3.0") to your project/plugins.sbt, then you can just start up sbt and run compileQuick /path/to/your/file
(See https://stackoverflow.com/a/46849619/1358677)

Related

What is Scala's Simple Build Tool (sbt) and why is it used?

I am new in Scala and I have to learn Scala and SBT, I read the sbt tutorial but i am unable to understand the use of sbt, for what purpose its been used.After reading this tutorial
I am still confused can any one will explain it in simple words, also suggest me if there is some tutorial for simple build tool
When you write small programs that consist of only one, or just two or three source files, then it's easy enough to compile those source files by typing scalac MyProgram.scala in the command line.
But when you start working on a bigger project with dozens or maybe even hundreds of source files, then it becomes too tedious to compile all those source files manually. You will then want to use a build tool to manage compiling all those source files.
sbt is such a tool. There are other tools too, some other well-known build tools that come from the Java world are Ant and Maven.
How it works is that you create a project file that describes what your project looks like; when you use sbt, this file will be called build.sbt. That file lists all the source files your project consists of, along with other information about your project. Sbt will read the file and then it knows what to do to compile the complete project.
Besides managing your project, some build tools, including sbt, can automatically manage dependencies for you. This means that if you need to use some libraries written by others, sbt can automatically download the right versions of those libraries and include them in your project for you.

Using sbt with custom Scala builds

I occasionally play with Scala forks and sometimes need to debug these forks on SBT projects. In general, scalaHome works great, but there are a few things that I'd like to find better ways to achieve.
1) Is it possible to have SBT pick up custom scalac class files produced by the ant quick build rather than jar files emitted by the ant pack build? The latter implies 5-10 seconds of additional delay per build, so it'd be great to avoid it.
2) Even in big projects, problems exhibited by scalac usually manifest themselves when compiling single files. Is there a way to tell sbt to neglect its change tracking heuristics and recompile just a single file? What I would particularly like to prevent is recompilation of the whole world when I recompile scalaHome or change scalac flags.
3) Would it be possible to have sbt hot reload scalac classes coming from scalaHome, when scalaHome gets recompiled? Currently I have to shutdown and restart sbt to apply the changes.
1) No, this would make sbt depend on the details of the Scala build. If Scala were built with sbt, you might be able to depend on Scala as a source dependency or at least this could probably be supported without too many changes.
2) No, see https://github.com/sbt/sbt/issues/604
3) sbt 0.13 should check the last modified times of the jars coming from scalaHome and use a new class loader. It is a bug if it does not.

Setting up a Scala project in Eclipse, together with JUnit & Scalatest

I have recently completed the Scala course on Coursera, and since then I have been looking forward to getting my hands dirty with Scala again. I have written code for some years but I neither educated to be nor work as a programmer, so it took me a while to get a good opportunity but now that I have some time to invest and a good project to work on it's time...
Except I can't seem to get things set up properly, which I find really frustrating. I have OpenJDK 1.7.0_25 running on my Linux machine. I have downloaded and installed the Bundle Scala IDE build for Eclipse (just like we used in the course). And I got ScalaTest both as a jar file and the Eclipse plug-in.
I have a simple project (so far) and no matter what I do I can't seem to get my builds and tests in order. First off how exactly am I supposed to set up my project so that my classes and tests are actually run properly? All the assignments we got were projects that had the same structure, so do I have to have:
project
|--src
|--main
|--scala
|--test
|--scala
structure? If so why is it not the default way the project is setup when I create a new project? Do I create these folders manually, as packages or as source folders? The whole thing gets pretty murky..
I should mention that I tried to "Mavenize" the project using the contextual menu in Eclipse, added my ScalaTest dependency. The first thing that happens is that I get compile errors, at every point of dependency in my code. So clearly the library is not visible, in other words Maven does not seem to be doing much of management. I thought the whole point of Maven was to get and maintain dependencies as the project evolves. I concluded that I do not fully understand the way Maven works and thus I eventually gave up on Maven, once again, and went back to doing things manually.
Secondly, I can't seem to run my tests; the Run As... menu item does not include ScalaTest as it's mentioned in the documentation of ScalaTest Eclipse Plug-in. I have double checked that the plugin is installed. If I instead try to run using JUnitRunner then my tests are not recognized as valid tests. I have JUnit and ScalaTest on my build path, so it's got to be something else.
I suppose my overarching question is as follows:
given the Scala IDE build of Eclipse and ScalaTest, just exactly how am I supposed to set up my project (in Eclipse) so that I can just focus on writing my code and testing it, and hopefully not have any other headaches?
I work alone, and this project is not a product I need to deliver to some client. In other words I do not need to adhere to strict professionalism here. Honestly I just want to be able to code, get better acquainted with Scala and hopefully build a small data analysis tool that I will be using from time to time.
Thanks in advance!
Try using the sbt eclipse plugin:
https://github.com/typesafehub/sbteclipse
This is of course assumes that you use sbt as you build tool. If you don't at the moment you can find instructions on installation and usage here: http://www.scala-sbt.org/
Personally I've been using typesafe giter8 template (https://github.com/typesafehub/scala-sbt.g8) to setup my Scala projects, and then I use the sbt plugin mentioned above to generate eclipse project files.
Scala is somewhat Maven-based (sometimes implicitly), that's why you use that structure.
The easiest way I think is to create a simple Sbt/Maven POM and create the Eclipse project configurations (like with sbt eclipse). There you can set the dependencies (like the actual version of JUnit, Scalatest to use), so you can use the ScalaTest plugin easily.
In case of other issues, feel free to ask at the ScalaTest mailing list, Chee Seng and Bill Venners can help you a lot there.
The Scala IDE website has a full documentation on how to run unit testing frameworks with the IDE, have a look ! If you find missing elements, the bug tracker of the scala-IDE project is here.

Using Joda Time in Scala (scalaj-time) with IntelliJ IDEA

EDIT:
Version information, as of 01/27/2013:
Scala 2.10.0
IntelliJ IDEA Leda 123.139 (EAP)
Scala Plugin version 0.7.108 (Nightly Build)
JDK 7u11
Joda Time 2.1
ScalaJ-Time 2.9.1-0.6
I have given up on trying to work with SBT, as I didn't see any progress with it - I'm not sure how to combine IntelliJ and SBT, and after hours of trying, I had ended up where I'd first begun.
My JodaTime library contains the Scalaj-Time jar:
I have tried almost every combination of settings, reaching from Joint compilation (first Scala, then Java and vv), external build, over to lifting my JodaTime library over Scala library in the dependencies (yes, I've even done that), and invalidating caches. All I get is a bunch of errors - no matter if I "Make" the project, "Run" the current file or "Compile" it - that are produced randomly. And, sometimes, it works. Yes, as idiotic as it sounds, the behaviour is that undefined. I'm not sure as to what causes this. I have counted 3 different error messages that appear, I will upload them to pastie.org, otherwise it will take too much space: http://pastie.org/pastes/5887847/text.
What I have not tried: Going back to earlier releases of any of the apps/libraries vide supra, getting deep into SBT (I figured it's not worth it).
What do I expect from this thread? I expect that someone provide a solid solution to this problem which, in the best case, will not include any mention of SBT (optional).
Also, on a side note: Why does Joda-Time ship their library in a broken format? Is there any secret behind this that everyone should know about? What was the problem with including FromString into the release version? (I still think that's the cause of it all)
Regards,
Danyel
ORIGINAL POST: (you can ignore this)
I've got the latest build of IntelliJ (123.139), Scala 2.10.0, and hadn't encountered any problems thus far.
Instead of using Java time library, I was eager to use Joda Time, and seeing that there are a bunch of implicits to use in Scala, I wanted to try that out! I added all the libraries, but implicits wouldn't be recognized. When I tried to compile it via IDEA Popup Menu, following errors appeared:
error while loading DateTime, class file '~\workspace\Libraries\JodaTime\joda-time-2.1.jar(org/joda/time/DateTime.class)' is broken
(class java.lang.RuntimeException/bad constant pool tag 10 at byte 42)
error while loading DateTimeZone, class file '~\workspace\Libraries\JodaTime\joda-time-2.1.jar(org/joda/time/DateTimeZone.class)' is broken
(class java.lang.RuntimeException/bad constant pool tag 7 at byte 44)
error while loading AbstractInstant, class file '~\workspace\Libraries\JodaTime\joda-time-2.1.jar(org/joda/time/base/AbstractInstant.class)' is broken
(class java.lang.RuntimeException/bad constant pool tag 10 at byte 10)
I went to the source of those DateTime and noticed that org.joda.convert.FromString; was imported, but the resource didn't exist! I guessed it was because of that why Scala wouldn't compile. So I googled for what I should do. And everywhere it said "SBT, SBT!!", and I was trying to find out what this SBT was, so I installed it: Version 0.12.2, Manual Installation (I'm using Windows 7) from http://www.scala-sbt.org/. I wanted it to run with my IntelliJ so I went to ~\.sbt\plugins, and created a file build.sbt with the line addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0") and downloaded the zip from https://github.com/mpeltonen/sbt-idea, extracted it, and went to that very folder with CMD, entered sbt and gen-idea within sbt and it did a lot of things and all seemed to work out. So I went to my project that I wanted to run Joda Time with, and first of all, it seemed very hard to include Scala 2.10.0 to SBT. I created a file <PROJECT>\build.sbt and filled it with these lines:
name := "Project"
version := "1.0"
scalaHome := Some(file("C:/Program Files (x86)/scala"))
scalaVersion := "2.10.0"
Then, to include the scalaj-time, I went to <PROJECT>\project\project\ and created build.sbt with the line libraryDependencies += "org.scalaj" %% "scalaj-time" % "0.6".
Lastly, I went to <PROJECT> with CMD, entered "sbt", it (down)loaded a lot of files, and it seemed to work out, then I entered gen-idea, and everything was fine.
I opened IntelliJ and I could open the project easily. When I opened Project Structure, I went to Modules, and there were two Modules: Project and Project-build. I ignored the Project-build one, clicked on the Project module, and there were a lot of Source Folders and Test Folders that were not existent: src/main/scala etc., I removed them all and added my src as Source Folder.
I noticed that Joda-Time was not included in External libraries (btw I use Joda-Time 2.1 and Scalaj-time 0.6), so I had to add them myselves. The joda-time library is a .jar while the scalaj-time is a folder, but that should be no problem, right? I could run a simple println( DateTime.now ) instruction (I don't know if it was possible before; didn't try), but a + 2.months was still not possible. Here is a screenshot so you get the idea:
I think I explained in very detail how I proceeded and I hope that you can find something that I did wrong. I've been working for many hours to resolve this, but in the end, I landed where I was in the beginning...
Thank you for your time!
Regards!
How to import FromString for joda-time?
This worked like a charm (for now, who knows how things will ensue). I am so mad that I didn't think of this in the first place... Grrrrr.
EDIT:
This answer is invalid. See the EDIT in the main post. While this works SOMETIMES, it is still heavily undefined as to WHEN it works. When I create a new project, it varies from working to not-working (not compiling, printing random errors), but in another larger project, it had the same undefined behaviour, except now (for whatever reason) it doesn't work, PERIOD. (On my newly created project it still varies)
ORIGINAL POST:
So, after another 10 minutes of trying and googling, I found a .JAR for Scalaj-time (0.6).
I was like "Well, what harm can it bring?", downloaded it, and included it instead of the folder.
Tadaaa, everything worked... All I needed, too, was only these lines:
object Test extends App {
import org.scala_tools.time.Imports._
println( DateTime.now + 2.months )
}
No SBT, nothing, no other imports whatsoever. You just download scalaj_time from http://mvnrepository.com/artifact/org.scalaj/scalaj-time_2.9.1 (Version 0.6, as of now) and Joda Time (V 2.1), make a library ScalajTime that includes 2+ jars, and add it to your dependencies. All you need is that one import statement and you are ready to go.
Maybe the main problem was that I cannot import SOURCE Files from libraries? Because the source folder I imported seemed to have no impact whatsoever. I don't know how I "ignored" that fact but it seemed stupid to assume.
So, now it works.
Regards.

How to pull dependency using sbt

Disclaimer: I'm scala beginner. All defaults works nice for me, but whenever I want to have custom layout/build I run into a problem.
So, as part of my build I need to pull .war(web app) from project A and .jar(jetty launcher) from project B into some directory of project C(tanuki service wrapper).
Can anybody please provide an an example how to do this in the most effective way.
Not sure if it works with war files, but for making jars locally available you could use sbt's publish-local command. Say you have an sbt project "mylibrary" and another sbt project "mymain". If you locally publish "mylibrary.jar", you can add it as a dependency to "mymain" just like you add any other sbt-managed dependency, i.e., by adding a line such as
libraryDependencies += "foo.bar.com" %% "mylibrary" % "0.1-SNAPSHOT"
to the build.sbt of "mymain".
If that is not possible you might want to write an sbt plugin/command that copies the files into a given directory. I don't have experience with extending sbt, so I can't help with that, but other stackoverflowers surely can :-)
EDIT: (addressing a comment by the OP)
No, I don't have a particular Sbt tutorial. If I need help I turn to the usual suspects, the wiki, the mailing list, Stackoverflow, Sbt's source code. Sbt has an IO package which offers a copyFile method, which, according to this thread, comes in handy. Searching for 'copying files' on the mailing list also yields other results that might help you.