Global configuration of default packages

I’ve got an idea:
allow for a global configuration of all the packages that are included by default by cabal or even loaded by ghc.
This includes

  • The configured list of packages is by default in cabal build-depends
  • That list of packages is by default loaded by ghci (as if we had written ghci -package A -package -B
  • When compiling ghc modules without cabal the “default packages” are also made available implicitly (-package)
  • cabal repl loads the default packages too

Implementation wise:

  • for cabal this should not be a problem, since cabal manages its own set of package databases, so all packages specified in the default configuration would be in reach
  • for ghc it is not so simple: ghc uses a global package database (configured at install time) which often just has the boot packages (containers et all). Specifying, in the said default package list, packages already included in the global database would be trivial, but to access packages not installed in the global pkg DB I’m not sure - either we disallow it or allow specifying additional package databases there? not simple.
  • a third option is for ghc to simply load all packages it recognizes, while cabal will load them all and even install them if they aren’t yet available

Ultimately, though, I think regardless of that ghc pkgdb complication, this could work out well — and that said default list of packages could be itself, by default, the list that has been implicitly discussed here, which I think comprises just of packages already available in the global pkgdb

2 Likes

The motivation for it being that almost everyone would like their own particular set of things made available by default!
For some that includes e.g. aeson and recursion-schemes while others would rather have a minimal set and avoid tweaking the build depends every new project.

There is already a default GHC environment that GHC and GHCi will use outside of cabal packages. You can use the (dreaded) cabal install --lib command to add packages to that environment, however it’s quite easy to get conflicts and it is hard to remove packages from an environment. See 5.2. Commands — Cabal 3.10.1.0 User's Guide and 5.9. Packages — Glasgow Haskell Compiler 9.6.1 User's Guide.

One issue with including packages by default in build-depends fields is that .cabal files are supposed to be completely static descriptions of your package, so it should list all dependencies explicitly. One thing that cabal could do is to add a default set of packages when initializing a new package with cabal init.

I think the last point about cabal repl loading the global default packages would be easier to improve but only when cabal repl is called outside cabal projects. When called outside a project it will create a dummy project with some default configuration which I assume could be easily extended with the global default set of packages.

2 Likes

Yes, that is what I meant! Thanks Jaro

Oh, so that’s what cabal install --lib does! Thanks for the first intelligible explanation of that command I’ve seen. (I’ve never used it myself, but on the FP Discord server we regularly get beginners who try it and then get confused.)

Which is why the fix is usually to clear out the subdirectories of the .ghc directory.

1 Like

cabal install --lib often gets confusing.

cabal install --lib --package-env=. works pretty well IMHO. But it’s not global.

I wonder what extra messaging could be added to the tooling around package environments to make it less confusing.

There was the idea at some point of having a separate cabal env command IIRC. What came of it?

Whereas I like the idea, I think it isn’t a good idea. Generally speaking explicit is better than implicit. If I remmember correctly, stack has a templates option which allows you to share a package.yaml/stack.yaml file to start a project with some sensible defaults. I don’t know if cabal admits such a thing.

It would be nice to have a folder in the .cabal configuration file with templates and you can run cabal init --template cli_template, or cabal repl --template web_template. This would work moreless like “default” packages but it is more explicit.

3 Likes

cabal templates! Sounds really good. Though a default template is still explicit if you have to manually declare it. There’s an argument to be made about not having to worry again about sensible defaults after having configured them once.

There is an awesome tool called summoner which allows you to “summon” cabal projects (and more). I don’t really see the need to integrate this functionality into cabal-install itself.

2 Likes

In my mind, the most important thing to do is to remove this suggestion, which I got in the error message when I ran (for instance) cabal install pandoc:

* You might have wanted to add them to a GHC environment. In this case use
"cabal install --lib pandoc pandoc". The "--lib" flag is provisional: see
https://github.com/haskell/cabal/issues/6481 for more information.

That being said, I just now tried running that command again, and couldn’t get that error message… so maybe it’s been removed already?

Yes, we desperately need for cabal to stop recommending cabal install --lib.

Nice tool. Does “summoner” support the functionality talked here? I don’t it see in the documentation. For example the file configuration section doesn’t talk about dependencies.

That’s a good/reasonable argument.

Ah, you’re right. Currently you can only add one alternative prelude package as dependency. Maybe curating your own lists of default packages would be a good enhancement to summoner.

1 Like

/me Intensively thinks of a lightweight cabal plugin

(A plugin would arguably integrate better with existing cabal workflows and be more lightweight bc I would just want the one feature of setting defaults)

Is there such a thing as a cabal plugin?