From b010b42027a508549c7948d11c20d49cf3dd323e Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Fri, 26 Jan 2018 12:21:31 +0000 Subject: [PATCH 1/5] Add nix haskell tooling idea --- content/ideas/cabal-nix-workflow.md | 71 +++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 content/ideas/cabal-nix-workflow.md diff --git a/content/ideas/cabal-nix-workflow.md b/content/ideas/cabal-nix-workflow.md new file mode 100644 index 0000000..a75c685 --- /dev/null +++ b/content/ideas/cabal-nix-workflow.md @@ -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 environement (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 appropiate 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 appropiately 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 From 9207245da49a0bce5ebabdafbefd4eb6ba515434 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Fri, 26 Jan 2018 12:28:16 +0000 Subject: [PATCH 2/5] Spelling --- content/ideas/cabal-nix-workflow.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ideas/cabal-nix-workflow.md b/content/ideas/cabal-nix-workflow.md index a75c685..61bf415 100644 --- a/content/ideas/cabal-nix-workflow.md +++ b/content/ideas/cabal-nix-workflow.md @@ -32,7 +32,7 @@ However, the ideal tool doesn't yet exist. We want a tool with the following phi 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 environement (by a cabal file +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. @@ -41,7 +41,7 @@ As an exemplification of this, using workflow (3), by default invoking `cabal2ni 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 appropiate build dependencies for building whichever component +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`. @@ -55,7 +55,7 @@ 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 appropiately generated package set) and so on. +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 From 9463f18c30cf67209bc69f49ce51504c2329df17 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Mon, 29 Jan 2018 11:10:11 +0000 Subject: [PATCH 3/5] Add additional link --- content/ideas/cabal-nix-workflow.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/ideas/cabal-nix-workflow.md b/content/ideas/cabal-nix-workflow.md index 61bf415..db64241 100644 --- a/content/ideas/cabal-nix-workflow.md +++ b/content/ideas/cabal-nix-workflow.md @@ -64,8 +64,9 @@ such as specifying a `lts` version (with an appropriately generated package set) 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://github.com/Gabriel439/haskell-nix/ https://docs.haskellstack.org/en/stable/nix_integration/ https://www.haskell.org/cabal/users-guide/nix-integration.html +https://github.com/jyp/styx **Difficulty**: Intermediate From 7e580c936ac349c5f9f1ada7837aca0e7b23263b Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Tue, 30 Jan 2018 10:12:27 +0000 Subject: [PATCH 4/5] Typo and links --- content/ideas/cabal-nix-workflow.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/ideas/cabal-nix-workflow.md b/content/ideas/cabal-nix-workflow.md index db64241..6814eee 100644 --- a/content/ideas/cabal-nix-workflow.md +++ b/content/ideas/cabal-nix-workflow.md @@ -42,7 +42,7 @@ will generate a nix expression which loads both the build and test dependencies 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 +it wants to build and no more. Similarly, "cabal test" should 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`. @@ -68,5 +68,6 @@ https://github.com/Gabriel439/haskell-nix/ https://docs.haskellstack.org/en/stable/nix_integration/ https://www.haskell.org/cabal/users-guide/nix-integration.html https://github.com/jyp/styx +https://nixos.org/nix-dev/2016-September/021765.html **Difficulty**: Intermediate From 034bd1b9759e17d2d57ccdf8d0e9bf1c5663ed13 Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Tue, 30 Jan 2018 10:17:37 +0000 Subject: [PATCH 5/5] Link into the pull request --- content/ideas/cabal-nix-workflow.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/ideas/cabal-nix-workflow.md b/content/ideas/cabal-nix-workflow.md index 6814eee..a5cd8c4 100644 --- a/content/ideas/cabal-nix-workflow.md +++ b/content/ideas/cabal-nix-workflow.md @@ -61,9 +61,12 @@ such as specifying a `lts` version (with an appropriately generated package set) 8.0.2 package set rather than rely on the user to have already installed the compiler locally. +* [Extending `cabal2nix` to work with `cabal.project` files.](https://github.com/haskell-org/summer-of-haskell/pull/45#issuecomment-361255425) + 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/haskell-org/summer-of-haskell/pull/45 https://github.com/Gabriel439/haskell-nix/ https://docs.haskellstack.org/en/stable/nix_integration/ https://www.haskell.org/cabal/users-guide/nix-integration.html