commercialhaskell / commercialhaskell/stack

Nix: avoid code duplication between stack and nixpkgs

Open
#2,272 0 comments 0 reactions 0 assignees View on GitHub
component: nix type: discuss type: enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.