callCabal2nixWithOptions: add srcModifier argument

Fixes #256769

Repro + test of fix here: https://gitlab.com/ramirez7/bug-repros/-/merge_requests/1

Adds a `srcModifier` argument to `callCabal2nixWithOptions` to allow
customizing the source files used to generate the cabal file (e.g. to
support `hpack`/`package.yaml`).
This commit is contained in:
Armando Ramirez 2023-09-27 14:41:12 -07:00 committed by sternenseemann
parent 9e2c860bc2
commit 876d055062
2 changed files with 76 additions and 12 deletions

View File

@ -230,7 +230,7 @@ completely incompatible with packages from `haskellPackages`.
Every haskell package set has its own haskell-aware `mkDerivation` which is used
to build its packages. Generally you won't have to interact with this builder
since [cabal2nix][cabal2nix] can generate packages
since [cabal2nix](#haskell-cabal2nix) can generate packages
using it for an arbitrary cabal package definition. Still it is useful to know
the parameters it takes when you need to
[override](#haskell-overriding-haskell-packages) a generated Nix expression.
@ -1123,18 +1123,75 @@ for [this to work][optparse-applicative-completions].
Note that this feature is automatically disabled when cross-compiling, since it
requires executing the binaries in question.
## Import-from-Derivation helpers {#haskell-import-from-derivation}
### cabal2nix {#haskell-cabal2nix}
[`cabal2nix`][cabal2nix] can generate Nix package definitions for arbitrary
Haskell packages using [import from derivation][import-from-derivation].
`cabal2nix` will generate Nix expressions that look like this:
```nix
# cabal get mtl-2.2.1 && cd mtl-2.2.1 && cabal2nix .
{ mkDerivation, base, lib, transformers }:
mkDerivation {
pname = "mtl";
version = "2.2.1";
src = ./.;
libraryHaskellDepends = [ base transformers ];
homepage = "http://github.com/ekmett/mtl";
description = "Monad classes, using functional dependencies";
license = lib.licenses.bsd3;
}
```
This expression should be called with `haskellPackages.callPackage`, which will
supply [`haskellPackages.mkDerivation`](#haskell-mkderivation) and the Haskell
dependencies as arguments.
`callCabal2nix name src args`
: Create a package named `name` from the source derivation `src` using
`cabal2nix`.
`args` are extra arguments provided to `haskellPackages.callPackage`.
`callCabal2nixWithOptions name src opts args`
: Create a package named `name` from the source derivation `src` using
`cabal2nix`.
`opts` are extra options for calling `cabal2nix`. If `opts` is a string, it
will be used as extra command line arguments for `cabal2nix`, e.g. `--subpath
path/to/dir/containing/cabal-file`. Otherwise, `opts` should be an AttrSet
which can contain the following attributes:
`extraCabal2nixOptions`
: Extra command line arguments for `cabal2nix`.
`srcModifier`
: A function which is used to modify the given `src` instead of the default
filter.
The default source filter will remove all files from `src` except for
`.cabal` files and `package.yaml` files.
<!--
`callHackage`
: TODO
`callHackageDirect`
: TODO
`developPackage`
: TODO
-->
<!--
TODO(@NixOS/haskell): finish these planned sections
### Overriding the entire package set
## Import-from-Derivation helpers
* `callCabal2nix`
* `callHackage`, `callHackageDirect`
* `developPackage`
## Contributing {#haskell-contributing}
### Fixing a broken package {#haskell-fixing-a-broken-package}
@ -1309,3 +1366,4 @@ relevant.
[profiling]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html
[search.nixos.org]: https://search.nixos.org
[turtle]: https://hackage.haskell.org/package/turtle
[import-from-derivation]: https://nixos.org/manual/nix/stable/language/import-from-derivation

View File

@ -211,15 +211,21 @@ in package-set { inherit pkgs lib callPackage; } self // {
}) firstRevision;
# Creates a Haskell package from a source package by calling cabal2nix on the source.
callCabal2nixWithOptions = name: src: extraCabal2nixOptions: args:
callCabal2nixWithOptions = name: src: opts: args:
let
filter = path: type:
extraCabal2nixOptions = if builtins.isString opts
then opts
else opts.extraCabal2nixOptions or "";
srcModifier = opts.srcModifier or null;
defaultFilter = path: type:
pkgs.lib.hasSuffix ".cabal" path ||
baseNameOf path == "package.yaml";
expr = self.haskellSrc2nix {
inherit name extraCabal2nixOptions;
src = if pkgs.lib.canCleanSource src
then pkgs.lib.cleanSourceWith { inherit src filter; }
src = if srcModifier != null
then srcModifier src
else if pkgs.lib.canCleanSource src
then pkgs.lib.cleanSourceWith { inherit src; filter = defaultFilter; }
else src;
};
in overrideCabal (orig: {