如何使用 `callCabal2nix` 将包列表提供给 'ghcWithPackages'?

How to get use `callCabal2nix` to supply package list to 'ghcWithPackages'?

我有一个包含 ~46 个依赖项的列表。

我生成了一个 shell,其中包括调用:

server = pkgs.haskellPackages.callCabal2nix "server" ./server.cabal { };

在进入 pkgs.myHaskellPackagespkgs.haskellPackages 覆盖范围内。

shell 工作正常。但是,我有另一个用于构建 docker 的 nix,这需要来自以下的构建输入:

ghc = pkgs.myHaskellPackages.ghcWithPackages (p: [ longlistofdependencies ]);

如何指定一长串依赖项而不必手动写出它们,这违背了使用 callCabal2nix 的初衷。

let                                                                                                                                                                                                                                           
  bootstrap = import <nixpkgs> { };                                                                                                                                                                                                           
                                                                                                                                                                                                                                              
  nixpkgs = builtins.fromJSON (builtins.readFile ./nixpkgs-unstable.json);                                                                                                                                                                    
                                                                                                                                                                                                                                              
  src = bootstrap.fetchFromGitHub {                                                                                                                                                                                                           
    owner = "NixOS";                                                                                                                                                                                                                          
    repo  = "nixpkgs";                                                                                                                                                                                                                        
    inherit (nixpkgs) rev sha256;                                                                                                                                                                                                             
  };                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                              
  config = {                                                                                                                                                                                                                                  
    allowBroken = true;                                                                                                                                                                                                                       
                                                                                                                                                                                                                                              
    packageOverrides = pkgs: rec {                                                                                                                                                                                                            
      servantSrc = pkgs.fetchFromGitHub {                                                                                                                                                                                                     
        owner = "haskell-servant";                                                                                                                                                                                                            
        repo = "servant";                                                                                                                                                                                                                     
        rev = "73c87bc2bc0685649f2337b06ab4fdc66c4ce1dd";                                                                                                                                                                                     
        sha256 = "0sw4mrncmfna30cyxrvinc1krqhfxn5dcc1ggzqfy39s0yl9q98r";                                                                                                                                                                      
        #sha256 = "0000000000000000000000000000000000000000000000000000";                                                                                                                                                                     
      } + "/servant";                                                                                                                                                                                                                         
                                                                                                                                                                                                                                              
      myHaskellPackages = pkgs.haskellPackages.override {                                                                                                                                                                                     
        overrides = haskellPackagesNew: haskellPackagesOld: rec {                                                                                                                                                                             
          server =                                                                                                                                                                                                                            
            haskellPackagesNew.callCabal2nix "server" ./server.cabal { };                                                                                                                                                                     
                                                                                                                                                                                                                                              
          servant =                                                                                                                                                                                                                           
            haskellPackagesNew.callCabal2nix "servant" servantSrc {};                                                                                                                                                                         

          # several other overridden packages                                                                                                                                                                                                                                    
        };
      };
    };
  };

  pkgs = import src { inherit config; };

  devShell = pkgs.myHaskellPackages.shellFor {
    packages = p: [
      p.server 
    ];
    buildInputs = with pkgs.haskellPackages; [
      hlint
      brittany
      haskell-language-server
    ];
  };

  # Every time a dependency changes in the cabal file, this has to be edited as well.
  ghc = pkgs.myHaskellPackages.ghcWithPackages (p: [
    p.aeson p.aeson-qq p.base p.blaze-html p.bytestring p.cache p.containers
    p.contravariant-extras p.criterion p.either p.hashable p.hasql
    p.hasql-migration p.hasql-pool p.hasql-th p.hasql-transaction p.hspec
    p.http-client p.http-conduit p.http-types p.immortal-queue p.lens p.linear
    p.monad-logger p.mtl p.pqueue p.pretty-simple p.QuickCheck p.raw-strings-qq
    p.servant-blaze p.servant-docs p.servant-server
    p.string-interpolate p.text p.text-format p.time p.tuple p.unordered-containers
    p.utf8-string p.vector p.vector-split p.wai p.wai-cors p.warp p.xlsx p.yaml
  ]);

in {
  inherit devShell;
  inherit ghc;
  inherit pkgs;
}

ghc 输出在 docker.nix 中用作构建输入:

let 
    inherit (import ./pinned-nixpkgs.nix) ghc pkgs;

    pricing-server =
        pkgs.stdenv.mkDerivation {
            name = "my-server";
            pname = "my-server";
            version = "1.1.0";
            src = ./.;

            buildPhase = ''
              ghc -O2 --make -outputdir ./tmp2 Main.hs
            '';

            installPhase = ''
              mkdir -p $out/bin
              cp Main $out/bin
              cp -r ./sql $out/bin
            '';

            buildInputs = [ ghc ];
        };
in
dockerTools.buildImage {
    # irrelevant to the question.
}

可能的解决方案是 pkgs.myHaskellPackages.server.getBuildInputs.haskellBuildInputs,或 pkgs.myHaskellPackages.server.getCabalDeps.libraryHaskellDepends

您可以使用 nix repl 探索这些属性或任何表达式。不过,您可能必须从 let 绑定中公开一些值。在这种情况下,我只是在 nix repl <nixpkgs>.

中浏览了 haskellPackages.warp

我还注意到您在叠加层中使用了 rec。这将对你有用,直到它不起作用。我建议删除 rec 以避免以第三种方式访问​​属性,并改用更标准的 haskellPackagesNew.servant