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

nix-shell fails when passed -A env #19

Closed
m-renaud opened this issue Jul 12, 2017 · 6 comments
Closed

nix-shell fails when passed -A env #19

m-renaud opened this issue Jul 12, 2017 · 6 comments

Comments

@m-renaud
Copy link

On the most recent version of Nix the nix-shell -A env release0.nix command fails with the error:

error: attribute ‘env’ in selection path ‘env’ not found

Version info: nix-shell --version

nix-shell (Nix) 1.11.11

If you omit the -A env it works as expected.

@m-renaud
Copy link
Author

After further investigation, cloning this repo and running the command works. I had created my own repo and was following the README when I got the error above. There must be something that I'm missing but my default.nix looks identical to the one in this repo. Where is env defined?

@Gabriella439
Copy link
Owner

The -A flag is short for attribute, and conceptually if you do:

$ nix-shell --attr foo someFile.nix

... it is the same as:

$ nix-shell --expr '(import someFile.nix).foo`

In other words, it imports that file, evaluates the corresponding Nix expression, and then assumes that it is a record and tries to access the .foo attribute of that record

The reason that -A env works on the very first example is because that example evaluates to a Haskell package derivation:

let
  pkgs = import <nixpkgs> { };

in
  pkgs.haskellPackages.callPackage ./default.nix { }

... and every Haskell package derivation has an env attribute that you can use to create a nix-shell. The release2.nix example wraps that derivation in yet another record:

let
  pkgs = import <nixpkgs> { };

in
  { project0 = pkgs.haskellPackages.callPackage ./default.nix { };
  }

... which is why the attribute changes to project0.env, because now you need to access the project0 attribute of the outermost record and then access the env attribute of that

So the reason env didn't work is that your repo had an outer record wrapping the Haskell package derivation (like the release2.nix) example

Also, env is defined for all Haskell package derivations. The exact place where it is defined is here: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/generic-builder.nix#L335

@m-renaud
Copy link
Author

I've read through the Nix docs and other posts online and that was the most concise explanation I've seen for how the different parts of the command come together, thank you!

and every Haskell package derivation has an env attribute ...

Ahhh, that's the missing piece!

Reading back through it again I can see two things that initially confused me:

  1. Some of the example commands use a nix file with a naked derivation such as nix-shell -A env release0.nix in project0, while others later on have a set/record (release2.nix as you mention). Maybe just skip the naked derivation (release0.nix), since you say shortly after that you don't recommend doing that anyways :)
  2. nix-build uses -A projectx and nix-shell uses -A projectx.env (the latter specifying .env, the formed does not). It seems like a pretty easy mistake to make and since projectx is a valid expression there isn't an error, subsequent commands just fail mysteriously. Do you know why for nix-build you omit the .env suffix?

Also, all Haskell packages have env defined, is that just convention for Haskell packages or is that something I would see in other package groups as well? I guess Nix wouldn't care, but I wasn't able to find any docs around how the Haskell packages are structured, do you know if any exist?

In any case, I think having a section about how Haskell package derivations are structured and how the attribute argument is combined with the Nix expression would be very useful somewhere in this repo.

Anyways, thanks again for putting this together! It was incredibly helpful and I think I'm going to use Nix going forward :)

@Gabriella439
Copy link
Owner

Not all packages have a .env defined. Only some languages require the .env for nix-shell whereas others don't. A lot of these instructions derive the from the Nixpkgs manual which tells you what are the language-specific idioms for doing development in Nix: https://nixos.org/nixpkgs/manual/

I will probably stick with not wrapping the result in a record initially, but better explain what the -A flag is doing and where the .env attribute comes from so that the user is less confused

@Gabriella439
Copy link
Owner

I have a pull request out with updates to the tutorial: #22

Take a look at that and let me know if that addresses your initial confusion

@m-renaud
Copy link
Author

Left a few comments but LGTM.

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

No branches or pull requests

2 participants