Skip to content

add nix flake for easier contribution for nix users #8753

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

Conversation

ParetoOptimalDev
Copy link

@ParetoOptimalDev ParetoOptimalDev commented Feb 10, 2023


Please include the following checklist in your PR:

Please also shortly describe how you tested your change. Bonus points for added tests!

Tested from root of repo with nix develop -c cabal build cabal.

Context: baby steps to start figuring out the effort involved in implementing the fix for #8434

@Kleidukos
Copy link
Member

Kleidukos commented Feb 10, 2023

I don't have anything against you particularly @ParetoOptimalDev but I do have some remarks:

  1. I don't believe we've discussed the inclusion of a flakes setup, it would have been nice to get some input from the community of maintainers first;
  2. I don't believe we should adopt an experimental feature of a niche build system;
  3. Nix setups are a hell of a burden;
  4. You yourself are a first-time contributor, which means that you're statistically very likely to contribute only once to this repository (that's how open-source works). I don't believe the community of maintainers (≠ contributors) has the resources to take care of this setup when you leave;
  5. Lastly it's fairly ironic because Nix setups are unlikely to bring us near any kind of Pareto optimum. I would even argue that adopting the Nix setup to satisfy some Nix users will definitely decrease the satisfaction of people on whom falls the burden of maintaining it.

It's my firm belief that you should stick around for a while, reviewing PRs and making contributions to tickets, before gifting us a whole build system for which there is very little expertise out there. :)

@ParetoOptimalDev
Copy link
Author

ParetoOptimalDev commented Feb 10, 2023

I don't have anything against you particularly @ParetoOptimalDev

Well that's a good start! 😄

I don't have anything against you either @Kleidukos

but I do have some remarks:

I don't believe we've discussed the inclusion of a flakes setup, it would have been nice to get some input from the community of maintainers first;

Could it just be labeled as experimental? Without this the workflow would be rather inconvenient for me as a Nix user because I'd always have a dirty git worktree as flakes require flake.nix being added or at least staged to the repo.

I don't believe we should adopt an experimental feature of a niche build system;

I don't know if niche is fair for Nix:

2023-02-10_14-41

source to search above

[NixOS/nixpkgs] has 11.4K stars as well and 1084 merged pull requests from the past week per Github pulse.

Nix setups are a hell of a burden;

That's subjective and depends on the type. In this flake I do the simplest possible thing:

I use Nix to provide zlib and bootstrap ghc and Cabal. The entire flake.nix is small enough to just paste here without interruping the flow of my response imo.

{
  description = "A devshell that enables nix users to just run `cabal build cabal` and start contributing to Cabal";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  };

  outputs = inputs@{ flake-parts, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      systems = [ "x86_64-linux" "aarch64-darwin" ];
      perSystem = { config, self', inputs', pkgs, system, ... }: {
        packages.default = pkgs.lib.trace "This flake currently only contains a devshell for use with nix develop";
        devShells.default = pkgs.mkShell {
          buildInputs = [ pkgs.ghc pkgs.cabal-install pkgs.zlib ];
        };
      };
      flake = {};
    };
}

You yourself are a first-time contributor, which means that you're statistically very likely to contribute only once to this repository (that's how open-source works).

Agreed. My opinion though is that any Nix user that sees a flake.nix will be much more likely to contribute.

I recently started monitoring github for new projects that have added a flake.nix file and have been building them locally and toying around with them, which is the first step for me to actually contribute.

I don't believe the community of maintainers (≠ contributors) has the resources to take care of this setup when you leave;

Given the wide versions of ghc/cabal-install cabal is buildable with, I don't think it would break. This would be for the use of Nix users to contribute though, any of whom would be capable of fixing what is one of the more trivial examples of a Nix flake.

Lastly it's fairly ironic because Nix setups are unlikely to bring us near any kind of Pareto optimum.

Really? Maybe our definitions differ? See Pareto Optimality and software development for my complete thoughts. In short though I'm going by this definition:

In brief, Pareto optimal solution is defined as a set of ’non-inferior’ solutions in the objective space defining a boundary beyond which none of the objectives can be improved without sacrificing at least one of the other objectives - https://www.sciencedirect.com/topics/engineering/pareto-optimality

Which I'd argue Nix provides the best set of tradeoffs for, otherwise I wouldn't use it 🤓

I would even argue that adopting the Nix setup to satisfy some Nix users will definitely decrease the satisfaction of people on whom falls the burden of maintaining it.

It could be put in the documentation that no features will be added to the Nix setup.

It's my first belief that you should stick around for a while, reviewing PRs and making contributions to tickets, before gifting us a whole build system for which there is very little expertise out there. :)

Ideally yes, but knowing myself I'm merely trying to increase the probability I'll continue contributing. For me that means I can:

  • decide to work on cabal
  • cd to that directory and run cabal build
  • be anywhere in the world, offline, online, airplane, w/e
  • never worry about a build failure

Perhaps I should "get over that" or not have those requirements... but even if I decided that were the case changing people (especially yourself) is hard.

On the other hand this is arguably an issue of neruodivergent inclusivity but I respect that this itself can sometimes be at odds with not putting undue burden on consistent contributors and maintainers.

Hopefully you can see why from my perspective this is a fairly low-cost contribution given it's the lack of warranty for the Nix setup is spelled out in CONTRIBUTING.md.

I'll reflect more on what you said though and think of alternatives solution that might resolve friction in contributing to cabal for me.

@Kleidukos
Copy link
Member

Kleidukos commented Feb 10, 2023

Regarding the status of this build system, the main question is whether or not we include it in the CI:

  • If we need it to succeed in order to make a merge request, it means that we need to have in-house expertise to fix if there is ever a problem. And it's not unreasonable, after all it is advertised as an experimental feature
  • If we don't require it to succeed, it means that we're leaving the occasional hardcore nix user to deal with it first and then they'll be able to make a Cabal contribution (for which we have more need). So now it has become a barrier unless someone has a way of both staying around and continuously making sure that the build system never breaks because CI will merely be an indicator and not a real support system

Without this the workflow would be rather inconvenient for me as a Nix user because I'd always have a dirty git worktree as flakes require flake.nix being added or at least staged to the repo.

echo "flake.nix" >> .git/info/exclude

should be enough for your cabal contributions. :)

On the other hand this is arguably an issue of neruodivergent(sic) inclusivity

Inclusivity is important and that's why we aim to provide maintained, seamless ways to approach contributions to the project. If we cannot guarantee the quality of a build setup (or worse, that we can guarantee that it's going to be less than optimal), we're raising the barrier to contribution for experts only and that's a grave issue.

And finally:

In brief, Pareto optimal solution is defined as a set of ’non-inferior’ solutions in the objective space defining a boundary beyond which none of the objectives can be improved without sacrificing at least one of the other objectives - sciencedirect.com/topics/engineering/pareto-optimality

Which I'd argue Nix provides the best set of tradeoffs for, otherwise I wouldn't use it 🤓

Unfortunately this is not applicable here because your addition of the experimental Nix Flake is not to increase the reliability of our build system but to increase your own satisfaction as an individual. We have many problems with cabal but environment bootstrapping is not really the most important one. Getting zlib and ghc is trivial and I would say that your intellect is best used in one of our high priority issues. :)

Edit: We may not have the same understanding of Vilfredo Pareto's work, I have studied him in the context of microeconomics.

@ParetoOptimalDev
Copy link
Author

ParetoOptimalDev commented Feb 10, 2023

Regarding the status of this build system, the main question is whether or not we include it in the CI:

It seems the most agreeable change would be to not include it in CI. Even without including it in CI, this still a very meaningful improvement for Nix users.

If we need it to succeed in order to make a merge request, it means that we need to have in-house expertise to fix if there is ever a problem. And it's not unreasonable, after all it is advertised as an experimental feature
If we don't require it to succeed, it means that we're leaving the occasional hardcore nix user to deal with it first and then they'll be able to make a Cabal contribution (for which we have more need). So now it has become a barrier unless someone has a way of both staying around and continuously making sure that the build system never breaks because CI will merely be an indicator and not a real support system

This seems like all or nothing thinking to a fault and feels as if it is aimed at just preventing Nix from spreading.

The current state as I see it now is:

  • ghcup users: Can happily build Cabal with cabal build cabal
  • Nix users: Cannot just build cabal with cabal build cabal

I feel I have more of a claim on representing Nix users here in declaring that:

A flake.nix marked experimental that attempts to give me the same level of accessibility as a ghcup user is better even if it ends up failing or I have to fix it myself.

So at this point this feels more political than practical in other words.

There is a very low bar here for making the UX of a nix user the same as a ghcup user and the argument of "the nix user might encounter breakage on a flake.nix marked as experimental" doesn't seem very convincing.

On the other hand this is arguably an issue of neruodivergent(sic) inclusivity

Inclusivity is important and that's why we aim to provide maintained, seamless ways to approach contributions to the project.

I'm glad to hear in words that inclusivity is important and appreciate the work to provide maintained, seamless ways to contribute. I hope to see this demonstrated in action here as I've seen the importance of inclusivity demonstrated in action in the past by both the Haskell Foundation and Haskell community at large elsewhere.

I must say as a nix user though, this wasn't true for me. I aimed to solve provide that for Nix users in this PR so they too have a seamless way to contribute.

I can point to at least one other example where a notable member of the Haskell community was pushed away from contributing to Cabal because of (at least) perceived anti-Nix sentiment in the Cabal codebase.

I was reassured by later comments in that thread there is no such anti-Nix sentiment, but such strong resistance to what I feel I've proven is a very low-stakes change that only improves the status-quo makes me feel otherwise.

If we cannot guarantee the quality of a build setup (or worse, that we can guarantee that it's going to be less than optimal), we're raising the barrier to contribution for experts only and that's a grave issue.

Which is more experts only from a Nix user perspective?

  • A repo with a familiar flake.nix where you can run the familiar nix develop command
  • A repo where running cabal build cabal returns .... zlib not installed ... that leaves you to wonder how much else might be broken for Nix users

And finally:

In brief, Pareto optimal solution is defined as a set of ’non-inferior’ solutions in the objective space defining a boundary beyond which none of the objectives can be improved without sacrificing at least one of the other objectives - sciencedirect.com/topics/engineering/pareto-optimality

Which I'd argue Nix provides the best set of tradeoffs for, otherwise I wouldn't use it nerd_face

Unfortunately this is not applicable here because your addition of the experimental Nix Flake is not to increase the reliability of our build system but to increase your own satisfaction as an individual.

Sharing my own personal experience wasn't mean to imply this was motivated by my own individual desires. I will be fine whether this is merged or not because I know how to build Cabal from NixOS as a somewhat proficient user.

This will demonstrably improve the reliability of builds for nix users from:

$ cabal build cabal
.... snip ...
zlib not installed
... snip ...

to a successful build:

$ cabal build cabal
.... snip ...
Linking /home/cody/org-roam/data/f0/ac2f93-650a-4c85-be69-02415de3f5ef/cabal/dist-newstyle/build/x86_64-linux/ghc-9.2.4/cabal-install-3.9.0.0/x/cabal/build/cabal/cabal ...

This is expressly primarily motivated to make it easier for novice nix users who may want to build, contribute to, or understand the workings of Cabal using Nix.

We have many problems with cabal but environment bootstrapping is not really the most important one. Getting zlib and ghc is trivial and I would say that your intellect is best used in one of our high priority issues. :)

It's trivial if you know what to do and where to add it.

More importantly, from the UX perspective of a user who's never built Cabal before and uses Nix cabal build cabal just working is likely the difference between playing around with the codebase and possibly contributing and never contributing.

I also noticed in your prior comment you argued:

Nix setups are a hell of a burden;

It likely holds then that you believe a new nix user likely won't know how to bootstrap zlib/ghc/cabal right? Or at least there will be some friction every time they want to go and build Cabal, right?

I would ask you to sympathize with a novice nix Haskell user and allow the inclusion of a flake.nix with no warranty that is marked experimental to give that user a better chance.

Edit: We may not have the same understanding of Vilfredo Pareto's work, I have studied him in the context of microeconomics.

Yes, it can be difficult when you've studied something in one context so deeply to generalize to another one especially if you see many more ways the comparison breaks down or just plain doesn't make sense.

A final note is that having such a high burden for adding a change that doesn't negatively affect current users and improves quality of life for another set of users is likely offputting to potential contributors.

I'm sure many would have closed their PR and disappeared by this point.

That isn't to minimize the real concern of maintenance burden where it objectively applies (if it does), but to express what I believe the feelings are around contributing to Cabal.

@hasufell
Copy link
Member

Do nix users need special handholding from every single project to contribute?

I haven't seen gentoo, arch or ubuntu users contributing their ebuilds/PKGBUILDs etc everywhere just to contribute.

I don't thinks that's sustainable. If you need to write a lot of code and maintain complicated environments just to build a simple Haskell project, I'd argue that's a problem of your distro and those "flakes" should be maintained centrally somewhere else. They are clearly irrelevant to the rest of the users.


That rant out of the way... if you insist, I wouldn't mind such contributions to my own projects, but I'd refuse any maintenance on them and rip them out at the first sign of trouble (e.g. you not responding to bug reports within a week).

nix develop # if you don't have direnv installed
cabal build cabal
```

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add something like "Nix flake is not officially supported and as such may fall out of date. Be prepared to tweak it and please contribute fixes back" to make it less controversial and burdensome.

@angerman
Copy link
Collaborator

angerman commented Feb 11, 2023

I'm with @hasufell on this. Why does this need to live in this repo?

This flake could easily live in some github:<owner>/<repo> and instead of nix develop (inside of the cabal directory) one could do nix develop github:<owner>/<repo>.

All this does is really create a shell with ghc cabal-install zlib. And as @Bodigrim correctly points out this is not an officially supported approach, or one that looks like it would be officially supported soon. As such I'm skeptical of the added value in relation to the added lines of code, potential divergence. Who'd be responsible for updating the nixpkgs pin?

For an example on how the development provisioning can be decoupled from the project, I could point to https://github.com/input-output-hk/devx; provisioning does not need to live in the project, especially not if it's as generic as here.

Again the flake is basically identical to the following invocation:

nix-shell -p ghc -p cabal-install -p zlib

I get the appeal of direnv, but is there a large enough set of people who use this? The change seems to only be beneficial for people who (a) use nix, (b) use nix flakes, (c) use nix + direnv.

@ParetoOptimalDev
Copy link
Author

Do nix users need special handholding from every single project to contribute?

This reads to me the same as "Do docker users need special handholding from every single project to contribute?".

Respectfully, free time comes at a premium and I'm not all too interested in spending much if any of that time debugging build issues.

I haven't seen gentoo, arch or ubuntu users contributing their ebuilds/PKGBUILDs etc everywhere just to contribute.

I don't thinks that's sustainable. If you need to write a lot of code and maintain complicated environments just to build a simple Haskell project, I'd argue that's a problem of your distro and those "flakes" should be maintained centrally somewhere else. They are clearly irrelevant to the rest of the users.

Maybe. I'll reflect on that.

Currently my thoughts are: Ideally, but especially with ecosystems like Haskell I like to have as low-cost of a way as possible to drop down a level to say debug ghc from writing my application code. A vision like this becomes much more viable if each thing in the stack can't be built reproducibly with a flake.nix.

That rant out of the way... if you insist, I wouldn't mind such contributions to my own projects, but I'd refuse any maintenance on them and rip them out at the first sign of trouble (e.g. you not responding to bug reports within a week).

That sounds quite reasonable to me.

@ParetoOptimalDev
Copy link
Author

I'm with @hasufell on this. Why does this need to live in this repo?

I'm confused by a statement from someone who uses Nix a lot! Confused, but interested...

The first thing that comes to mind for me is "Why does a flake.nix need to live in any repo?". To which the answer is "so I can use nix build, nix develop, or use direnv to transparently use nix develop".

In that view, it'd be ideal if all repos had a flake.nix in the same way many have a Dockerfile.

This flake could easily live in some github:<owner>/<repo> and instead of nix develop (inside of the cabal directory) one could do nix develop github:<owner>/<repo>.

How would you handle submitting a pull request? Delete the flake.{nix, lock} each time?

All this does is really create a shell with ghc cabal-install zlib.

That was on purpose to keep it as simple as possible. I was aware I'd probably meet resistance and even this level of complexity was responded to with:

Nix setups are a hell of a burden

So in this situation it seems:

  • to the Nix averse or Nix newbies any any inclusion of nix is hopelessly complex
  • In the attempt to simplify as much as possible and avoid complexity, experienced Nix users claim this simple of a change doesn't add value

Am I alone in the period of time I knew that nix-shell existed but couldn't remember nix-shell -p ghc cabal-install zlib?

Or for instance in having teammates that won't learn the concepts to be able to create a flake.nix or remember nix-shell -p ghc cabal-install zlib but are okay with remembering nix develop and nix build?

From my perspective there is value here, but with a lot of experience I can see how it'd look pretty useless.

And as @Bodigrim correctly points out this is not an officially supported approach, or one that looks like it would be officially supported soon. As such I'm skeptical of the added value in relation to the added lines of code, potential divergence.

I don't know about you, but besides myself I know at least a few other nix users who immediately run nix develop or nix build any time they come across a repo that has flake.nix, end up toying with it, and sometimes even fix an issue.

Who'd be responsible for updating the nixpkgs pin?

I'd be fine with being responsible that. I'd be willing to be it wouldn't need to be done super frequently and would be quite easy each time.

For an example on how the development provisioning can be decoupled from the project, I could point to https://github.com/input-output-hk/devx; provisioning does not need to live in the project, especially not if it's as generic as here.

That's an option, but I can't remember such a long command. I'd like other Haskell/nix users to only have to type either cabal build cabal or nix develop; cabal build cabal.

Again the flake is basically identical to the following invocation:

nix-shell -p ghc -p cabal-install -p zlib

I agree. I think I responded to this one above though about keeping complexity down so the change wasn't too disagreeable. I'd also say that the above is simple as long as you know it, but as beginners you don't know what you don't know.

I get the appeal of direnv, but is there a large enough set of people who use this? The change seems to only be beneficial for people who (a) use nix, (b) use nix flakes, (c) use nix + direnv.

I think even without direnv this is a useful change. But to answer your question here are 170 on Github according to SourceGraph.

It's kind of a chicken and egg problem though no? Why use direnv with Nix if the software you hack on doesn't have a flake.nix and .envrc?

@hasufell
Copy link
Member

In that view, it'd be ideal if all repos had a flake.nix in the same way many have a Dockerfile.

We're comparing apples with oranges here.

Dockerfiles committed to repos are very rarely meant as a mechanism of setting up a dev environment for a contributor.

Either they are part of the build artifacts the project wants to produce on a release or they're an integral part of the CI workflow.

I think we could easily link to a third party repository in the contribution guide that maintains nix flake for cabal.

@angerman
Copy link
Collaborator

@ParetoOptimalDev correct. I do use nix a lot. But only where I am convinced of the benefits. And in this instance I'm not.

In this instance having a line in the CONTRIBUTING.md document, that says something like:

For nix users, the necessary development environment can usually be provisioned with

nix-shell -p ghc -p cabal-install -p zlib

or

nix develop github:nixos/dev-envs#cabal

or maybe (though potentially slightly more controversial) there could be a make target in the Makefile.

# hacking environments
##############################################################################
# make target for nix users, to ensure the necessary dependencies are available during hacking.
.PHONY: nix-shell
nix-shell:
	nix-shell -p ghc -p cabal-install -p zlib

The complexity in all these solution is magnitudes smaller than this PR, and are also readable (and understandable) by someone who doesn't know or care about nix much. This PR adds a nix file, a massive lock file, some .envrc file. Without broad consensus (and maybe there is broad consensus among the primary contributors to cabal?), I don't see the value in this. I have quite some doubts that the lack of .envrc, and nix flake are the reasons that inhibit people contributing to cabal.

It's kind of a chicken and egg problem though no? Why use direnv with Nix if the software you hack on doesn't have a flake.nix and .envrc?

True, but why should cabal be a vehicle to push this? Again is a large set of core contributors to cabal find this useful, I doubt there's much resistance here. My primary contribution to this PR is highlighting that the this PR adds a lot of lines of code, for which I don't see the justification yet. Again, maybe I'm wrong. I'd like to hear from existing contributors and maintainers (@Mikolaj?) if they thing taking this on adds value and strikes the right balance.

@andreabedini
Copy link
Collaborator

andreabedini commented Feb 11, 2023

@ParetoOptimalDev The flake doesn't have to live within the repo. You can host it on a repo on your own and maybe we can link to it from the README.md. This lets you maintain and curate your environment at will without any burden to cabal maintainers.

@Kleidukos
Copy link
Member

Likewise, I have no problems whatsoever for a nix setup living outside of the repo and us linking to it with the appropriate warnings.

@Mikolaj
Copy link
Member

Mikolaj commented Feb 11, 2023

@ParetoOptimalDev: first of all, thank you very much for your contribution. Second, just as the other esteemed commenters, I'd welcome tips for Nix users in our CONTRIBUTING.md, README.md, even Makefile, whichever is appropriate.

Regarding adding more files, I'd prefer if we reached a (near-)consensus. My personal worry is that the files bitrot and actually break or degrade the Nix setup of cabal-contributing Nix-persons and take their time in order to decide if the breakage it actually some particularly smart hack they can't grasp. The only way we know to prevent bitrot is CI. Our CI is strained already due to a lack of a cabal devops, even a part time one (BTW, contributions warmly welcome; adding GHC 9.6(alpha) to CI is the most urgent on the list, #8675). If you could find a way to improve cabal Nix experience without the risks outlined in this PR, that would be ideal.

@peterbecich
Copy link
Member

Thanks for this, could maybe be combined with https://github.com/yvan-sraka/cabal.nix

cabal/CONTRIBUTING.md

Lines 18 to 23 in a20e074

> **Note**
> If you're using Nix, you might find it convenient to work within a shell that has all the `Cabal` development dependencies:
> ```
> $ nix-shell -p cabal-install ghc ghcid haskellPackages.fourmolu_0_12_0_0 pkgconfig zlib.dev
> ```
> A Nix flake developer shell with these dependencies is also available, supported solely by the community, through the command `nix develop github:yvan-sraka/cabal.nix`.

@ulysses4ever
Copy link
Collaborator

This has been dormant for more than a year, so closing for now. Happy to discuss a nix-based dev experience at some point though.

@ulysses4ever ulysses4ever added the re: devx Improving the cabal developer experience (internal issue) label Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
re: devx Improving the cabal developer experience (internal issue) status: consider closing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants