Skip to content

This repo is a tool to quickly cook a buildable and deployable haskell project or nixify an existing Haskell project.

Notifications You must be signed in to change notification settings

hughjfchen/quick-cook-or-nixify-haskell-project

Repository files navigation

Readme

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.

Why you would like this?

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.

Features

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 and macos are supported, windows with WSL 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 and haskell.nix) update
    • very easy to add new project template with new build infrastructure
  • 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 as docker-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 on haskell.nix version so that the build is reproduceable and reduce build time by downloading cache from haskell.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 as docker 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

Usage

Following these steps to use this tool:

  1. clone the repository.
  2. 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
        
  3. 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
        
  4. follow the prompt of the screen til everything is done. usually, you just press enter

How does it work

Dependencies provision

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.

Generate haskell project (deprecated, not recommended)

This tool uses the summoner to do this job, for more information during the project generation, please refer to the official site.

Generate the build framework based on the haskell.nix infrastructure

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 the niv tool
  • It uses the nixpkgs source from the haskell.nix within the default.nix file and set the nixpkgs 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 the default.nix to the one of the haskell.nix internal index state
  • It generate a shell.nix file with following features:
    • With the hoogle tool enabled
    • With cabal, hasktages and haskell-language-server enabled and set their versions to the default one of the latest stable nix channel
    • You can optionally enable other tools, like ghcid, niv or lorri, just check the shell.nix file
  • It generate the cross-build.nix file which will build the fully static binary linked with musl library by default. If you would like to cross build for other platforms, check the nix/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 a nix file for this package under the directory nix/overlay and it will be picked up automatically.

Generate the deploy framework based on the docker, docker-compose and arion-compose

This tool generates the ready to go deploy framework with follow facts:

  • With arion-pkgs.nix, it imports the package set from the default.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.

Setup development environment

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 with haskell-mode and lsp 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 the index-state set to the one of the haskell.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 the HLS 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.

Build

To build your project, just run build within your project directory.

Deploy

To deploy your project and run it, just type deploy command within the project directory.

Nixify existing projects

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.

How to really write code

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.

Todos

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

About

This repo is a tool to quickly cook a buildable and deployable haskell project or nixify an existing Haskell project.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published