Skip to content

Commit dc9954a

Browse files
committed
feat(v1 API): document v1 API examples
1 parent f47ce48 commit dc9954a

File tree

12 files changed

+758
-0
lines changed

12 files changed

+758
-0
lines changed

docs/src/SUMMARY.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,16 @@
3131
# Development Roundups
3232
- [April - June 2022](./development-roundups/2022-april-june.md)
3333
- [July - September 2022](./development-roundups/2022-july-september.md)
34+
35+
# WIP
36+
- [v1 API](./v1-api/summary.md)
37+
- [problems of the current dream2nix](./v1-api/problems.md)
38+
- [users of dream2nix](./v1-api/users.md)
39+
- [v1 packaging: project initialization](./v1-api/packaging/nodejs-init-project.md)
40+
- [v1 packaging: workspaces](./v1-api/packaging/nodejs-workspaces.md)
41+
- [v1 packaging: multiple repos](./v1-api/packaging/nodejs-multiple-repos.md)
42+
- [v1 packaging: monorepo](./v1-api/packaging/monorepo.md)
43+
- [v1 consuming: inspect package options](./v1-api/consuming/inspect-options.md)
44+
- [v1 consuming: override packages](./v1-api/consuming/override.md)
45+
- [v1 integrating: lang2nix tool (pure)](./v1-api/integrating/integrate-lang2nix-pure.md)
46+
- [v1 integrating: lang2nix tool (code-gen/impure)](./v1-api/integrating/integrate-lang2nix-impure.md)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Inspect the API of a package
2+
Downstream users can inspect the api of any consumed package as well as raw package modules
3+
4+
## Load the dream2nix shell
5+
```shell
6+
nix-shell https://dream2nix.dev -A devShells.default
7+
```
8+
9+
## Get manual of package module
10+
Assuming a package module in `./upstream/my-package.nix`
11+
12+
```shell
13+
$ dream2nix man ./upstream/my-package.nix
14+
```
15+
16+
## Get manual of derivation
17+
Assuming derivations defined via `./upstream/default.nix`
18+
19+
```shell
20+
dream2nix man ./upstream/default.nix -A packages.my-package
21+
```
22+
23+
## Get manual of flake attribute
24+
Assuming derivations defined via a flake on github
25+
26+
```shell
27+
dream2nix man github:user/repo#some-package
28+
```

docs/src/v1-api/consuming/override.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Consume and modify dream2nix packages
2+
3+
## Given the following package
4+
`upstream/my-package.nix`
5+
```nix
6+
{config, lib, dream2nix, ...}: {
7+
8+
imports = [
9+
dream2nix.modules.nodejs.mkDerivation
10+
dream2nix.modules.nodejs.package-lock
11+
];
12+
13+
pname = "my-package";
14+
version = "2.0.0";
15+
16+
src = {
17+
type = github;
18+
owner = "my-user";
19+
repo = "my-repo";
20+
ref = config.version;
21+
hash = "sha256-mia90VYv/YTdWNhKpvwvFW9RfbXZJSWhJ+yva6EnLE8=";
22+
};
23+
24+
# declare dependency on python3
25+
deps = {nixpkgs, ...}: {
26+
python3 = nixpkgs.python39;
27+
};
28+
29+
nativeBuildInputs = [
30+
config.deps.python3
31+
];
32+
33+
configurePhase = ''
34+
python3 --version
35+
'';
36+
37+
buildPhase = ''
38+
python3 -c 'print("Hello World!")' > $out
39+
'';
40+
}
41+
```
42+
43+
`upstream/default.nix`
44+
```nix
45+
{
46+
nixpkgs ? import <nixpkgs> {},
47+
dream2nix ?
48+
import
49+
(builtins.fetchTarball "https://dream2nix.dev/tarball/1.0")
50+
{inherit nixpkgs;},
51+
}: {
52+
packages.my-package = dream2nix.eval ./my-package.nix;
53+
}
54+
```
55+
56+
## 1. Override using modules
57+
58+
### 1.1 Define a module for the override
59+
`my-package-override.nix`
60+
```nix
61+
{config, lib, ... }: {
62+
63+
version = "2.1.0";
64+
65+
# No need to re-define other fetcher attributes.
66+
# The module system updates them for us.
67+
src.hash = "sha256-LM5GDNjLcmgZVQEeANWAOO09KppwGaYEzJBjYmuSwys=";
68+
69+
deps = {nixpkgs, ...}: {
70+
71+
# change the python version
72+
python3 = lib.mkForce nixpkgs.python310;
73+
74+
# add a dependency on hello
75+
hello = nixpkgs.hello;
76+
};
77+
78+
# add hello to nativeBuildInputs
79+
# (`oldAttrs.nativeBuildInputs + ...` not needed here)
80+
nativeBuildInputs = [
81+
config.deps.hello
82+
];
83+
84+
# add lines to configurePhase
85+
postConfigure = ''
86+
hello --version
87+
'';
88+
89+
# replace the build phase via mkForce
90+
buildPhase = lib.mkForce "
91+
hello > $out
92+
";
93+
}
94+
```
95+
96+
### 1.2 Apply `my-package-override.nix` via extendModules
97+
Using `extendModules` is simple.
98+
It allows to extend an existing package with another module.
99+
This doesn't require knowledge about the original modules that went into the package.
100+
101+
`./default.nix`
102+
```nix
103+
let
104+
nixpkgs = import <nixpkgs> {};
105+
upstream = import ./upstream {inherit nixpkgs;};
106+
my-package = upstream.packages.my-package;
107+
108+
# The recommended way of modifying a package is using extendModules,
109+
# which uses the module systems merge logic to apply changes.
110+
my-package-extended = my-package.extendModules {
111+
modules = [./my-package-override.nix];
112+
};
113+
114+
in {
115+
inherit my-package-extended;
116+
}
117+
```
118+
119+
### 1.3 Or apply `my-package-override.nix` via dream2nix.eval
120+
This approach is a bit cleaner.
121+
It doesn't introduce a chain of extendModules function calls.
122+
This style also makes it obvious which modules went into the package.
123+
Though, this requires access to the original `my-package.nix` module and knowledge about the `packageSets` that went into it.
124+
125+
`default.nix`
126+
```nix
127+
{
128+
nixpkgs ? import <nixpkgs> {},
129+
dream2nix ?
130+
import
131+
(builtins.fetchTarball "https://dream2nix.dev/tarball/1.0")
132+
{inherit nixpkgs;},
133+
134+
}: let
135+
136+
my-package-extended = dream2nix.eval
137+
{packagetSets = {inherit nixpkgs;};}
138+
[
139+
./upstream/my-package.nix
140+
./my-package-override.nix
141+
];
142+
143+
in {
144+
my-package-extended
145+
}
146+
```
147+
148+
149+
## 2. Override package via `override[Attrs]` functions
150+
151+
It is recommended to use modules for overriding, like described above, but for backward compatibility, `overrideAttrs` and `override` are still supported.
152+
153+
```nix
154+
let
155+
nixpkgs = import <nixpkgs> {};
156+
upstream = import ./upstream {inherit nixpkgs;};
157+
my-package = upstream.packages.my-package;
158+
159+
# Override the package via `override` and `overrideAttrs`
160+
my-package-overridden' = my-package.override
161+
(oldAttrs: {
162+
163+
# change the python version
164+
python3 = nixpkgs.python310;
165+
});
166+
167+
my-package-overridden = my-package-overridden'.overrideAttrs
168+
(oldAttrs: rec {
169+
170+
version = "2.1.0";
171+
172+
src = nixpkgs.fetchFromGithub {
173+
owner = "my-owner";
174+
repo = "my-repo";
175+
ref = version;
176+
hash = "sha256-LM5GDNjLcmgZVQEeANWAOO09KppwGaYEzJBjYmuSwys=";
177+
};
178+
179+
# add hello to nativeBuildInputs
180+
nativeBuildInputs = [
181+
nixpkgs.hello
182+
];
183+
184+
# add lines to configurePhase
185+
postConfigure = ''
186+
hello --version
187+
'';
188+
189+
# replace the build phase
190+
buildPhase = ''
191+
hello > $out
192+
'';
193+
});
194+
195+
in {
196+
inherit my-package-overridden;
197+
}
198+
```
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Integrate lang2nix tool (impure/code-gen)
2+
3+
We use [gomod2nix](https://github.com/nix-community/gomod2nix) as an example here to demonstrate creating a dream2nix integration.
4+
5+
Gomod2nix is a nix code generator that requires network access, a great example for an impure dream2nix integration.
6+
7+
`dream2nix/modules/go.gomod2nix.nix`
8+
```nix
9+
{config, lib, dream2nix, system, ...}: rec {
10+
11+
imports = [
12+
13+
# import generic mkDerivation interface, which will add options like:
14+
# - buildInputs
15+
# - nativeBuildInputs
16+
# - ...
17+
dream2nix.modules.mkDerivation-interfaces
18+
19+
# Generic interface for impure lang2nix tools (code generators)
20+
# This provides options like `generateBin` (see below)
21+
dream2nix.modules.integrations.impure
22+
];
23+
24+
options = {
25+
modules = lib.mkOption {
26+
description = "The path to the gomod2nix.toml";
27+
type = lib.types.str;
28+
default = "${config.dream2nix.artifactsLocation}/gomod2nix.toml" ;
29+
};
30+
31+
};
32+
33+
config = {
34+
# Generated code will end up in:
35+
# {repo}/dream2nix/artifacts/{engineName}/{package_identifier}
36+
dream2nix.engineName = "gomod2nix";
37+
38+
# An executable that generates nix code for the given `src`
39+
dream2nix.generateBin = dream2nix.utils.writePureShellScript "gomod2nix-generate.sh"
40+
[
41+
# add gomod2nix tool to PATH
42+
dream2nix.inputs.gomod2nix.packages.${system}.gomod2nix
43+
]
44+
''
45+
targetDir=$1
46+
gomod2nix --dir "${config.src}" --outdir "$targetDir"
47+
'';
48+
49+
# signal that all options should be passed to the final derivation function
50+
argsForward = l.mapAttrs (_: _: true) options;
51+
52+
# the final derivation is built by calling gomod2nix.buildGoApplication
53+
config.final.derivation =
54+
dream2nix.inputs.gomod2nix.lib.${system}.buildGoApplication
55+
config.final.derivation-args;
56+
};
57+
}
58+
```
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Integrate lang2nix tool (pure)
2+
We use [crane](https://crane.dev) as an example here to demonstrate creating a dream2nix integration
3+
4+
`dream2nix/modules/rust.crane-buildPackage.nix`
5+
```nix
6+
{config, lib, dream2nix, system, ...}: rec {
7+
8+
imports = [
9+
# import generic mkDerivation interface, which will add options like:
10+
# - buildInputs
11+
# - nativeBuildInputs
12+
# - ...
13+
dream2nix.modules.mkDerivation-interfaces
14+
];
15+
16+
options = {
17+
buildPhaseCargoCommand = lib.mkOption {
18+
description = "A command to run during the derivation's build phase. Pre and post build hooks will automatically be run.";
19+
type = lib.types.nullOr lib.types.str;
20+
default = null;
21+
};
22+
cargoArtifacts = lib.mkOption {
23+
description = "A path (or derivation) which contains an existing cargo target directory, which will be reused at the start of the derivation. Useful for caching incremental cargo builds.";
24+
type = lib.types.nullOr lib.types.str;
25+
default = null;
26+
};
27+
cargoBuildCommand = lib.mkOption {
28+
description = "A cargo invocation to run during the derivation's build phase";
29+
type = lib.types.nullOr lib.types.str;
30+
default = null;
31+
}
32+
33+
# ... more options of crane's buildPackage
34+
};
35+
36+
config = {
37+
# signal that all options should be passed to the final derivation function
38+
argsForward = l.mapAttrs (_: _: true) options;
39+
40+
# the final derivation is built by calling crane.buildPackage
41+
config.final.derivation =
42+
dream2nix.inputs.crane.lib.${system}.buildPackage
43+
config.final.derivation-args;
44+
};
45+
}
46+
```

0 commit comments

Comments
 (0)