haskell-overridez is a tool and library of nix functions that simplify the use of overrides while developing haskell projects with nixpkgs.
haskell-overridez is inspired by the section on Advanced Dependency Management in haskell-nix. The idea is to turn the recommendations there into a tool that is itself installed into the nix environment.
It's assumed that you have already installed nix.
You can then install haskell-overridez
using nix-env
:
nix-env --install -f https://github.com/adetokunbo/haskell-overridez/archive/v0.10.3.1.tar.gz
Installation adds the executable haskell-overridez
to the nix environment.
It writes the output of the other tools it uses to subdirectories of the development project.
E.g,
$ cd my-nix-project
# install an override using github json
$ haskell-overridez -g reflex-frp/reflex-dom-contrib
# install an override using cabal2nix
$ haskell-overridez https://github.com/tathougies/beam -- --subpath beam-core
There are various options for managing the overrides; to see them all, you can read the help message:
$ haskell-overridez -h
haskell-overridez - manage nix overrides for haskell packages
...
Given the previous example commands, haskell-overridez
creates a project with the following layout:
├── default.nix
│
├── nix (1)
│ │
│ ├── haskell-overridez.nix (2)
│ │
│ ├── nix-expr (3)
│ │ └── beam-core.nix
│ │
│ ├── git-json (3)
│ │ └── reflex-dom-contrib.json
- There is a
nix
subdirectory of the main project directory. - There is a
haskell-overridez.nix
file that contains the nix expression used to load the accompanying nix expression library. - There are subdirectories (
nix-expr
,git-json
) that contain the output from the tools. - The accompanying library functions use the contents of the subdirectories to generate a nix expression that combines all the overrides into a single nix overlay.
The library functions can be used from default.nix
by setting the overlays
attribute.
let
overridez = import ./nix/haskell-overridez.nix;
overlays = [
(newPkgs: oldPkgs: {
haskellPackages = oldPkgs.haskellPackages.override {
overrides = overridez.allIn ./nix;
};
})
];
pkgs = import <nixpkgs> { inherit overlays; };
in
{}
or by setting the packageOverrides
attribute of the config element.
let
overridez = import ./nix/haskell-overridez.nix;
config = {
packageOverrides = pkgs: {
haskellPackages = pkgs.haskellPackages.override {
overrides = overridez.allIn ./nix;
};
};
};
pkgs = import <nixpkgs> { inherit config; };
in
{}
Some overrides can't be specified using the features of haskell-overridez
and need to be specified directly. These direct overrides can be combined with the configured ones using combineAllIn
instead of allIn
:
let
overridez = import ./nix/haskell-overridez.nix;
myManualOverride = self: super: {};
myImportedOverrides = import /from/some/nix/file.nix;
overlays = [
(newPkgs: oldPkgs: {
haskellPackages = oldPkgs.haskellPackages.override {
overrides = overridez.combineAllIn ./nix [myManualOverride myImportedOverrides];
};
})
];
pkgs = import <nixpkgs> { inherit overlays; };
in
{}
Projects developed using the Reflex Platform can benefit from adopting the layout in
reflex-project-skeleton. This allows them to share
haskell code between frontend and backend. In these projects, haskell-overridez
can be used as follows:
let pkgs = import <nixpkgs> {};
overridez = import ./nix/haskell-overridez.nix;
in
{}:
(import ../../repos/reflex-platform {}).project ({ pkgs, ... }: {
packages = {
common = ./common;
backend = ./backend;
frontend = ./frontend;
};
shells = {
ghc = ["common" "backend" "frontend"];
ghcjs = ["common" "frontend"];
};
overrides = overridez.allIn ./nix;
})
haskell-overridez
has a fetch
subcommand that makes it easy to share the overrides it manages. As long as the override config files are saved in a git repository, they can be fetched for use in other projects.
haskell-overridez fetch
copies the override configuration from a target git repo to a subdirectory of the current project's nix
directory.
- Use
haskell-overridez
to manage thenix
overrides of a project - Publish the project to an online git repo, ensuring that the
nix
folder is a top-level directory in the repo - Use
haskell-overridez fetch <url-of-repo>
to clone the project's nix configs
To fetch from local private git repos, use a file url to the git directory.
- This example repo can have its configs fetched.
- See the integration test fixtures for examples of remote fetching and local fetching, and for usage of a remote-fetched config and of a local-fetched config.
Contributions are welcome! Please raise an issue to report any problems or open a PR with fixes and improvements.
haskell-overridez
uses PVP. While it does not provide a library, the package provides an executable and nixpkg functions. Its public API is defined as the documentation provided by haskell-overridez -h
and all the nixpkgs functions exported by default.nix
.
Each 'version' tag (e.g, vN.N.N) in the repository is a release. To update managed projects to a new release
- re-install
haskell-overridez
- update the projects to use the releases's nixpkgs functions with
haskell-overridez -i
These are installed using a versioned archive file, so updating is optional. If you don't upgrade, any existing projects will be unaffected.
These were installed with the original installation instructions that used an archive of the master branch. Unfortunately, after each new release, the hash of the master branch changes, meaning that the hash specified in /nix/haskell-overridez.nix
of these projects becomes incorrect, and derivations using the overrides will start to fail to load. In these cases, you must update haskell-overridez
and the affected projects.
- Ask people to try it out to see if its useful (reddit)
- Iterate on any proposed feature requests (.. ongoing)
- (??) Merge it into nixpkgs (later, if people think that's a good idea)
BSD-3 clause