This is a tool which can help you quickly generate a haskell project based on best practice to structure your program and with the nix and haskell.nix as the build framework and docker, docker-compose, arion-compose] and my own deploy-packer as the deployment framework.
We want to write code as quickly as possible when we build an application. However, the reality is that we need to build the application and deploy it for testing. Without the build and deploy, we can’t test it(even for unit testing). And without testing, we don’t know if our application works as expected. So we need to put a lot of effort to make our application build and deploy for testing. Fortunately, we can reduce the effort by generating the build and deploy infrastructure for our application. Furthermore, our application need to follow some best practice to structure our source code for maintenance. And this can also achieve by generating project based on a template.
Also, you may want to nixify an existing haskell project, i.e., build the existing haskell project based on the nix
infrastructure because you want to be
able to reproduceablely build the project for a long time so that you can focus on development.
Based on the above consideration, I create this project generator to quickly cook a project if I want to build a haskell application.
This tool has following features at this moment:
- install build and deploy dependencies, including
nix
,docker
,docker-compose
if needed - multiple platforms supported(currently
linux
andmacos
are supported,windows
withWSL
may work but not tested) - generate project based on the tool
summon
(deprecated, will be removed eventually) - create project based on existing project templates with rob
- currently there are one existing templates
nixos2111-ghc8107-haskell.nix
full-system-nixos2111-ghc8107
- new template will be added following the tools(
nix
andhaskell.nix
) update - very easy to add new project template with new build infrastructure
- currently there are one existing templates
- generate most usable nix files for build and deploy, including:
- default.nix
- this is the major nix file which is used by all other nix files.
- shell.nix
- to setup a development environment with nix-shell
- cross-build.nix
- this nix expression can be used to build cross platform targets, including fully static binary linked with musl library
- docker.nix
- this file can be used to build a docker image for the project
- tarball.nix
- this file can be used to tar up the executable and its dependencies as a tarball for the project
- release.nix
- this file can be used to pack up the executable, its configuration and its dependencies as a self-extractable tarball for the project and ship to the deployment target machine directly. This uses my own deploy-packer
- arioin-pkgs.nix
- this file can be used to define the package set for
arion-compose
to build the container - arion-compose.nix
- this file can be used to compose services by
arion-compose
and orchestrate these services asdocker-compose
- build
- use this script to build the project
- deploy
- use this script to deploy the project
- develop
- use this script to start development of the project
- arion
- the utility to check the deployment status
- pin
nix
package based onhaskell.nix
version so that the build is reproduceable and reduce build time by downloading cache fromhaskell.nix
- ready to be built project, just type
build
and you can get the project executable - ready to be deployed project, just type
deploy
and your project will be deployed asdocker
container - source code stub following the three layer cake pattern practice
- ready to run Github Action CI support
- nixify existing projects, i.e., make existing projects build and deploy using this build and deploy framework
Following these steps to use this tool:
- clone the repository.
- to generate a project skeleton from scratch, run the following command under the clone directory:
./cook.sh <the directory where the project will be put> <the name of the project> <generate|template> - generate means generate new project with summon(deprecated, not recommended) - template means create project based on existing template
- to nixify an existing project, run the following command under the clone directory:
./nixify.sh <the parent directory of the existing project> <the name of the existing project> <template> - template means nixify the existing project based on template
- follow the prompt of the screen til everything is done. usually, you just press enter
This tool provides scripts to provision dependencies. When you try to run build
and get nix command not found
error, you could run following command to provision nix
dependency:
./ci/prepare-env/do.sh (assume you're within your project directory)
And if run deploy
and get docker or docker-compose not found
, run following to install docker
and docker-compose
:
./cd/prepare-env/do.sh (assume you're within your project directory)
The provision process connect to the official nix
web site and install nix
first, it also set the default nix
channel to the latest stable one. It also install the docker
and docker-compose
packages.
This tool uses the summoner
to do this job, for more information during the project generation, please refer to the official site.
This tool generates the ready to go build framework for the generated project with following facts:
- It pinned the
haskell.nix
version to the current date with theniv
tool - It uses the
nixpkgs
source from thehaskell.nix
within thedefault.nix
file and set thenixpkgs
version to the latest stable nix channel - It sets the
ghc
version to the default one from the latest stable nix channel - It sets the
index-state
for the project within thedefault.nix
to the one of thehaskell.nix
internal index state - It generate a
shell.nix
file with following features:- With the
hoogle
tool enabled - With
cabal
,hasktages
andhaskell-language-server
enabled and set their versions to the default one of the latest stablenix
channel - You can optionally enable other tools, like
ghcid
,niv
orlorri
, just check theshell.nix
file
- With the
- It generate the
cross-build.nix
file which will build the fully static binary linked withmusl
library by default. If you would like to cross build for other platforms, check thenix/cross-build/systems.nix
and comment out for which platforms you want - It also generates a
docker.nix
file which can be used to build a docker image - It also generates a
tarball.nix
file which can be used to build a tarball file - It also comes with overlay support. If you want to override some packages within the
hackage
database, you can add anix
file for this package under the directorynix/overlay
and it will be picked up automatically.
This tool generates the ready to go deploy framework with follow facts:
- With
arion-pkgs.nix
, it imports the package set from thedefault.nix
generated by the build framework so make consistent with the build - It uses the
arion-compose.nix
to compose your project executable and other nix packages or docker images from dockerhub and ready to deploy
So if you want other packages or docker images as the runtime dependencies of your project executable, just add them into the arion-compose.nix
.
Besides the shell.nix
, this tool also generates some other files to help you quick start the development:
- The tool assumes you will use
emacs
withhaskell-mode
andlsp
combination as the development environment. If you use other tools, you need to figure out how to setup the development environment yourself. - The tool will generate a
cabal.project
file with theindex-state
set to the one of thehaskell.nix
internal index state. - The tool will generate a
cabal.project.local
to make sure the haskell tools will use the new style cabal commands. - The tool will also generate a
.dir-locals.el
and set theHLS
executable path.
With above files in place, you can just run the develop
under the project directory to enter a nix-shell
and start emacs
within the nix-shell
and start to code.
To build your project, just run build
within your project directory.
To deploy your project and run it, just type deploy
command within the project directory.
When nixifying an existing project with the nixify.sh
script, it will override or modify some files, e.g. cabal.project
etc. It will backup the modified files before overriding or modifying.
With the build and deploy framework in place, we can finally focus on writing haskell code. So how should I do that? Well, as said previously, the generated project source tree is followed the practice described the the article Three Layer Haskell Cake, so to really write code, read that article, understand its structure and happy hacking.
Following are the incomplete list of the features I want to implement in near future:
- Add github action CI support based on
haskell.nix
DONE - Add more project templates