Skip to content

Commit 666c68e

Browse files
committed
support local overlays
1 parent f3bfbe6 commit 666c68e

File tree

5 files changed

+151
-2
lines changed

5 files changed

+151
-2
lines changed

devenv/src/flake.tmpl.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
then devenvdefaultpath
6161
else throw (devenvdefaultpath + " file does not exist for input ${name}.");
6262
project = pkgs.lib.evalModules {
63-
specialArgs = inputs // { inherit inputs pkgs; };
63+
specialArgs = inputs // { inherit inputs; bootstrapPkgs = pkgs; };
6464
modules = [
6565
(inputs.devenv.modules + /top-level.nix)
6666
{

docs/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ nav:
2121
- Binary caching: binary-caching.md
2222
- Git hooks: git-hooks.md
2323
- Tests: tests.md
24+
- Overlays: overlays.md
2425
- Outputs: outputs.md
2526
- Common patterns: common-patterns.md
2627
- Writing devenv.yaml:

docs/overlays.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Overlays
2+
3+
!!! info "New in version 1.4.2"
4+
5+
Overlays in devenv allow you to modify or extend the default package set (`pkgs`) that devenv uses. This is useful when you need to:
6+
7+
- Override existing packages to apply patches
8+
- Add new packages that aren't in the default set
9+
- Use custom builds of existing packages
10+
11+
## Using overlays
12+
13+
To add overlays to your devenv configuration, use the `overlays` option in your `devenv.nix` file:
14+
15+
```nix
16+
{ pkgs, ... }:
17+
18+
{
19+
# List of overlays to apply to pkgs
20+
overlays = [
21+
# Each overlay is a function that takes two arguments: final and prev
22+
(final: prev: {
23+
# Override an existing package
24+
hello = prev.hello.overrideAttrs (oldAttrs: {
25+
patches = (oldAttrs.patches or []) ++ [ ./hello-fix.patch ];
26+
});
27+
28+
# Add a custom package
29+
my-custom-package = final.callPackage ./my-package.nix {};
30+
})
31+
];
32+
33+
# Now you can use the modified or added packages
34+
packages = [ pkgs.hello pkgs.my-custom-package ];
35+
}
36+
```
37+
38+
## How overlays work
39+
40+
Each overlay is a function that takes two arguments:
41+
- `final`: The final package set after all overlays are applied
42+
- `prev`: The package set as it existed before this overlay (but after previous overlays)
43+
44+
The function should return an attrset containing the packages you want to add or modify. These will be merged into the final package set.
45+
46+
## Common use cases
47+
48+
### Patching existing packages
49+
50+
```nix
51+
overlays = [
52+
(final: prev: {
53+
# Apply a patch to fix a bug
54+
somePackage = prev.somePackage.overrideAttrs (oldAttrs: {
55+
patches = (oldAttrs.patches or []) ++ [ ./my-fix.patch ];
56+
});
57+
})
58+
];
59+
```
60+
61+
### Using a different version of a package
62+
63+
```nix
64+
overlays = [
65+
(final: prev: {
66+
# Use a specific version of Node.js
67+
nodejs = prev.nodejs-18_x;
68+
})
69+
];
70+
```
71+
72+
### Adding custom packages
73+
74+
```nix
75+
overlays = [
76+
(final: prev: {
77+
# Add a package from a local derivation
78+
my-tool = final.callPackage ./nix/my-tool.nix {};
79+
})
80+
];
81+
```
82+
83+
### Using packages from older nixpkgs
84+
85+
First, add the extra input to your `devenv.yaml`:
86+
87+
```yaml
88+
inputs:
89+
nixpkgs:
90+
url: github:cachix/devenv-nixpkgs/rolling
91+
nixpkgs-unstable:
92+
url: github:nixos/nixpkgs/nixpkgs-unstable
93+
```
94+
95+
Then use it in your `devenv.nix`:
96+
97+
```nix
98+
{ pkgs, inputs, ... }:
99+
100+
{
101+
overlays = [
102+
(final: prev: {
103+
# Use a package from nixpkgs-unstable
104+
nodejs = (import inputs.nixpkgs-unstable {
105+
system = prev.stdenv.system;
106+
}).nodejs;
107+
})
108+
];
109+
110+
# Now you can use these packages from your regular pkgs
111+
languages.javascript.enable = true;
112+
}
113+
```

examples/overlays/devenv.nix

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,16 @@
88
# from subflake
99
pkgs.hello2
1010
];
11+
12+
overlays = [
13+
(final: prev: {
14+
hello = prev.hello.overrideAttrs (old: {
15+
name = "hello-2.0.0";
16+
});
17+
})
18+
];
19+
20+
enterTest = ''
21+
which hello | grep "2.0.0"
22+
'';
1123
}

src/modules/top-level.nix

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{ config, pkgs, lib, ... }:
1+
{ config, pkgs, lib, bootstrapPkgs ? null, ... }:
22
let
33
types = lib.types;
44
# Returns a list of all the entries in a folder
@@ -60,6 +60,21 @@ in
6060
default = "";
6161
};
6262

63+
overlays = lib.mkOption {
64+
type = types.listOf (types.functionTo (types.functionTo types.attrs));
65+
description = "List of overlays to apply to pkgs. Each overlay is a function that takes two arguments: final and prev. Supported by devenv 1.4.2 or newer.";
66+
default = [ ];
67+
example = lib.literalExpression ''
68+
[
69+
(final: prev: {
70+
hello = prev.hello.overrideAttrs (oldAttrs: {
71+
patches = (oldAttrs.patches or []) ++ [ ./hello-fix.patch ];
72+
});
73+
})
74+
]
75+
'';
76+
};
77+
6378
packages = lib.mkOption {
6479
type = types.listOf types.package;
6580
description = "A list of packages to expose inside the developer environment. Search available packages using ``devenv search NAME``.";
@@ -243,6 +258,12 @@ in
243258
See https://devenv.sh/guides/using-with-flakes/ how to use it with flakes.
244259
'';
245260
}
261+
{
262+
assertion = config.devenv.flakesIntegration || config.overlays == [ ] || lib.versionAtLeast config.devenv.cliVersion "1.4.2";
263+
message = ''
264+
Using overlays requires devenv 1.4.2 or higher, while your current version is ${config.devenv.cliVersion}.
265+
'';
266+
}
246267
];
247268
# use builtins.toPath to normalize path if root is "/" (container)
248269
devenv.state = builtins.toPath (config.devenv.dotfile + "/state");
@@ -312,6 +333,8 @@ in
312333
infoSections."env" = lib.mapAttrsToList (name: value: "${name}: ${toString value}") config.env;
313334
infoSections."packages" = builtins.map (package: package.name) (builtins.filter (package: !(builtins.elem package.name (builtins.attrNames config.scripts))) config.packages);
314335

336+
_module.args.pkgs = bootstrapPkgs.appendOverlays config.overlays;
337+
315338
ci = [ config.shell ];
316339
ciDerivation = pkgs.runCommand "ci" { } "echo ${toString config.ci} > $out";
317340
};

0 commit comments

Comments
 (0)