Skip to content

adetokunbo/haskell-overridez

Repository files navigation

haskell-overridez CircleCI

haskell-overridez is a tool and library of nix functions that simplify the use of overrides while developing haskell projects with nixpkgs.

Inspiration

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.

Installation

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

Basic usage

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
...

Project Layout

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
  1. There is a nix subdirectory of the main project directory.
  2. There is a haskell-overridez.nix file that contains the nix expression used to load the accompanying nix expression library.
  3. There are subdirectories (nix-expr, git-json) that contain the output from the tools.
  4. 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.

Using the library functions

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
  {}

Using the library functions in reflex-project-skeleton projects

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;
})

Fetching shared configs

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.

Sharing public projects

  • Use haskell-overridez to manage the nix 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

Fetch configs from private git clones

To fetch from local private git repos, use a file url to the git directory.

Examples

Contributions

Contributions are welcome! Please raise an issue to report any problems or open a PR with fixes and improvements.

Versioning

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.

Updating after releases

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

Newer projects

These are installed using a versioned archive file, so updating is optional. If you don't upgrade, any existing projects will be unaffected.

Older projects

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.

Road Map

  1. Ask people to try it out to see if its useful (reddit)
  2. Iterate on any proposed feature requests (.. ongoing)
  3. (??) Merge it into nixpkgs (later, if people think that's a good idea)

License

BSD-3 clause