|
5 | 5 | , lib |
6 | 6 | , runCommand |
7 | 7 | , stdenv |
| 8 | +, path |
8 | 9 | }@topargs: |
9 | 10 |
|
10 | 11 | { # The path to your stack.yaml file. |
|
77 | 78 | # This is not used if `baseHaskellPkgSet` is `null`. |
78 | 79 | all-cabal-hashes ? null |
79 | 80 | , callPackage ? topargs.callPackage |
| 81 | +, # Path to Nixpkgs. |
| 82 | + # |
| 83 | + # nixpkgsPath :: Path |
| 84 | + nixpkgsPath ? topargs.path |
80 | 85 | }: |
81 | 86 |
|
82 | 87 | # The stack.yaml path can be computed from the stack.yaml.lock path, or |
|
372 | 377 | # This roughly returns an overlay that looks like the following: |
373 | 378 | # ``` |
374 | 379 | # { lens = callHackage "lens" "5.0.1" {}; |
375 | | - # conduit = callHackage "conduit" "5.0.1" {}; |
| 380 | + # conduit = callHackage "conduit" "1.3.4" {}; |
376 | 381 | # } |
377 | 382 | # ``` |
378 | 383 | haskPkgLocksToOverlay = haskPkgLocks: hfinal: hprev: |
@@ -635,22 +640,135 @@ let |
635 | 640 | inherit all-cabal-hashes; |
636 | 641 | }); |
637 | 642 |
|
| 643 | + devShellForPkgSet = packageSet: |
| 644 | + if packageSet == null then |
| 645 | + null |
| 646 | + else |
| 647 | + packageSet.shellFor { |
| 648 | + packages = localPkgsSelector; |
| 649 | + nativeBuildInputs = additionalDevShellNativeBuildInputs packageSet; |
| 650 | + }; |
| 651 | + |
638 | 652 | # A development shell created by passing all your local packages (from |
639 | 653 | # `localPkgsSelector`) to `pkgSet.shellFor`. |
640 | 654 | # |
641 | 655 | # devShell :: Drv |
642 | 656 | # |
643 | 657 | # Note that this derivation is specifically meant to be passed to `nix |
644 | 658 | # develop` or `nix-shell`. |
645 | | - devShell = |
646 | | - if pkgSet == null then |
| 659 | + devShell = devShellForPkgSet pkgSet; |
| 660 | + |
| 661 | + # An Nixpkgs Haskell overlay that has GHC boot packages set to `null`. This |
| 662 | + # is used as an initial overlay when creating a brand new package set. |
| 663 | + newPkgSetCompilerConfig = self: super: { |
| 664 | + # TODO: Should llvmPackages be enabled here? |
| 665 | + # llvmPackages = pkgs.lib.dontRecurseIntoAttrs self.ghc.llvmPackages; |
| 666 | + |
| 667 | + # Disable GHC core libraries. |
| 668 | + array = null; |
| 669 | + base = null; |
| 670 | + binary = null; |
| 671 | + bytestring = null; |
| 672 | + Cabal = null; |
| 673 | + containers = null; |
| 674 | + deepseq = null; |
| 675 | + directory = null; |
| 676 | + exceptions = null; |
| 677 | + filepath = null; |
| 678 | + ghc-bignum = null; |
| 679 | + ghc-boot = null; |
| 680 | + ghc-boot-th = null; |
| 681 | + ghc-compact = null; |
| 682 | + ghc-heap = null; |
| 683 | + ghc-prim = null; |
| 684 | + ghci = null; |
| 685 | + haskeline = null; |
| 686 | + hpc = null; |
| 687 | + integer-gmp = null; |
| 688 | + libiserv = null; |
| 689 | + mtl = null; |
| 690 | + parsec = null; |
| 691 | + pretty = null; |
| 692 | + process = null; |
| 693 | + rts = null; |
| 694 | + stm = null; |
| 695 | + template-haskell = null; |
| 696 | + |
| 697 | + # GHC only builds terminfo if it is a native compiler |
| 698 | + # terminfo = if pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform then null else self.terminfo_0_4_1_5; |
| 699 | + terminfo = null; |
| 700 | + |
| 701 | + text = null; |
| 702 | + time = null; |
| 703 | + transformers = null; |
| 704 | + unix = null; |
| 705 | + |
| 706 | + # GHC only bundles the xhtml library if haddock is enabled, check if this is |
| 707 | + # still the case when updating: https://gitlab.haskell.org/ghc/ghc/-/blob/0198841877f6f04269d6050892b98b5c3807ce4c/ghc.mk#L463 |
| 708 | + # xhtml = if self.ghc.hasHaddock or true then null else self.xhtml_3000_2_2_1; |
| 709 | + xhtml = null; |
| 710 | + }; |
| 711 | + |
| 712 | + # This is similar to `pkgSet`. |
| 713 | + # |
| 714 | + # While `pkgSet` is `baseHaskellPkgSet` overridden with overlays from your |
| 715 | + # stack.yaml.lock file, `newPkgSet` is a completely new Nixpkgs Haskell |
| 716 | + # package set. It _only_ contains packages defined in the `stack.yaml` file. |
| 717 | + # |
| 718 | + # newPkgSet :: HaskellPkgSet |
| 719 | + # |
| 720 | + # `newPkgSet` will contain local packages. For instance, if you have a local |
| 721 | + # package called `my-haskell-pkg`: |
| 722 | + # |
| 723 | + # Example: `newPkgSet.my-haskell-pkg` |
| 724 | + # |
| 725 | + # `newPkgSet` will also contain packages in your stack.yaml resolver. For |
| 726 | + # instance: |
| 727 | + # |
| 728 | + # Example: `newPkgSet.lens` |
| 729 | + # |
| 730 | + # `pkgSet` will _not_ contain packages from the underlying Haskell package |
| 731 | + # set. For instance, `termonad` is not available in Stackage, so it is not |
| 732 | + # available in `newPkgSet`. |
| 733 | + newPkgSet = |
| 734 | + if baseHaskellPkgSet == null then |
647 | 735 | null |
648 | 736 | else |
649 | | - pkgSet.shellFor { |
650 | | - packages = localPkgsSelector; |
651 | | - nativeBuildInputs = additionalDevShellNativeBuildInputs pkgSet; |
652 | | - }; |
| 737 | + let |
| 738 | + haskPkgSet = callPackage (nixpkgsPath + "/pkgs/development/haskell-modules") { |
| 739 | + haskellLib = haskell.lib.compose; |
| 740 | + |
| 741 | + # TODO: Is it okay to use a completely different package set as the |
| 742 | + # base package set like this? |
| 743 | + buildHaskellPackages = baseHaskellPkgSet; |
| 744 | + |
| 745 | + ghc = baseHaskellPkgSet.ghc; |
| 746 | + |
| 747 | + compilerConfig = newPkgSetCompilerConfig; |
| 748 | + |
| 749 | + initialPackages = _: _: {}; |
| 750 | + |
| 751 | + overrides = lib.composeManyExtensions [ |
| 752 | + # It is not possible to put these overlays into the |
| 753 | + # `initialPackages` argument, because they use functions like |
| 754 | + # `callHackage` and `callCabal2nix`, which appear to not be |
| 755 | + # available when `initialPackages` gets evaluated. |
| 756 | + combinedOverlay |
| 757 | + additionalHaskellPkgSetOverrides |
| 758 | + ]; |
| 759 | + |
| 760 | + nonHackagePackages = _: _: {}; |
| 761 | + configurationCommon = _: _: _: {}; |
| 762 | + configurationNix = _: _: _: {}; |
| 763 | + configurationArm = _: _: _: {}; |
| 764 | + configurationDarwin = _: _: _: {}; |
| 765 | + }; |
| 766 | + in haskPkgSet; |
653 | 767 |
|
| 768 | + # Same as `devShell`, but based on `newPkgSet`. |
| 769 | + # |
| 770 | + # newPkgSetDevShell :: Drv |
| 771 | + newPkgSetDevShell = devShellForPkgSet newPkgSet; |
654 | 772 | in |
655 | 773 |
|
656 | 774 | { inherit |
|
662 | 780 | localPkgsSelector |
663 | 781 | pkgSet |
664 | 782 | devShell |
| 783 | + newPkgSet |
| 784 | + newPkgSetDevShell |
665 | 785 | ; |
666 | 786 |
|
667 | 787 | # These are a bunch of internal attributes, used for testing. |
|
0 commit comments