Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show how to incorporate ghcWithHoogle into shell.nix #33

Open
kuznero opened this issue Nov 9, 2017 · 4 comments · May be fixed by #90
Open

Show how to incorporate ghcWithHoogle into shell.nix #33

kuznero opened this issue Nov 9, 2017 · 4 comments · May be fixed by #90

Comments

@kuznero
Copy link

kuznero commented Nov 9, 2017

Show how to incorporate ghcWithHoogle into shell.nix preferably without modifying default.nix that is generated with cabal2nix . > default.nix.

@kuznero kuznero changed the title Show how to incorporate ghcWithHoogle into shell.nix Show how to incorporate ghcWithHoogle into shell.nix Nov 9, 2017
@Gabriella439
Copy link
Owner

I don't know of an (easy) way to do this.

Normally the way you would do this for a package already in nixpkgs is to do nix-shell --packages haskellPackages.ghcWithHoogle (pkgs : [ pkgs.someHaskellPackage ]). However, nix-shell doesn't have an easy way to change the package set while using the --packages option. The way we work around this at work is to override nixpkgs to use our own package set that is the same as nixpkgs except with our own custom packages injected in.

@kuznero
Copy link
Author

kuznero commented Nov 12, 2017

@Gabriel439, so far I ended up including additional hoogle.nix:

{ compiler ? "ghc821" }:

let
  bootstrap = import <nixpkgs> {};
  nixpkgs = builtins.fromJSON (builtins.readFile ./nixpkgs.json);
  src = bootstrap.fetchFromGitHub {
    owner = "NixOS";
    repo  = "nixpkgs";
    inherit (nixpkgs) rev sha256;
  };
  pkgs = import src { };
in
  with pkgs;
  runCommand "shell" {
    buildInputs = [
      ( haskell.packages.${compiler}.ghcWithHoogle ( ps: with ps; [
        data-default
      ] ) )
    ];
  } ""

This file needs to be modified every time dependencies change (at least every time developer needs documentation on another dependency he/she is using). In addition there is a simple hoogle.sh bash script that simply starts hoogle server:

#!/usr/bin/env bash
nix-shell hoogle.nix --command "hoogle server -p 8080 --local --haskell"

This has a bit of code duplication to re-use pinned nixpkgs coming from nixpkgs.json (similar to release.nix), but this way it at least is connected to exact version developer is using.

This works kind of on the side from shell.nix, default.nix and release.nix. Another thing I was thinking is to modify default.nix to accept additional boolean flag that will override ghc with ghcWithPackages, but then it will also need to add it to buildDepends which is not so nice, as I would like to keep using the version of default.nix generated for me by cabal2nix. So, in the end of the day I think that inconvenience of rebuilding hoogle.nix when dependencies change is an ok trade off, compare to changing default.nix.

Though it would still be nice to enclose such things solely in shell.nix.

You may find example project here.

@cumber
Copy link

cumber commented Nov 13, 2017

I've used this as my shell.nix in the past:

{ nixpkgs ? import <nixpkgs> {}, compiler ? "default", withHoogle ? true }:

let

  inherit (nixpkgs) pkgs;

  f = import ./default.nix;

  packageSet = (
    if compiler == "default"
      then  pkgs.haskellPackages
      else  pkgs.haskell.packages.${compiler}
  );

  haskellPackages = (
    if withHoogle
      then  packageSet.override {
              overrides = (self: super:
                {
                  ghc = super.ghc // { withPackages = super.ghc.withHoogle; };
                  ghcWithPackages = self.ghc.withPackages;
                }
              );
            }
      else  packageSet
  );

  drv = haskellPackages.callPackage f {};

in

  if pkgs.lib.inNixShell then drv.env else drv

It's designed to import a default.nix produced by cabal2nix . > default.nix, without needing to manually update anything other than the cabal file. I suspect I'd do something cleaner with overlays if I was writing it now (I haven't used this particular setup for a little while).

The key idea is to override ghcWithPackages to actually be ghcWithHoogle, so that when the haskell helper nix code produces the env attribute containing a suitable build environment, it pulls in a hoogle database as well as just the libraries.

@kuznero
Copy link
Author

kuznero commented Nov 13, 2017

@cumber thanks a lot! I ended up extending your shell.nix slightly to pin nixpkgs. So now it looks much cleaner and most importantly uses cabal packages 👍

{ compiler ? "ghc821"
, withHoogle ? true
}:

let
  bootstrap = import <nixpkgs> {};
  nixpkgs = builtins.fromJSON (builtins.readFile ./nixpkgs.json);
  src = bootstrap.fetchFromGitHub {
    owner = "NixOS";
    repo  = "nixpkgs";
    inherit (nixpkgs) rev sha256;
  };
  pkgs = import src {};
  f = import ./default.nix;
  packageSet = pkgs.haskell.packages.${compiler};
  hspkgs = (
    if withHoogle then
      packageSet.override {
        overrides = (self: super: {
          ghc = super.ghc // { withPackages = super.ghc.withHoogle; };
          ghcWithPackages = self.ghc.withPackages;
        });
      }
      else packageSet
  );
  drv = hspkgs.callPackage f {};
in
  if pkgs.lib.inNixShell then drv.env else drv

TristanCacqueray added a commit to TristanCacqueray/haskell-nix that referenced this issue Oct 17, 2020
@TristanCacqueray TristanCacqueray linked a pull request Oct 17, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants