Better way to use nixpkgs git repo

Hello! I have a question about better usage of nixpkgs github repo. For example I want to use this expression

Atm I have nixpkgs as submodule in git repo of my library. So far it was ok to have it, but I found that if I’m using my library in other haskell stack project (as extra-dep), stack build tool tries to fetch all library submodules with the command

git submodule update --init --recursive

Which is ok, but not for this huge repo. And I don’t see possibility to say stack to add --depth 1 parameter or something like that. So maybe there are better ways to use nixpkgs than just git submodule in project? Thanks!

i think what you are trying to accomplish can be done like so:

src = fetchgit {
    url = "https://github.com/your_repo/with_submodules.git";
    rev = "...";
    sha256 = "...";
    deepClone = false;
    fetchSubmodules = false;
  };

Haskell stack don’t understand nix expressions. In my case it has library with submodules in stack.yaml

extra-deps:
       - github: organization/package
         commit: ...

where organization/package has nixpkgs as submodule. I’m thinking how to avoid usage of nixpkgs submodule, because tools like haskell stack are doing only deep clone.

I’m just thinking that my approach to have access to nixpkgs expressions through git submodule might be wrong. I’m just not aware of alternatives.

Using builtins.fetchTarball you can avoid git cloning nixpkgs.git. Create a nixpkgs.nix containing this for instance:

builtins.fetchTarball {url="https://github.com/NixOS/nixpkgs-channels/archive/b7bdf48e3fa6b90ea475a03ed159f397bd3c3c65.tar.gz"; sha256="0ap49yync5rwvr5qn0qb45x2yzzix2vhfqfljbampdhs0ncnhigi";}

and use it in a shell.nix like this:

let
  nixpkgs = import ./nixpkgs.nix;
  pkgs = import nixpkgs {};
in
pkgs.mkShell {
  buildInputs = [
    pkgs.stack
  ];
  shellHook = ''
    export NIX_PATH="nixpkgs=${nixpkgs}"
  '';
}

You can generate this nixpkgs.nix like that (eg. in a .envrc when nixpkgs.nix does not exist):

nixpkgs_channel=nixos-unstable-small
rev=$(curl -L https://nixos.org/channels/"$nixpkgs_channel"/git-revision | head -n1 | tr -dC 'a-z0-9')             sha256=$(nix-prefetch-url --unpack https://github.com/NixOS/nixpkgs-channels/archive/"$rev".tar.gz)
echo >nixpkgs.nix "builtins.fetchTarball {url=\"https://github.com/NixOS/nixpkgs-channels/archive/$rev.tar.gz\"; sha256=\"$sha256\";}"

If you need to patch nixpkgs (when overlays are not powerful enough, eg. to change the type of an option of a NixOS service, or to directly fetch a PR which is not merged yet), you can do like this:

let
  originNixpkgs = import ./nixpkgs.nix;
  originPkgs = import originNixpkgs {};
  nixpkgsPatches = [
    { meta.description = "Dovecot plugin for Full Text Search (FTS) with Xapian";
      url = "https://github.com/NixOS/nixpkgs/pull/78780.diff";
      sha256 = "053md69ryybj27cp0xdfrza48zyzpblk6wvb2m2dbs9hm0gmcwc4";
    }
    { meta.description = "dstat: fix pluginpath";
      url = "https://github.com/NixOS/nixpkgs/pull/80151.diff";
      sha256 = "0jjw2gvp7b7v2n2m2d6yj0gw711j6p9lyjf5ywp2y9ql6905qf4b";
    }
  ];
  localNixpkgsPatches = [
    #patches/direnv.diff
  ];
  nixpkgs = originPkgs.stdenv.mkDerivation {
    name = "nixpkgs-patched";
    src = originNixpkgs;
    phases = [ "unpackPhase" "patchPhase" ];
    patches = map originPkgs.fetchpatch nixpkgsPatches ++ localNixpkgsPatches;
    postPatch = ''
      patch=$(printf '%s\n' ${builtins.concatStringsSep " " (map (p: p.sha256) nixpkgsPatches)} |
        sort | sha256sum | cut -c -7)
      mv $PWD $out
      echo "+patch-$patch" >$out/.version-suffix
    '';
  };
  pkgs = import nixpkgs {
    config = {}; # Make the config pure, ignoring user's config.
    #overlays = import ./overlays.nix;
  };
in
[...]

HTH,
Julien

2 Likes

Thanks! But it’s still unclear for me how exactly I can access this expression

Now when I have submodule, I’m just using

import ./nixpkgs/pkgs/development/beam-modules/build-mix.nix {
               inherit stdenv writeText elixir erlang hex lib;
             }

Importing yourself a path from within nixpkgs is rarely needed, I guess here you could use pkgs.beamPackages.hex.

Should you want to do such a contrived import, here is how you can:

nix-instantiate --eval --expr 'let nixpkgs = import ./nixpkgs.nix; pkgs = import nixpkgs {}; hex = pkgs.callPackage (nixpkgs + "/pkgs/development/beam-modules/hex") {}; in hex'

Or using the nixpkgs in your $NIX_PATH:

nix-instantiate --eval --expr 'let pkgs = import <nixpkgs> {}; hex = pkgs.callPackage <nixpkgs/pkgs/development/beam-modules/hex> {}; in hex'

Here, using pkgs.callPackage is like your import but avoids the manual inherit by auto-supplying attributes using those in pkgs.
You can override those using the extra {} if need be.

1 Like

Wow, that implicit inherit looks cool, I’ll definitely try it out, thanks!