-
-
Notifications
You must be signed in to change notification settings - Fork 264
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
Add shell.nix tutorial #671
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good start, but we should either make this sufficiently different from Declarative and Reproducible Developer Environments or combine them and reorganize.
PS1 = "\u@\h [myEnv] $ "; | ||
} | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other variables are protected: the shell prompt format is set by the `PS1` environment variable, but `nix-shell` already overrides this by default, and does not allow us to alter the `PS1` attribute directly. In these cases, we can still set a new value for that environment variable by manually exporting it in the [`shellHook` attribute](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell-attributes) passed to `mkShell`. | |
To set the shell prompt to the format `<username>@<hostname> [myEnv] $ `, the `shell.nix` file would look like this: | |
```nix | |
let | |
pkgs = import <nixpkgs> {}; | |
in | |
pkgs.mkShell { | |
packages = [ | |
pkgs.python310 | |
pkgs.curl | |
]; | |
# Database username and password | |
DB_USER = "db_user"; | |
DB_PASSWORD = "super secret don't look"; | |
# Set the shell prompt to '<username>@<hostname> [myEnv] $ ' | |
mkShell = '' | |
export PS1="\u@\h [myEnv] $ "; | |
''; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this together in todays Learning journey meeting.
There's duplication with the existing tutorial, but this is the first tutorial in the new learning journey series and it can be reconciled later with the existing material. We can add this to the landing page of the learning journey section.
- Does it overlap with https://nix.dev/tutorials/first-steps/declarative-and-reproducible-developer-environments?
- @zmitchell: Doesn't have motivation, doesn't cover everything
- @proofconstruction: There should be a flow between these tutorials
- @zmitchell: That one isn't in the learning journey track
- Regarding PS1 not being settable in env vars
- @roberth: nix-shell is messy, not worth going in-depth
- @infinisil: Warning to say that some attributes can't be set in derivation attributes, need to use shellHook instead
- @proofconstruction: Apparently the PS1 thing it's a feature in some Nix release notes
- @roberth:
shellHook
is also useful for e.g. appending to variables
- @infinisil:
- Use
python3
instead ofpython310
- Use
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-08-03-learning-journey-working-group-meeting-notes-20/31251/1 |
} | ||
``` | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed online: mention this as a warning rather than guidance. Mention that you can use shellHook
to still set these variables if you need to. Then illustrate the Bash syntax for exporting environment variables to do this as a one line example. Another example is setting secrets you get from another command.
touch should_exist.txt | ||
''; | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed online: Provide other examples such as initializing a data directory for a database, getting secrets, etc.
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-08-10-learning-journey-meeting-notes-21/31556/1 |
@zmitchell Oh, I said in the meeting that I would like to review it again, which I was just doing right now 😅 |
Shoot, I totally forgot. I can revert the commit. |
The `nix-shell` command by default looks for a file called `shell.nix` in the current directory and tries to build a shell environment by evaluating the Nix expression in this file. | ||
So, if you properly describe the shell environment you want in a `shell.nix` file, you can enter it with just the `nix-shell` command without any further arguments. | ||
No more specifying packages on the command line. | ||
Here's what a basic `shell.nix` looks like that installs Python 3.10 as before: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's what a basic `shell.nix` looks like that installs Python 3.10 as before: | |
Here's what a basic `shell.nix` looks like that installs Python 3 as before: |
]; | ||
} | ||
``` | ||
where `mkShell` is a function that when called produces a shell environment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where `mkShell` is a function that when called produces a shell environment. | |
where `mkShell` is a function that produces a shell environment. |
``` | ||
|
||
:::{note} | ||
`nix-shell` was originally conceived as a way to construct a shell environment containing the tools needed to *develop software*; only later was it widely used as a general way to construct temporary environments for other purposes. Also note that `mkShell` is a [wrapper around `mkDerivation`](https://nixos.org/manual/nixpkgs/stable/#sec-pkgs-mkShell) so strictly speaking you can provide any attributes to `mkShell` that you could to `mkDerivation` such as `buildInputs`. However, the `packages` attribute provided to `mkShell` is an alias for `buildInputs`, so you shouldn't need to provide both `packages` and `buildInputs`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
packages
is an alias for nativeBuildInputs
: https://github.com/NixOS/nixpkgs/blob/bfe04ea76ce84de0ecc00ff219867aac2f890a47/pkgs/build-support/mkshell/default.nix#L37
For example, the shell prompt format for most shells is set by the `PS1` environment variable, but `nix-shell` already overrides this by default, and will ignore a `PS1` attribute listed in `env`. | ||
|
||
If you _really_ need to override these protected environment variables you can use the `shellHook` feature discussed in the next section and `export MYVAR="value"` in the hook script. | ||
It's generally discouraged to set environment variables this way. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be called discouraged, it's very valid for secret environment variables.
A follow-up PR sounds fine, it's very small things |
Creates a tutorial to complete #516