field test: conscript, giter8, and sbt-dirty-money

Just wanted to share a few techniques of everyday coding using some of the Scala tools.
Suppose you're developing a tool or a library, and you get a bug report. My first focus, before I start analyzing the cause, is to reproduce the issue using the same data the user is using. Once the issue is reproduced, then you can move on to simplifying the issue into a failing spec or functional test. Once the bug is fixed, you can then use the same setup to confirm the fix using the real data.

command line apps using conscript

The first scenario to consider is a command line app. The reproduction part is not interesting. You should make a separate reproduction directory apart from normal projects, make a subdirectory under it, and just run your app with the data.
Writing a shell script would make calling with arguments easier.

What I am after is shortening the edit-deploy-test cycle using the same setup as the user would see. Enter n8han's conscript. conscript is a small utility that sets up command line apps that uses sbt's dependency management as the backend. So all you do is deploy a jar with a class extending xsbti.AppMain and push a launchconfig to github.

When the user installs the app as cs you/project, all conscript does is to download the launchconfig, and create a shell script that calls sbt-launch.jar with it. So at this point, there your jar doesn't exist on the user's machine. To kickstart the process, conscript calls the shell script with --version argument, and then the rest is done by sbt's launcher. In public launchconfig, you would write the current stable version, but there's a version override feature that could download arbitrary version. This works only if you haven't changed things like the main entry point.

Preparation steps:
1. change your project's version to x.y.z-SNAPSHOT first.
2. install your app foo with version x.y.z-SNAPSHOT:

$ cs you/foo/x.y.z-SNAPSHOT

Edit-deploy-test:
1. > publish-local from sbt.
2. in another tab, $ cs --clean-boot from shell.
3. run $ foo data.txt from shell.

The cool thing is that you can then publish the snapshot jar, and it's available to your user right away.

setting up sbt plugins using giter8

The next scenario is an sbt plugin. Plugins are great, but they are tedious to set up for a throwaway project. Enter n8han's giter8.

Giter8 is a command line tool to generate files and directories from templates published on github.

Once you set up you/foo.g8, you can run:

$ g8 you/foo

and it would grab everything under src/main/g8 and perform some string substitutions if you want.
This could be used to preconfigure an empty sbt project with your plugin preinstalled.

Edit-deploy-test:
1. > publish-local from sbt.
2. in another tab, run $ sbt run from shell.

Again, if you publish the snapshot, the fix would be available right away.

cleaning your Ivy cache with sbt-dirty-money

There's one problem with using publish-local. Your Ivy cache knows where you last of the jar from, and it'll keep using it. This could set up a "works (only) on my machine" situation. Wiping out ~/.ivy2 is not ideal. Enter sbt-dirty-money.

This plugin adds a few commands to wipe out ~/.ivy2 slightly more selectively by doing:

((dir / "cache") ** ("*" + organization + "*") ** ("*" + name + "*")).get

This is not perfect obviously, because it would pick up unfiltered-xyz when used from unfiltered/unfiltered for example.

> show clean-cache-files
> clean-cache

The above cleans the ~/.ivy2/cache using the organization and project name.

> show clean-local-files
> clean-local

The above cleans the ~/.ivy2/local using the organization and the project name.