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

Add shell.nix tutorial #671

Merged
merged 3 commits into from
Aug 10, 2023
Merged

Add shell.nix tutorial #671

merged 3 commits into from
Aug 10, 2023

Conversation

zmitchell
Copy link
Contributor

Creates a tutorial to complete #516

Copy link
Contributor

@proofconstruction proofconstruction left a 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.

source/tutorials/learning-journey/shell-dot-nix.md Outdated Show resolved Hide resolved
PS1 = "\u@\h [myEnv] $ ";
}
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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] $ ";
'';
}

source/tutorials/learning-journey/shell-dot-nix.md Outdated Show resolved Hide resolved
Copy link
Member

@infinisil infinisil left a 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.

source/tutorials/learning-journey/shell-dot-nix.md Outdated Show resolved Hide resolved
source/tutorials/learning-journey/shell-dot-nix.md Outdated Show resolved Hide resolved
source/tutorials/learning-journey/shell-dot-nix.md Outdated Show resolved Hide resolved
source/tutorials/learning-journey/shell-dot-nix.md Outdated Show resolved Hide resolved
@nixos-discourse
Copy link

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

@zmitchell zmitchell marked this pull request as ready for review August 10, 2023 13:19
}
```


Copy link
Contributor Author

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
'';
}
```
Copy link
Contributor Author

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.

@nixos-discourse
Copy link

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 zmitchell merged commit 31f269d into NixOS:master Aug 10, 2023
1 check passed
@infinisil
Copy link
Member

@zmitchell Oh, I said in the meeting that I would like to review it again, which I was just doing right now 😅

@zmitchell
Copy link
Contributor Author

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Member

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.

@infinisil
Copy link
Member

A follow-up PR sounds fine, it's very small things

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 this pull request may close these issues.

None yet

5 participants