commercialhaskell / commercialhaskell/stack
Nix: avoid code duplication between stack and nixpkgs
- Dominant language
- Haskell
- Stars
- 4.1k
- Forks
- 850
- Avg merge
- 10h 37m
- Merged PRs (30d)
- 4
Description
(( This is sort of a follow up on https://github.com/commercialhaskell/stack/issues/2258 and https://github.com/NixOS/nixpkgs/pull/16250 ))
Right now, stack has two ways to support nix: either
[A]. with a simple package list; or
[B]. with a fully customizable shell.nix (supporting everything nix has to offer in terms
of overriding, package configuration, etc.)
The problem is that two different codepaths are in charge of these, while [B] could perfectly support [A].
[A] uses a nix-expression created by stack in `src/Stack/Nix.hs` and [B] uses a nix
function `haskell.lib.buildStackProject`, from nixpkgs codebase (https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/generic-stack-builder.nix).
Both make all the configuration that stack expects (env vars notably).
When an update is made to [A](e.g. a new environment variable to pass to the inner stack), it has to be ported to [B](this is what caused https://github.com/commercialhaskell/stack/issues/2258) and conversely.
The main idea would be to have both [A] and [B] rely on a function like `haskell.lib.buildStackProject`.
The problem is that [B] relies on the regular process of nixpkgs: commiting to the master and waiting
for the commit to reach `nixpkgs-unstable` channel (which can take days), then future nixpkgs-stable release (which can take months).
For instance, right now `haskell.lib.buildStackProject` doesn't even exist in the latest nixpkgs stable release.
So it means that [A] won't be able to use it as is for a moment, and also that evolution of nix support in Stack won't be easy if we systematically rely on an external function.
The idea would be to take the functionality of `generic-stack-builder.nix` back inside stack's codebase. I see at least 2 ways to do this:
1. Physically move `generic-stack-builder.nix` inside stack codebase, and modify it so that instead of returning a function, it overrides user nixpkgs to add this function. Then, have both stack [A] and the user [B] use this function when creating the derivation for the nix-shell.
2. Embed `generic-stack-builder.nix` content as a string inside `src/Stack/Nix.hs` for the same effect
@peti @mboes Do you have an opinion about that? Another way to achieve the same result?
@mgsloan @borsboom 1. seems cleaner, but I have a question then: how do we package this `generic-stack-builder.nix` file? As a part of the regular stack distribution (which will then be installed to some standard location) or as a file that will be downloaded in `$HOME/.stack` e.g. when doing a `stack setup`?
Contributor guide
Assessment
This issue has not been assessed yet.