-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Project Idea: Better haskell-specific tooling for working with nix #45
Closed
Closed
Changes from 2 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
--- | ||
title: Haskell specific tooling for working with nix projects | ||
--- | ||
|
||
Nix is becoming more and more widely used as a way to manage package dependencies. | ||
This is despite the approach being quite low level and difficult to use. There | ||
are very few layers of abstraction which isolate less experienced uses from the | ||
internal workings of the nix machine. | ||
|
||
There are currently three main modes for working with nix which each have benefits and tradeoffs. | ||
|
||
1. Using `stack` with nix (somewhat common) | ||
2. Using `cabal` with the nix option (very uncommon) | ||
3. Using nix directly (the most common) | ||
|
||
To take each option in turn. | ||
|
||
(1) only uses nix to manage non-haskell dependencies. This is clearly not ideal | ||
as we can't make use of the binary caching or anything else which is great about nix. | ||
|
||
(2) is quite simple minded currently and relies on the presence of an | ||
already generated `shell.nix` file. When the option is set several commands are run in this shell | ||
instead of using cabal's normal dependency management. | ||
|
||
(3) The most flexible option is to invoke `cabal2nix` yourself and then manipulate the | ||
environment using `nix-shell` but there are several redundancies in this approach | ||
such as having to regenerate the `shell.nix` file every time your cabal file changes. | ||
It is also quite low level and requires in-depth knowledge about how nix works. We | ||
want to abstract away from this. | ||
|
||
However, the ideal tool doesn't yet exist. We want a tool with the following philosophy: | ||
Nix, you are responsible for provisioning the correct environment but I will take | ||
care of the all important build. | ||
|
||
The user provides a declarative specification of their necessary environment (by a cabal file | ||
or some other means), then when a user runs a command, nix provisions this | ||
environment and then the tool runs the haskell specific commands necessary to | ||
build the package locally. | ||
|
||
As an exemplification of this, using workflow (3), by default invoking `cabal2nix --shell` | ||
will generate a nix expression which loads both the build and test dependencies into the | ||
environment. It is not usual for the test dependency tree to quite a bit larger than the | ||
build dependency tree. Ideally, when a user runs "cabal build", cabal should enter | ||
a nix shell with the appropriate build dependencies for building whichever component | ||
it wants to build and no more. Similarly, "cabal test" should load enter an | ||
environment with test dependencies. It is currently possible to achieve this | ||
for benchmarking dependencies by the somewhat archaic `nix-shell --argstr doBenchmark true`. | ||
|
||
|
||
Some more possible angles to explore are: | ||
|
||
* In a `cabal.project` file we can specify additional local dependencies. | ||
In `--nix` mode, these should turn into overrides of the local package set and `nix` should | ||
build them. | ||
|
||
* There should be an easy way to "pin" a nixpkgs version so that builds are reproducible. | ||
This could take the form of specifying a hash directly of a nixpkgs commit or more indirectly | ||
such as specifying a `lts` version (with an appropriately generated package set) and so on. | ||
|
||
* `cabal build --nix -w ghc-8.0.2` should modify the environment to provision the | ||
8.0.2 package set rather than rely on the user to have already installed the | ||
compiler locally. | ||
|
||
There are many more angles to explore. A successful proposal will flesh out in | ||
detail what would be necessary to implement one or perhaps two of these ideas. | ||
|
||
https://github.com/Gabriel439/haskell-nix/issues | ||
https://docs.haskellstack.org/en/stable/nix_integration/ | ||
https://www.haskell.org/cabal/users-guide/nix-integration.html | ||
|
||
**Difficulty**: Intermediate |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"should load enter an" doesn't look quite right.