We’re happy to announce the first release of stackage-cli (Command Line Interface). This project got started by a request in a somewhat unlikely place: a MinGHC issue. We started on this as a way to automate some of the instructions available on stackage.org, but quickly realized there was a lot more potential to make lives of developers even better.
To get started, just run cabal update && cabal install
stackage-cli
. You can see more information on
the Github README. In the rest of this blog post, we’ll cover
some of the motivation for the tool, and directions to see it head
in the future.
Stackage’s primary mechanism for setup is to give cabal-install
a set of constraints of which package versions to install, via a
cabal.config file in your project. Typically, setting up Stackage
is a matter of running wget
https://www.stackage.org/lts/cabal.config
. However, there
are a few minor annoyances around this:
wget
available (this
was the main point of the original MinGHC issue).With stackage-cli, you just run stackage init
to
get a cabal.config file. stackage purge
deletes that
file and wipes your package database. And stackage
upgrade
does both.
The above is nice, but not especially noteworthy. The sandbox feature is where the tool really begins to shine. As many of you know, cabal sandboxes are highly touted for minimizing “cabal hell” problems, by isolating interactions between different projects. However, there are two downsides of sandboxes:
stackage-cli fixes both of those by introducing automated shared sandboxes. The idea is this: when you use a single LTS Haskell version, you’re hardcoding your dependency tree. Therefore, multiple projects using the same LTS version can share the same sandbox. To demonstrate this, let me proceed by making fun of Yesod a bit with a shell session:
$ yesod init
# Answer some questions, get a bunch of output
$ cd project1
$ stackage sandbox init
Writing a default package environment file to
/home/vagrant/Desktop/project1/cabal.sandbox.config
Creating a new sandbox at /home/vagrant/.stackage/sandboxes/ghc-7.8.4/lts-2.3
$ cabal install --run-tests
# Let's get some coffee
# OK, lunch time
# Fine, I'll actually go work out today
# Still not done???
# OK, done
$ cd ..
$ yesod init
# Start project 2
$ cd project2
$ stackage sandbox init
Initializing at snapshot: lts-2.3
Writing a default package environment file to
/home/vagrant/Desktop/project2/cabal.sandbox.config
Using an existing sandbox located at
/home/vagrant/.stackage/sandboxes/ghc-7.8.4/lts-2.3
$ cabal install --run-tests
# Wait, it's already configuring
# Oh, it's done. Crap, no coffee
The point of this little demonstration is: you compile your package set once. You then get to reuse it across multiple projects. Yes, the first installation takes just as long and just as much disk space. But subsequent uses will be immediate.
By the way, please pay attention to the caveats.
We use LTS Haskell at FP Complete and on client projects, and it
has eliminated problems of incompatible package versions. Our
recommendation is to check in the cabal.config file to your repo,
or equivalently make sure that everyone on your team starts
development by running the same init command, e.g. stackage
sandbox init lts-1.15
.
We’d typically recommend to start off with sandboxes, and only
leave them if you have a good reason. Given that, you may be
wondering why we have two versions of the command. One answer is
that there are multiple sandboxing technologies already out there.
For example, hsenv
still provides some functionality
that people prefer to cabal sandboxes. Another answer is that there
are other sandboxing approaches that have yet to be fully explored,
such as Docker containers, which may provide significant
advantages. We don’t want to tie the tool down to one
implementation.
One final point. If you pay close attention, you may notice that
stackage-cli provides a few different executables. We’ve decided to
emulate the Git approach to the command line tool: we have a
wrapper executable called stackage
(and a shorter
abbreviation stk
) which will call out to any other
tools with the name stackage-*
. stackage-cli ships
with executables called stackage-init
,
stackage-purge
, stackage-upgrade
, and
stackage-sandbox
. These all work as plugins to the
main executable. This provides for a number of nice features:
stackage-cli
can remain light-weightThe only requirements placed on a Stackage plugin are that it must:
--summary
, give a
short description of its functionalityThe Stackage.CLI module provides some helper functions for this.
There are already a few Stackage plugins on Hackage.
cabal
update
. With both stackage-cli
and
stackage-update
installed, you now just run stk
update
We hope others will join in the fun with both the core stackage-cli tool, and by producing their own plugins. If you have ideas, please bring them up on the mailing list, issue trackers, or elsewhere. We also have plans for further open sourcing of our internally built code bases. We’re still fixing up some details, but the tools we’ve developed have been in production use by our customers for a while now, and we’re excited to get them into the community’s hands. We’re also looking at providing tools to provide greater package download security, and to automate the process of getting a Haskell development environment up and running. Stay tuned.
Subscribe to our blog via email
Email subscriptions come from our Atom feed and are handled by Blogtrottr. You will only receive notifications of blog posts, and can unsubscribe any time.