Skip to content

deepfire/nix-head

Repository files navigation

What?

A workbench intended for working with broken packages (which happens with ghcHEAD), that provides:

  1. Nixpkgs (or just nix-shell) with ghcHEAD (or any other compiler of choice) with:
  2. https://github.com/hvr/head.hackage patches applied
  3. Custom package pins & other overrides
  4. Nixpkgs pinning

In essence, it gives you Nixpkgs for a composition of head.hackage’s patches and local overrides (both declarative and FS-stateful), for a given compiler, all in scope of given Nixpkgs:

nix-head :: HeadHackage -> OverSpecs FS -> OverSpecs Decl -> GHCVer -> Either Nixpkgs NixpkgsCommit -> Nixpkgs

..where:

OverSpecs Decl
Declarative override specification in extra-overrides.nix, that’s slightly more convenient than the default syntax. Only covers common override cases, but easily extended.
OverSpecs FS
Same as above, but specified by separate files in the ./pins folder, which is essentially treated as a stateful DB. pin-package.sh is used to set per-repo src overrides (aka pins).

Quick setup (Nix assumed installed)

git clone --recurse-submodules https://github.com/deepfire/nix-head

..or, equivalently:

git clone https://github.com/deepfire/nix-head
./update-head-hackage.sh

..and then:

cd nix-head
nix-shell --no-build-output --cores 0 -j4

..which will give you a shell with ghcHEAD and cabal-install (by default).

The dispatching super-script shows available commands:

./head.sh --help

Quickref

WhatHow
Change Nixpkgs pin./pin-nixpkgs.sh REVISION [GITHUB-USERNAME] ..or.. ./head.sh pin-nixpkgs REV [USER]GITHUB-USERNAME defaults to NixOS
Select a GHCnix-shell --argstr compiler ghc863Defaults to ghcHEAD.
..or edit default-compiler.nix.
Set head.hackage commit used./pin-head-hackage COMMIT-ID [GITHUB-USERNAME]
Set a package pin./pin-package.sh GITHUB-USERNAME HASKELL-REPO [COMMIT-ID]COMMIT-ID defaults to repo’s HEAD.
..when HASKELL-REPO is same as HASKELL-ATTR, otherwise also add a line to extra-overrides.nix:
HASKELL-ATTR = { repo = "repo-name"; };
Build single pkg./build.sh aeson ..or.. ./head.sh build aeson
Enter shell for a pkg./shell-for.sh aeson ..or.. ./head.sh shell-for aeson
Print effective overrides and patches./print-overrides [--patches-only] [--overrides-only]
Different packages in the shell=nix-shell –arg pkgs ‘[“aeson” “cabal-install”]’=Defaults to just cabal-install.
..or edit default-packages.nix.
The dispatch umbrella script./head.sh --helphead.sh is intended for aliasing.

Note, that most of the bash scripts (like shell-for.sh) are position-independent, so can be invoked from arbitrary $PWD.

Setting overrides using OverSpecs

Haskell derivation overrides other than just src attribute, can be conveniently specified in a declarative way via extra-overrides.nix:

{ pin ? false        :: Bool            ## Override the repo/commit from pins/${x}-src.json; see ./pin.sh
, just ? null        :: Deriv           ## Use a derivation value directly
, repo ? attr        :: String          ## When repository name != attribute name
, chdir ? null       :: Filepath        ## When package's cabal file is in subdir of repository
, dontRevise ? pin   :: Bool            ## Disable edited cabal file & revision
, patch ? null       :: Maybe PatchSpec ## Argument to fetchpatch
, jailbreak ? false  :: Bool
, doHaddock ? true   :: Bool
, doCheck ? true     :: Bool
, scope ? null       :: Maybe (HaskPkgs -> HaskPkgs -> HaskPkgs)
, headPatch ? true   :: Bool            ## Suppress head.hackage's patch
, headCabal ? true   :: Bool            ## Suppress head.hackage's cabal file
, extAttrs ? {}      :: Map AttrName (Map AttrName Any) ## Extend arbitrary haskell derivation attribute of type attrset
, extLists ? {}      :: Map AttrName [Any]              ## Extend arbitrary haskell derivation attribute of type list
, extStrs  ? {}      :: Map AttrName (String -> String) ## Modify arbitrary haskell derivation attribute of type string
}

Note, that this declarative specification takes precedence over the FS-based specs, so, as an example, if you have a src-json pin in pins, you can disable it in the declarative spec by specifying pin = false.

Mass rebuild workflow

This is a workflow optimised for debugging problems of the requested package set:

  1. Edit overrides (using ./pin-package.sh, and/or extra-overrides.nix edits).
  2. Either ./build.sh the affected packages for individual builds (failure logs saved under ./logs), or:
  3. ./all-failures-raw.sh, which will attempt to build all requested packages, but won’t stop at the first failure – proceeding until nothing else can be built. This is a batch operation that is intended to give you inputs for step #1, so that you can retry efficiently.

    Alternatively, ./all-failures.sh and ./all-failures-dialog.sh will present the list of failed derivation builds in a more palatable manner (stdout and an interactive dialog interface for log viewing, correspondingly).

Leveraging as package set supplier for your program

The Nixpkgs package set provided by this can be leveraged during development of another program, where chasing latest GHC is desired for some obscure reason.

For this:

  1. Fork https://github.com/deepfire/nix-head – since you’ll be adding overrides.
  2. git clone --recurse-submodules https://github.com/${USER}/nix-head in your repository.
  3. Use the provided Nixpkgs package set:
    nixpkgs = import ./nix-head/nixpkgs.nix {};
        

About

More pleasant chasing of `ghcHEAD` with Nix

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published