Gradle or SBT
Tags: programming.gradle, programming.sbt, programming.antlr4, programming.scala, programming.eclipse, programming.scalatest
Motivation
Somehow I find the current setup less ideal than it should be.
Here’s the “problem” for-which gradle and sbt are a couple of build systems
which provide the “solution”:
I’ve a bunch of Scala code which depends on Java sources generated from an Antlr 4 grammar.
It would be nice to be able to build these easily from the command line without locking it down to a particular IDE. (Bonus points for being able to generate just the Antlr 4 files themselves).
It would be nice to be able to automatically generate Eclipse project files.
JVM Build Systems
– In terms of these JVM-related build-systems, the story goes something like
this: ant used to be the big guy, but then maven came along which allowed
for automatic dependency resolution. (It would download specified dependencies
for the project).
ant got ivy to help with this.
However, ant and maven are both written in XML; maven has more
conventions such-that while every maven repo looks the same, it’s difficult
to get maven to do anything it doesn’t do already.
gradle comes across as the next ‘agnostic’ solution, (agnostic regarding
which JVM language it’s for), customised with an (e)DSL in Groovy.
sbt, the Scala Build Tool, is surely more for Scala projects even if it
(probably) says it can work with anything.
– These aren’t the only alternatives/options. Indeed, the maven repositories
give convenience-code to download dependencies for more tools than this. But
these two were the ones I looked at.
SBT vs Gradle
For the above setup, both do “okay”.
But as things are for me now, each tool has it’s share of drawbacks for this.
– Both can take a long time to run one command. (Well, the first time they
run, they need to bootstrap themselves / download the project dependencies of
course, etc.; but those are forgiveable/understandable). I mean for just like
$ tool compile
, both take several seconds to “load” before running the
command.
sbt mitigates this by being able to run as a ‘shell’ to execute tasks.
gradle can be run as a
daemon, but is still
somewhat slow compared to sbt for tasks which don’t need to do anything.
(e.g. immediately consecutive compile
commands, sbt takes no time, gradle
takes a couple of seconds).
– I’ll cheat here and say that, so long as I can generate an Eclipse project,
then this isn’t crucial.
In general, it seems that gradle can have more tasks, but really needs to be
customised to get much useful functionality out of it. (e.g. there’s no gradle run SomeMainClass
task. And the closest
thing
doesn’t look great).
Scala & ScalaTest
Both handle Scala compilation well-enough.
The “drawback” here, though, is that if you want to write tests with ScalaTest,
then sbt scores points above gradle; while it may not be
difficult/impossible with gradle (e.g. this
plugin presumably does the job),
it looks like it’s more intuitive with sbt. (ScalaTest SBT
support). Not by
much, though.
Antlr 4 Support
The bigger “ugh” factor about this, for me, seems to be Antlr 4 support.
Both handle this by-way-of plugins.
gradle,
sbt. (That, or extending/customising
the commands as each build tool allows, which would require a detailed
knowledge of the tool, I suppose).
– For the code to add these in, though; sbt is concise, gradle less-so.
Although apparently it can be cleaner in recent
versions. (As far
as I can tell, neither support the whole “just point to a GitHub repository”
technique).
I like the gradle plugin above sbt here because it has an antlr4
task/command where the latter doesn’t. – This may be down to ideological
differences between gradle and sbt, wherein this is on-purpose / by design.
e.g. if you’re regenerating files which other Java / Scala sources depend on,
surely you’d want to re-compile those too. gradle can manage to do this, but
with sbt there’s no choice about it. (EDIT: ah, it seems I was mistaken about
this. antlr4:antlr4Generate
will do the job; it’s not listed under tasks
,
though).
On the other hand, though.. neither are “great” about which version of Antlr
4 is being used. EDIT (28/01): Oops, this isn’t true; I was just unfamiliar
with both tools.
Compare my gists forGradle
and SBT for more/less
the same thing. – One thing I don’t understand at the moment is whether SBT
(with this plugin) can have merely antlr4-runtime
rather than antlr4
as its
runtime dependency, and only use antlr4
for the “build script” part. (i.e.
for generating Antlr4 programs).
Whatsmore, apparently neither do the whole “nicely put the generated Java sources into packages by checking directory structure” thing; cf. gradle plugin issue, sbt plugin issue. – I could be wrong as to whether this is sane behaviour to expect, though.
Conclusion
As with many programs, it seems the only sensible conclusion is “they both
suck”; but it’s hard to tell from the above which sucks less. (The answer:
Eclipse).
I’m leaning towards sbt.