Intro

I must be getting old and eccentric. I have recently started working on the Coursera's Scala Specialization. It's all great, but my first realization was that the tools they use are not going to work for me. The problem lies mainly with sbt - their build tool. It fetches and installs in your system God knows what from God knows where to bootstrap itself. I don't trust this kind of behavior in the slightest. I understand that automatic pulling of dependencies and auto-update may save work, but they are also dangerous. I don't even want to mention that they contribute to general bloat and sluggishness that plagues the Java world. You don't need to know what depends on what, so everything uses everything, without a single thought.

Having said all that, I do trust and use QuickLisp. So, go figure.

I would still like to take the class, but I would like to do it using Emacs and command line. Here's what I did.

Prerequisites

You'll need the following packages:

==> sudo apt-get install default-jdk scala ant junit4 scala-mode-el

The assignments they give seem to have a stub for implementation and a bunch of scalatest test suites. I will also want to write some other code to play with things. This is the directory structure I used:

==> find -type f
./01-hello-world/build.xml
./01-hello-world/src/HelloWorld.scala
./02-square-root-newton/build.xml
./02-square-root-newton/src/SquareRoot.scala
./a00-lists/build.xml
./a00-lists/src/example/Lists.scala
./a00-lists/test/example/ListsSuite.scala
./a01-pascal-balance-countchange/build.xml
./a01-pascal-balance-countchange/src/recfun/Main.scala
./a01-pascal-balance-countchange/test/recfun/BalanceSuite.scala
./a01-pascal-balance-countchange/test/recfun/CountChangeSuite.scala
./a01-pascal-balance-countchange/test/recfun/PascalSuite.scala
./build.properties
./build-targets.xml
./lib/get-libs.sh

You can get all this here and will need to run the get-libs.sh script to fetch the two scalatest jar files before you can do anything else.

Ant

I wrote an ant build template that sets up scalac and scalatest tasks and provides compile and test targets. All that the build.xml files in the subdirectories need to do is define some properties and import the template:

1<project default="compile">
2  <property name="jar.name" value="recfun.jar" />
3  <property name="jar.class" value="recfun.Main" />
4  <property name="tests-wildcard" value="recfun" />
5  <import file="../build-targets.xml" />
6</project>
  • jar.name is the name of the resulting jar file
  • jar.class is the default class that should run
  • test-wildcard is the name of the package containing the test suites (they are discovered automatically)

You can then run the thing (some output has been omitted for clarity):

]==> ant compile
init:
    [mkdir] Created dir: ./build/classes
    [mkdir] Created dir: ./build-test

compile:
   [scalac] Compiling 1 source file to ./build/classes
      [jar] Building jar: ./build/recfun.jar

]==> ant test
compile-test:
   [scalac] Compiling 3 source files to ./build-test

test:
[scalatest] Discovery starting.
[scalatest] Discovery completed in 127 milliseconds.
[scalatest] Run starting. Expected test count is: 11
[scalatest] BalanceSuite:
[scalatest] - balance: '(if (zero? x) max (/ 1 x))' is balanced
[scalatest] - balance: 'I told him ...' is balanced
[scalatest] - balance: ':-)' is unbalanced
[scalatest] - balance: counting is not enough
[scalatest] PascalSuite:
[scalatest] - pascal: col=0,row=2
[scalatest] - pascal: col=1,row=2
[scalatest] - pascal: col=1,row=3
[scalatest] CountChangeSuite:
[scalatest] - countChange: example given in instructions
[scalatest] - countChange: sorted CHF
[scalatest] - countChange: no pennies
[scalatest] - countChange: unsorted CHF
[scalatest] Run completed in 246 milliseconds.
[scalatest] Total number of tests run: 11
[scalatest] Suites: completed 4, aborted 0
[scalatest] Tests: succeeded 11, failed 0, canceled 0, ignored 0, pending 0
[scalatest] All tests passed.

Submiting the assignments

I could probably write some code to do the assignment submission in python or using ant, but I am too lazy for that. I will use the container handling script that I wrote for another occasion and install sbt in there. The docker/devel sub dir contains a Dockerfile for an image that has sbt installed in it.

==> git clone https://github.com/ljanyst/jail.git
==> cd jail/docker/devel
==> docker build -t jail:v01-dev .

This is the configurations script:

CONT_HOSTNAME=jail-scala
CONT_HOME=$HOME/Contained/jail-scala/home
CONT_NAME=jail:v01-dev
CONT_RESOLUTION=1680x1050
If you like this kind of content, you can subscribe to my newsletter, follow me on Twitter, or subscribe to my RSS channel.