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

docs: update flake guides #1607

Merged
merged 2 commits into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions docs/.pages
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
nav:
- Home: index.md
- Guide:
- Getting Started: getting-started.md
- Files And Variables: files-and-variables.md
- Getting started: getting-started.md
- Files and variables: files-and-variables.md
- Writing devenv.nix:
- Basics: basics.md
- Packages: packages.md
- Scripts: scripts.md
- Tasks: tasks.md
- Languages:
- Overview: languages.md
- Supported Languages: supported-languages
- Supported languages: supported-languages
- Processes:
- Overview: processes.md
- Supported Process Managers: supported-process-managers
- Supported process managers: supported-process-managers
- Services:
- Overview: services.md
- Supported Services: supported-services
- Supported services: supported-services
- Containers: containers.md
- Binary Caching: binary-caching.md
- Git Hooks: git-hooks.md
- Binary caching: binary-caching.md
- Git hooks: git-hooks.md
- Tests: tests.md
- Outputs: outputs.md
- Common Patterns: common-patterns.md
- Common patterns: common-patterns.md
- Writing devenv.yaml:
- Inputs: inputs.md
- Imports: composing-using-imports.md
- Overview:
- Automatic Shell Activation: automatic-shell-activation.md
- Garbage Collection: garbage-collection.md
- Automatic shell activation: automatic-shell-activation.md
- Garbage collection: garbage-collection.md
- Guides: guides
- Integrations: integrations
- Tutorial: https://github.com/cachix/nixcon-2024-workshop
- Examples: examples.md
- Editor Support: editor-support
- Editor support: editor-support
- Roadmap: /blog/2024/10/22/devenv-is-switching-its-nix-implementation-to-tvix
- Reference: reference
- Blog: blog
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/.pages
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
nav:
- Using With Flakes: using-with-flakes.md
- Using With flake.parts: using-with-flake-parts.md
- Using with Flakes: using-with-flakes.md
- Using with flake.parts: using-with-flake-parts.md
121 changes: 83 additions & 38 deletions docs/guides/using-with-flake-parts.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
If you're familiar with the Nix language and ecosystem, `devenv` can be used without the `devenv` CLI by integrating into [Nix Flakes](https://www.tweag.io/blog/2020-05-25-flakes/) using [flake-parts](https://flake.parts).

Using `devenv` configuration in flakes is useful for projects that need to define other Nix flake features in addition to the development shell.
Additional flake features may include the Nix package for the project or NixOS and Home Manager modules related to the project.
Using a `devenv` configuration in flakes is useful for projects that need to define other Nix flake features in addition to the development shell.
Additional flake features may include the Nix package for the project, or NixOS and Home Manager modules related to the project.
Using the same lock file for the development shell and other features ensures that everything is based on the same `nixpkgs`.

A Nix flake needs to consist of at least the input declarations from `devenv.yaml`, as well as the `devenv` configuration that you would usually find in `devenv.nix`. `flake.lock` is the lock file for Nix flakes, the equivalent to `devenv.lock`.
A Nix flake needs to consist of at least the input declarations from `devenv.yaml`, as well as the `devenv` configuration that you would usually find in `devenv.nix`.
`flake.lock` is the lock file for Nix flakes, the equivalent of `devenv.lock`.

## Getting started

To quickly set a project up with Nix flakes, use `nix flake init`:
To quickly set up project with Nix flakes, use `nix flake init`:

```console
nix flake init --template github:cachix/devenv#flake-parts
```

This will create a `flake.nix` file with `devenv` configuration and a `.envrc` file with direnv configuration.
This will create a `flake.nix` file with a basic `devenv` configuration and a `.envrc` file for direnv support.

Open the `devenv` shell using:
## Working with flake shells

```console
nix develop --no-pure-eval
```

This will also create a lock file and open a new shell that adheres to the `devenv` configuration contained in `flake.nix`.

!!! note "Why do I need to use the `--no-pure-eval` flag?"
devenv needs to know the path to the current working directory to create and manage mutable state.
Flakes use "pure evaluation" by default, which prevents devenv from accessing external data, like the `$PWD` environment variable.
The `--no-pure-eval` flag relaxes this restriction.

## The `flake.nix` file
### The `flake.nix` file

Here's an example of a minimal `flake.nix` file that includes `devenv`:

Expand Down Expand Up @@ -68,21 +58,58 @@ Here's an example of a minimal `flake.nix` file that includes `devenv`:
}
```

Here a single shell is defined for all listed [systems](https://flake.parts/options/flake-parts.html#opt-systems). The shell includes a single `devenv` configuration module, under [`devenv.shells`](https://flake.parts/options/devenv.html#opt-perSystem.devenv.shells), named `default`.
Here a single shell is defined for all listed [systems](https://flake.parts/options/flake-parts.html#opt-systems).
The shell includes a single `devenv` configuration module, under [`devenv.shells`](https://flake.parts/options/devenv.html#opt-perSystem.devenv.shells), named `default`.

Add your `devenv` configuration (usually in the `devenv.nix` file) to this module. See [`devenv.nix` options](../reference/options.md) for more information about configuration options.
Add your `devenv` configuration (usually in the `devenv.nix` file) to this module.
See [`devenv.nix` options](../reference/options.md) for more information about configuration options.

## The direnv extension

To use direnv in your Nix flake project, you'll need [nix-direnv](https://github.com/nix-community/nix-direnv).
### Entering the shell

To configure direnv, ensure your project has a `.envrc` file that includes the following line:
Enter the `devenv` shell using:

```text
use flake . --no-pure-eval
```console
nix develop --no-pure-eval
```

This will create a lock file and open a new shell using the `devenv` configuration from your `flake.nix`.

!!! note "Why do I need to use the `--no-pure-eval` flag?"
Flakes use "pure evaluation" by default, which prevents devenv from figuring out the environment its running in: for example, querying the working directory.
The `--no-pure-eval` flag relaxes this restriction.

An alternative, and less flexible, workaround is to override the `devenv.root` option to the absolute path to your project directory.
This makes the flake non-portable between machines, but does allow the shell to be evaluated in pure mode.


### Launching processes, services, and tests

Once in the shell, you can launch [processes and services with `devenv up`](/processes).

```console
$ devenv up
17:34:37 system | run.1 started (pid=1046939)
17:34:37 run.1 | Hello, world!
17:34:37 system | run.1 stopped (rc=0)
```

And run [tests with `devenv test`](/tests).

```console
$ devenv test
Running tasks devenv:enterShell
Succeeded devenv:git-hooks:install 10ms
Succeeded devenv:enterShell 4ms
2 Succeeded 14.75ms
• Testing ...
Running tasks devenv:enterTest
Succeeded devenv:git-hooks:run 474ms
Not implemented devenv:enterTest
1 Skipped, 1 Succeeded 474.62ms
```

## Import a devenv module
### Import a devenv module

You can import a devenv configuration or module, such as `devenv-foo.nix` into an individual shell as follows.

Expand Down Expand Up @@ -141,15 +168,31 @@ in {
}
```

## Multiple shells
### Automated shell switching

You can configure your shell to launch automatically when you enter the project directory.

First, install [nix-direnv](https://github.com/nix-community/nix-direnv).

Depending on the structure of your project, you may want to define multiple development shells using flakes. We'll take a look at two use cases for multiple shells here: A single project with multiple shells and a project with an external flake.
Then add the following line to your `.envrc`:

### Single project with multiple shells
```text
use flake . --no-pure-eval
```

Allow `direnv` to evaluate the updated `.envrc`:

```console
direnv allow
```

Some projects lend themselves to defining multiple development shells. For instance, you may want to define multiple development shells for different subprojects in a monorepo. You can do this by defining the various development shells in a central `flake.nix` file in the root of the repository.
## Multiple shells

The `flake.nix` file outputs multiple [`devShells`](https://flake.parts/options/flake-parts.html#opt-flake.devShells) when you provide multiple [perSystem.devenv.shells](https://flake.parts/options/devenv.html#opt-perSystem.devenv.shells) definitions. For example:
Some projects lend themselves to defining multiple development shells. For instance, you may want to define multiple development shells for different subprojects in a monorepo.
You can do this by defining the various development shells in a central `flake.nix` file in the root of the repository.

The `flake.nix` file outputs multiple [`devShells`](https://flake.parts/options/flake-parts.html#opt-flake.devShells) when you provide multiple [perSystem.devenv.shells](https://flake.parts/options/devenv.html#opt-perSystem.devenv.shells) definitions.
For example:

```nix
# inside perSystem = { ... }: {
Expand Down Expand Up @@ -204,24 +247,26 @@ this is project A
(devenv) $
```

### Projects with an external flake
## External flakes

If you cannot or don't want to add a `flake.nix` file to your project repository, you can refer to external flakes.
If you cannot, or don't want to, add a `flake.nix` file to your project's repository, you can use external flakes instead.

You can create a repository with a `flake.nix` file as in the example above. You can now refer to this flake in a different project:
Create a separate repository with a `flake.nix` file, as in the example above. Then refer to this flake in your project:

```console
$ nix develop --no-pure-eval file:/path/to/central/flake#projectA
this is project A
(devenv) $
(devenv) $
```

You can also add this to the direnv configuration of the project. Just make sure the following line is in `.envrc`:
You can also add this to the `direnv` configuration of the project. Make sure the following line is in `.envrc`:

```text
nix flake --no-pure-eval file:/path/to/central/flake#projectA
```

Note that instead of referring to a directory on a local file system that includes the `flake.nix`, like `/path/to/central/flake`, it is also possible to use different references to a flake, for instance, `github:` or `git:`. See [Nix flake references](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references) for more information.
External flakes aren't limited to local paths using `file:`. You can refer to flakes on `github:` and generic `git:` repositories.
See [Nix flake references](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references) for more options.

When using this method to refer to external flakes, it's important to remember that there is no lock file, so there is no certainty about which version of the flake is used. A local project flake file will give you more control over which version of the flake is used.
When using this method to refer to external flakes, it's important to remember that there is no lock file, so there is no certainty about which version of the flake is used.
A local project flake file will give you more control over which version of the flake is used.
77 changes: 48 additions & 29 deletions docs/guides/using-with-flakes.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,17 @@ This template will create:
* A `flake.nix` file containing a basic devenv configuration.
* A `.envrc` file to optionally set up automatic shell activation with direnv.

Open the `devenv` shell with:
## Working with flake shells

```console
nix develop --no-pure-eval
```

This will create a `flake.lock` lock file and open a new shell based on the `devenv` configuration stated in `flake.nix`.
### The `flake.nix` file

!!! note "Why do I need to use the `--no-pure-eval` flag?"
devenv needs to know the path to the current working directory to create and manage mutable state.
Flakes use "pure evaluation" by default, which prevents devenv from accessing external data, like the `$PWD` environment variable.
The `--no-pure-eval` flag relaxes this restriction.
Setting up `devenv` inside a flake requires wiring up a few outputs.

## Modifying your `flake.nix` file
Here's a minimal `flake.nix` to start you off that includes:

Here's a minimal `flake.nix` file that includes:

* A single `devShell` for the `x86_64-linux` system created with `devenv.lib.mkShell`.
* A shell module containing the `devenv` configuration. This is what you'd usually write in `devenv.nix`.
* A `devShell` created with `devenv.lib.mkShell`.
See [the reference documentation](/reference/options/) for the possible options to use here.
* Two packages, `devenv-up` and `devenv-test`, that are needed for `devenv up` and `devenv test` to work inside the shell.

```nix
{
Expand All @@ -58,7 +49,6 @@ Here's a minimal `flake.nix` file that includes:
outputs = { self, nixpkgs, devenv, ... } @ inputs:
let
system = "x86_64-linux";

pkgs = nixpkgs.legacyPackages.${system};
in
{
Expand All @@ -84,6 +74,26 @@ Here's a minimal `flake.nix` file that includes:
}
```

### Entering the shell

Create and enter the `devenv` shell with:

```console
nix develop --no-pure-eval
```

This will evaluate the inputs to your flake, create a `flake.lock` lock file, and open a new shell using the `devenv` configuration from your `flake.nix`.

!!! note "Why do I need to use the `--no-pure-eval` flag?"
Flakes use "pure evaluation" by default, which prevents devenv from figuring out the environment its running in: for example, querying the working directory.
The `--no-pure-eval` flag relaxes this restriction.

An alternative, and less flexible, workaround is to override the `devenv.root` option to the absolute path to your project directory.
This makes the flake non-portable between machines, but does allow the shell to be evaluated in pure mode.


### Launching processes, services, and tests

Once in the shell, you can launch [processes and services with `devenv up`](/processes).

```console
Expand All @@ -94,6 +104,7 @@ $ devenv up
```

And run [tests with `devenv test`](/tests).

```console
$ devenv test
Running tasks devenv:enterShell
Expand All @@ -108,21 +119,26 @@ Not implemented devenv:enterTest
```


## Automatic shell switching with direnv
### Automated shell switching

Install [nix-direnv](https://github.com/nix-community/nix-direnv) for direnv to work with flakes.
You can configure your shell to launch automatically when you enter the project directory.

Add the following line to your `.envrc`:
First, install [nix-direnv](https://github.com/nix-community/nix-direnv).

```console
The add the following line to your `.envrc`:

```text
use flake . --no-pure-eval
```

## Multiple shells
Allow `direnv` to evaluate the updated `.envrc`:

Defining multiple development shells using flakes can be useful depending on your project's structure. We will handle two use cases here.
```console
direnv allow
```

### Single project with multiple shells

## Multiple shells

Some projects lend themselves to defining multiple development shells. For instance, you may want to define multiple development shells for different subprojects in a monorepo.
You can do this by defining the various development shells in a central `flake.nix` file in the root of the repository.
Expand All @@ -144,7 +160,10 @@ The `flake.nix` file contains multiple `devShells`. For example:
{
packages.${system} = {
projectA-devenv-up = self.devShells.${system}.projectA.config.procfileScript;
projectA-devenv-test = self.devShells.${system}.projectA.config.test;

projectB-devenv-up = self.devShells.${system}.projectB.config.procfileScript;
projectB-devenv-test = self.devShells.${system}.projectB.config.test;
};

devShells.${system} = {
Expand Down Expand Up @@ -174,7 +193,7 @@ The `flake.nix` file contains multiple `devShells`. For example:
}
```

Here we define two shells, each with a `devenv` configuration and differently defined `enterShell` command.
Here we've define two shells, each with a separate `devenv` configuration.

To enter the shell of `project A`:

Expand All @@ -192,11 +211,11 @@ this is project B
(devenv) $
```

### Projects with an external flake
## External flakes

If you cannot or don't want to add a `flake.nix` file to your project's repository, you can refer to external flakes.
If you cannot, or don't want to, add a `flake.nix` file to your project's repository, you can use external flakes instead.

You can create a repository with a `flake.nix` file as in the example above. You can now refer to this flake in a different project:
Create a separate repository with a `flake.nix` file, as in the example above. Then refer to this flake in your project:

```console
$ nix develop --no-pure-eval file:/path/to/central/flake#projectA
Expand All @@ -210,8 +229,8 @@ You can also add this to the `direnv` configuration of the project. Make sure th
nix flake --no-pure-eval file:/path/to/central/flake#projectA
```

Note that instead of referring to a directory on the local file system that includes the `flake.nix` file, like `/path/to/central/flake`, it is also possible to use different references to a flake.
For instance `github:` or `git:`. See [Nix flake references](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references) for more information.
External flakes aren't limited to local paths using `file:`. You can refer to flakes on `github:` and generic `git:` repositories.
See [Nix flake references](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html#flake-references) for more options.

When using this method to refer to external flakes, it's important to remember that there is no lock file, so there is no certainty about which version of the flake is used.
A local project flake file will give you more control over which version of the flake is used.
Loading