How to get one package from nix unstable?

I’m roughly stealing the code from Installing only a single package from `unstable` - #3 by fosskers to try to pull one package from unstable (this is shell.nix btw not NixOS):

  unstableTarball = builtins.fetchTarball {
    url = "https://github.com/nixos/nixpkgs/tarball/266ea7a68284945f04d8b78ad31e355bccd005d0";
    sha256 = "1jk6955blbqdfwb4d89ri3bakizbzf9k07nrg6pnbv8vl5445k6c";
  };
  
  unstablePackages = import
    unstableTarball
    { config = config.nixpkgs.config; };

I’m getting the error

undefined variable 'config'

If I change the line at the top of shell.nix from:

{ pkgs ? import <nixpkgs>, system  }:

to

{ pkgs ? import <nixpkgs>, system, config  }:

I then get the error

shell.nix:1:1 called without required argument 'config'

Note there is a line in flake.nix that is:

        devShell =
          import ./nix/shell.nix { inherit pkgs system; };

So perhaps I need to change this to pass in the config?

Note if I change:

  unstablePackages = import
    unstableTarball
    { config = config.nixpkgs.config; };

to

  unstablePackages = import
    unstableTarball
    {  };

I get the error:

error: attribute 'currentSystem' missing

Anyone got any guidance?

If you are using flakes, then it makes much more sense to add another input, and using that.

This is crucial. The linked example is a NixOS module, see the NixOS manual on modules for how they are structured. It’s the NixOS module system which passes config to its modules. There is no such thing in shell.nix or Flakes.

The reason why we set config in import unstableTarball {} is defensive programming. We want the unstable Nixpkgs to be configured the same as the other version we use, e.g. to also have allowUnfree or what not.

But in fact you don’t have to take the existing nixpkgs.config from NixOS config - it lives in pkgs.config as well.

For your specific problem you can do the following (assuming pkgs is your primary Nixpkgs):

unstablePackages = import unstableTarball { config = pkgs.config; inherit system; };

The reason for the error

error: attribute 'currentSystem' missing

is that flakes only allow pure evaluation, i.e., Nix will not determine your current system, as that would be a side effect. Usually, without flakes or pure evaluation, builtins.currentSystem will evaluate to whatever your system is, e.g. "x86_64-linux".

So only in the pure setting you would ever need to set system on importing Nixpkgs, but @NobbZ is right:

Then, if you add e.g. inputs.unstable and an argument unstable to the outputs = { ... }: function, your call to devShell will look like this:

devShell = import ./nix/shell.nix { inherit pkgs unstable; };

and you can use unstable as an argument in shell.nix:

{ pkgs, unstable }:
pkgs.mkShell {
  builtInputs = [ pkgs.foo unstable.bar ];
}

(I suppose you don’t need system any more, unless it is used for something else in the shell.)

4 Likes

Thank you @fricklerhandwerk for your reply.

I’m having trouble working out how do to this. I note that in my flake.nix file there is currently no reference to nixpkgs. But in my flake.lock file there is a reference to nixpkgs, and indeed in the past I have updated this pin.

    "nixpkgs": {
      "locked": {
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "4aceab3cadf9fef6f70b9f6a9df964218650db0a",
        "type": "github"
      },
      "original": {
        "id": "nixpkgs",
        "type": "indirect"
      }
    },

I figured I should add a “nixpkgs-unstable” like so:

    "nixpkgs-unstable": {
      "locked": {
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "a3a3dda3bacf61e8a39258a0ed9c924eeca8e293",
        "type": "github"
      },
      "original": {
        "id": "nixpkgs-unstable",
        "type": "indirect"
      }
    },

But I then haven’t a clue how to reference this nixpkgs-unstable in my inputs.

You do not edit the lock file directly, you just add an input to your flake.nix, nix will take care of the lockfile for you then.

Take a look at my various nixpkgs inputs:

I ended up working this out. For anyone viewing this ticket in the future, do the following:

  1. Add nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; to one’s inputs
  2. Add nixos-unstable to the arguments of outputs.
  3. Pass nixos-unstable to any import statements below where you need it.
  4. Add nixos-unstable to the argument list of any imported files where you have added the nixos-unstable argument.

That will then generate an entry in flake.nix the next time you run things. You can then manually edit the commit pin if you like.

@clinton that would be a great How-To article for nix.dev (source). If you consider taking time to draft one which contains a full example, I can help you along by reviewing.

1 Like

Are you able to explain what you mean exactly in steps three and four please? Also, I presume that in step two you meant to write nixpkgs-unstable rather than nixos-unstable, since that’s what seems to work for me?