There are so many different ways of building and maintaining Haskell projects.
I'm going to talk about using nix-shell and stack.
First you want a ~/.stack/config.yaml:
local-bin-path: /home/USERNAME/.stack/bin
templates:
params:
author-name: NAME
author-email: EMAIL
copyright: 'Copyright: (c) 2017 NAME'
github-username: USERNAME
Make sure to replace USERNAME and NAME and EMAIL with your details.
This will make sure that new projects gets these details automatically injected.
Next we create a project folder.
We can call it my-project.
mkdir my-project
touch my-project/shell.nixWe create a shell.nix that looks like:
#!/usr/bin/env nix-shell
{
pkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/8b1cf100cd8badad6e1b6d4650b904b88aa870db.tar.gz) {}
}:
with pkgs;
haskell.lib.buildStackProject {
name = "my-project";
buildInputs = [ ];
shellHook = ''
echo 'Entering Environment'
set -v
alias stack='\stack --nix'
set +v
'';
}This will ensure that stack uses the GHC version provided by shell.nix. It will be forced to select an appropriate Stackage snapshot that is compatible.
Here we can start nix-shell and enter into the environment.
From here perform stack new my-project. This creats a new folder called my-project. Copy over all of its contents into the current directory.
cp -rT my-project/my-project my-project
rm -r my-project/my-projectYou can now:
cd my-project
stack build
stack exec my-project-exe
stack test
stack ghci
stack ghci --testNote that don't use stack install within this environment as it will install executables into your ~/.stack profile. There's no way to install things directly into the project folder from the command line. Instead to add dependencies there are 3 choices.
- If it's a dependency outside of Haskell (like a system library), use the
shell.nix. - If it's a Haskell library that is within the Stackage snapshot selected, use the
package.yaml. - If it's a Haskell library that is outside the Stackage snapshot selected, use the
package.yamlandstack.yaml.
An interesting issue is when it's a Haskell executable that you want to use. If it's required for the compilation of the project or testing, you might want to put it into the package.yaml. But if it's just a one-off executable such as in the case of hakyll-init where the static site generator just creates new project folders, you can just use shell.nix.
Note that project specific build artifacts are stored in .stack-work. This is automatically hidden by the generated .gitignore file by stack new.
If you have an existing Cabal project, you can instead use stack init, which will expect an existing Cabal file.