A sort of branch-off discussion of Convenience in the Haskell ecosystem:
TL;DR:
Should we be trying to create some type of wrapper around hpack/cabal that focuses on user experience, avoiding the work of creating a cabal exact-printer, not burdening cabal maintainers with thinking about perfect UX, and leaving cabal alone to be a good packaging tool/power user tool?
Background Context
So I was trying out Bodigrim’s cabal-add
tool the other day, and it worked great. Admittedly I didn’t push it very hard, I just ran through the standard user-story for it but it worked basically how I wanted it to. Thanks Bodigrim for making that!
But as I was working through one of my projects, I was reminded of another major annoyance when working with cabal: other-modules
and exposed-modules
. Forgetting to add a module to one of these lists causes HLS to get angry at you, and the error reporting for it can be a bit vague. So I got to thinking, it sure would be nice if these two module types could be detected automatically. I started researching past discussion on this and ran into State of Cabal Q1/Q2 2021 and this github issue
I thought that Matt Parsons’ glob syntax was a great way to solve this issue, but Oleg was against the change:
I’d be 100% against allowing files with globs to be uploded to Hackage, as ”which package exposes XYZ module” will be impossible to answer only considering the index.
I’d like to have solution to this, but losing the declarativeness is huge concern, and if it’s not addressed, this will be wontdo.
This comment also really resonated with me:
I agree with @cdsmith .
I think cabal should decide to either be:
- A low level build tool designed to be used by high level build tools (ie. stack) and IDEs.
- A fully featured build tool that has everything you need to build + maintain your project in a convenient package.
I don’t take issue with Oleg’s opposition to this change, he has a valid reason for not wanting the glob pattern since hackage relies on explicit module lists to properly discover things. But then, it sounds like cabal’s primary target is not the user, it’s the packaging system.
My thoughts
It seems like its fundamentally a mismatch to try and make cabal a user facing tool since it has strict requirements to adhere to a machine based specification. I’ve also seen the problem recurring for a while now that a big part of what makes this difficult is we don’t have an exact-printer for cabal files. It seems to me that cabal should be a tool for power users. Cabal files use a proprietary format that is meant to provide exact descriptions for hackage, but also gives power users a lot of strength to express themselves.
I’ve also seen some other comments where people have said, the solution is to rely more on generating cabal files (rather than directly editing them?).
So if that’s the case, why not use a config format that’s easy to edit both for humans and programmatically-wise, like yaml? Then I found hpack, which seems to satisfy the requirement for a less exotic config format.
Potential Solution
We already have the easier to use yaml version of cabal files, and it seems like its fairly popular already! At this point, it feels like it would make more sense to write some wrapper around hpack/cabal which focuses on a user-friendly experience.
I could imagine some tool hacker
with cli options like
-
hacker add <component> <package>
Automatically adds packages to thedependencies
section of an hpack file -
hacker remove <component> <package>
Automatically removes the package from dependencies -
hacker build
-
hacker test
-
hacker run
and setting exposed-modules
and other-modules
to file system paths like
otherModules: "./src/internal/*"
exposedModules: "./src/public/*"
And then this tool would browse those paths to create an explicit package list when generating the cabal file.
Im sure there are other convenience commands people could think of that programmatically alter the hpack file from the cli. And each time one of these commands is run, hacker
automatically regenerates the cabal file.
This tool would be the “user-facing cabal”, free to focus on an ideal user experience, without having to worry about breaking the cabal spec, and without having to create a cabal exact-printer/parser. And it’s not really the same as stack
since it’s not focused on package sets, it would just be the normal hackage use-case.
I dunno! What do you all think?