- Write your own pre-commit tests for any project with a simple EDSL
- Automatic parallelisation
- Output that looks as if everything was run sequentially.
- Only one dependency:
stack
A zift.hs script is a code quality tool.
It can be used to define and enforce code quality standards in a repository.
To run a zift.hs script, execute ./zift.hs run.
This will run the preprocessor, the prechecker and the checker.
If at any point something fails, the entire execution will fail and the exit code will be nonzero.
To start using a zift.hs script automatically, you need to install it as a pre-commit script with zift.hs install.
This ensures that zift.hs run will be run before every git commit, and that you will not be able to commit unless zift.hs run exits successfully.
(There is still a way around this with git commit --no-verify for emergencies.)
You can also run individual parts of the zift.hs script with zift.hs preprocess, zift.hs precheck and zift.hs check.
Zifter is intended to be a composable (and extensible) code quality tool.
You can write your own zift.hs scripts to define the code quality standards that you want to uphold in your project.
A zift.hs has three main sections:
preprocessorprecheckerchecker
In the preprocess section, you define what needs to happen with your code before you start checking anything.
For example, this is where you put code formatters.
In the prechecker section, you define what needs to happen with the repository after the preprocessor check.
For example, after you have reformatted all the source files, you will probably want to run git add ., so that these changes are also in the commit.
In the checker section, you define all the checks that need to succeed in order to allow a commit.
For example, you probably want to ensure that the project builds successfully, that the tests pass, etc...
To find predefined functions that you can put in these sections, have a look at the zifter-* packages.
The following is an example of a zift.hs script for a Haskell project.
The following zift.hs script first runs hindent and cabal format on all relevant files, in parallel.
Then it runs git add ..
Lastly, it runs hlint on the entire project and then it runs stack to ensure that everything compiles without warnings and the tests succeed.
#!/usr/bin/env stack
{- stack
--install-ghc
runghc
--package zifter
--package zifter-cabal
--package zifter-git
--package zifter-hindent
--package zifter-hlint
--package zifter-stack
-}
import Zifter
import Zifter.Cabal
import Zifter.Git
import Zifter.Hindent
import Zifter.Hlint
import Zifter.Stack
main :: IO ()
main =
ziftWith $ do
preprocessor $ ziftP [hindentZift, cabalFormatZift]
prechecker gitAddAllZift
checker $ do
hlintZift
stackBuildZift
The functions in the preprocess, precheck and checker sections are of type Zift ().
All the relevant documentation is in the Zifter module.
It is important to note that Zift has a MonadIO instance, so that you can embed any IO action in a Zift action.
The most important parts here are the following:
- Make sure you get
stack:
addons:
apt:
packages:
- libgmp-dev
before_install:
- mkdir -p ~/.local/bin
- export PATH=$HOME/.local/bin:$PATH
- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
- chmod a+x ~/.local/bin/stack
Install all dependencies with stack:
install:
- stack setup
- stack build --only-snapshot
Run the zift.hs script on travis.
script:
- ./zift.hs run
The .travis.yml file in this repository can serve as an example.
The name 'Zifter' comes from the dutch word 'muggenzifter', which means 'nitpicker'.