Add two Nix/Flake examples
This commit is contained in:
parent
1353687dc2
commit
5967d1bb61
18
41-non-flake-inputs/README.md
Normal file
18
41-non-flake-inputs/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
# 41-non-flake-inputs
|
||||
|
||||
This example shows a `flake = false` input that exposes raw files instead of flake outputs.
|
||||
|
||||
It includes:
|
||||
|
||||
- one local input in `release-data/` without its own `flake.nix`,
|
||||
- one package that reads JSON from that input during evaluation, and
|
||||
- a check that proves the raw source and derived values match.
|
||||
|
||||
Useful commands:
|
||||
|
||||
```bash
|
||||
nix flake metadata
|
||||
nix build
|
||||
./result/bin/show-raw-release
|
||||
nix flake check
|
||||
```
|
||||
40
41-non-flake-inputs/flake.lock
generated
Normal file
40
41-non-flake-inputs/flake.lock
generated
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1776548001,
|
||||
"narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"releaseData": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"path": "./release-data",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"path": "./release-data",
|
||||
"type": "path"
|
||||
},
|
||||
"parent": []
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"releaseData": "releaseData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
65
41-non-flake-inputs/flake.nix
Normal file
65
41-non-flake-inputs/flake.nix
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
# Consumes a non-flake input as raw source by setting `flake = false`.
|
||||
description = "Consume a non-flake input as raw source";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
releaseData = {
|
||||
url = "path:./release-data";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs, ... }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
manifest = builtins.fromJSON (builtins.readFile "${self.inputs.releaseData}/manifest.json");
|
||||
|
||||
renderWave = wave: "${wave.stage}: ${toString wave.percentage}% owned by ${wave.owner}";
|
||||
|
||||
reportText = builtins.concatStringsSep "\n" (
|
||||
[
|
||||
"release: ${manifest.release}"
|
||||
"channel: ${manifest.channel}"
|
||||
"waves:"
|
||||
]
|
||||
++ map renderWave manifest.waves
|
||||
);
|
||||
in
|
||||
{
|
||||
packages.${system}.default = pkgs.writeShellApplication {
|
||||
name = "show-raw-release";
|
||||
text = ''
|
||||
cat <<'EOF'
|
||||
${reportText}
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
checks.${system}.release-data =
|
||||
pkgs.runCommand "non-flake-input-check"
|
||||
{
|
||||
releaseName = manifest.release;
|
||||
waveCount = toString (builtins.length manifest.waves);
|
||||
rawManifest = builtins.readFile "${self.inputs.releaseData}/manifest.json";
|
||||
}
|
||||
''
|
||||
if [ "$releaseName" != "edge-cache-2026-05" ]; then
|
||||
echo "unexpected release name: $releaseName" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$waveCount" != "2" ]; then
|
||||
echo "unexpected wave count: $waveCount" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s\n' "$rawManifest" | grep -q '"channel": "canary"'
|
||||
|
||||
echo ok > "$out"
|
||||
'';
|
||||
};
|
||||
}
|
||||
16
41-non-flake-inputs/release-data/manifest.json
Normal file
16
41-non-flake-inputs/release-data/manifest.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"release": "edge-cache-2026-05",
|
||||
"channel": "canary",
|
||||
"waves": [
|
||||
{
|
||||
"stage": "staging",
|
||||
"percentage": 20,
|
||||
"owner": "team-edge"
|
||||
},
|
||||
{
|
||||
"stage": "production",
|
||||
"percentage": 100,
|
||||
"owner": "team-edge"
|
||||
}
|
||||
]
|
||||
}
|
||||
19
42-lib-outputs/README.md
Normal file
19
42-lib-outputs/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# 42-lib-outputs
|
||||
|
||||
This example shows a `lib` output for pure reusable helpers and data.
|
||||
|
||||
It includes:
|
||||
|
||||
- one `lib` attrset with rollout data and render helpers,
|
||||
- one package that turns those helpers into a runnable report, and
|
||||
- a check that proves the exported `lib` values can be consumed through the flake output.
|
||||
|
||||
Useful commands:
|
||||
|
||||
```bash
|
||||
nix flake show
|
||||
nix eval .#lib.ownerByService.api --raw
|
||||
nix build
|
||||
./result/bin/show-lib-plan
|
||||
nix flake check
|
||||
```
|
||||
27
42-lib-outputs/flake.lock
generated
Normal file
27
42-lib-outputs/flake.lock
generated
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1776548001,
|
||||
"narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
73
42-lib-outputs/flake.nix
Normal file
73
42-lib-outputs/flake.nix
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
# Exposes a `lib` attrset for pure helper values that other outputs can reuse.
|
||||
description = "Expose reusable helpers through lib";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{ self, nixpkgs, ... }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
|
||||
playgroundLib = rec {
|
||||
rolloutPlan = [
|
||||
{
|
||||
service = "api";
|
||||
wave = 1;
|
||||
owner = "team-edge";
|
||||
}
|
||||
{
|
||||
service = "worker";
|
||||
wave = 2;
|
||||
owner = "team-batch";
|
||||
}
|
||||
];
|
||||
|
||||
ownerByService = builtins.listToAttrs (
|
||||
map (step: {
|
||||
name = step.service;
|
||||
value = step.owner;
|
||||
}) rolloutPlan
|
||||
);
|
||||
|
||||
renderStep = step: "wave ${toString step.wave}: ${step.service} owned by ${step.owner}";
|
||||
|
||||
renderPlan = builtins.concatStringsSep "\n" (map renderStep rolloutPlan);
|
||||
};
|
||||
in
|
||||
{
|
||||
lib = playgroundLib;
|
||||
|
||||
packages.${system}.default = pkgs.writeShellApplication {
|
||||
name = "show-lib-plan";
|
||||
text = ''
|
||||
cat <<'EOF'
|
||||
${self.lib.renderPlan}
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
checks.${system}.lib-output =
|
||||
pkgs.runCommand "lib-output-check"
|
||||
{
|
||||
apiOwner = self.lib.ownerByService.api;
|
||||
workerLine = self.lib.renderStep (builtins.elemAt self.lib.rolloutPlan 1);
|
||||
}
|
||||
''
|
||||
if [ "$apiOwner" != "team-edge" ]; then
|
||||
echo "unexpected api owner: $apiOwner" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$workerLine" != "wave 2: worker owned by team-batch" ]; then
|
||||
echo "unexpected worker line: $workerLine" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ok > "$out"
|
||||
'';
|
||||
};
|
||||
}
|
||||
@ -48,10 +48,11 @@ tarball+https://…/src.tar.gz
|
||||
nixpkgs # registry alias (resolves via `nix registry`)
|
||||
```
|
||||
|
||||
This repository now has focused examples for two of those cases:
|
||||
This repository now has focused examples for several of those cases:
|
||||
|
||||
- `39-flake-apps/` covers `apps.<system>` outputs, and
|
||||
- `40-path-inputs/` covers a local `path:` input.
|
||||
- `39-flake-apps/` covers `apps.<system>` outputs,
|
||||
- `40-path-inputs/` covers a local flake `path:` input, and
|
||||
- `41-non-flake-inputs/` covers a local `path:` input with `flake = false`.
|
||||
|
||||
Non-flake sources (a repo without `flake.nix`):
|
||||
|
||||
@ -60,6 +61,8 @@ inputs.some-src = { url = "github:owner/repo"; flake = false; };
|
||||
# Access raw files via self.inputs.some-src
|
||||
```
|
||||
|
||||
`41-non-flake-inputs/` shows that pattern with a local source tree and a JSON file.
|
||||
|
||||
### Outputs
|
||||
|
||||
A function: `{ self, ...inputs }: <attrset>`. The attrset keys are *conventions* the `nix` CLI knows about:
|
||||
@ -81,6 +84,9 @@ Default attrs `default` are picked when you omit the name: `nix build` ≡ `nix
|
||||
|
||||
`.<system>` is the platform triple: `x86_64-linux`, `aarch64-linux`, `aarch64-darwin`, or `x86_64-darwin`.
|
||||
|
||||
Arbitrary attrs are still allowed alongside those schema keys. `lib` is a common convention for pure helper functions and data; `42-lib-outputs/`
|
||||
shows one focused example.
|
||||
|
||||
---
|
||||
|
||||
## 2. The Lockfile
|
||||
|
||||
56
notes/044-non-flake-inputs.md
Normal file
56
notes/044-non-flake-inputs.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Non-flake Inputs
|
||||
|
||||
This note covers `41-non-flake-inputs/`, which declares `inputs.releaseData.flake = false;` so the input is consumed as raw source instead of as a flake.
|
||||
|
||||
---
|
||||
|
||||
## 1. What `flake = false` Changes
|
||||
|
||||
Normally, a flake input is expected to expose `outputs`. Setting `flake = false` tells Nix to treat the input as a plain source tree instead.
|
||||
|
||||
The example reads that source through `self.inputs.releaseData`, so it works with files directly instead of importing another flake interface.
|
||||
|
||||
---
|
||||
|
||||
## 2. Why This Example Uses a Local Path
|
||||
|
||||
The example keeps the source local with:
|
||||
|
||||
```nix
|
||||
releaseData = {
|
||||
url = "path:./release-data";
|
||||
flake = false;
|
||||
};
|
||||
```
|
||||
|
||||
That makes the boundary obvious:
|
||||
|
||||
- `release-data/` has no `flake.nix`,
|
||||
- the parent flake reads `manifest.json` directly, and
|
||||
- the package is built from values parsed out of that JSON file.
|
||||
|
||||
The same pattern works with remote GitHub sources that are not flakes. The important part is `flake = false`, not the transport.
|
||||
|
||||
---
|
||||
|
||||
## 3. What the Check Verifies
|
||||
|
||||
The check looks at both layers:
|
||||
|
||||
- parsed values such as the release name and wave count, and
|
||||
- the raw JSON text from the input path.
|
||||
|
||||
That keeps the example focused on the real distinction: a non-flake input gives you files to read, not outputs to import.
|
||||
|
||||
---
|
||||
|
||||
## 4. Commands to Try
|
||||
|
||||
```bash
|
||||
cd 41-non-flake-inputs
|
||||
|
||||
nix flake metadata
|
||||
nix build
|
||||
./result/bin/show-raw-release
|
||||
nix flake check
|
||||
```
|
||||
56
notes/045-lib-outputs.md
Normal file
56
notes/045-lib-outputs.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Lib Outputs
|
||||
|
||||
This note covers `42-lib-outputs/`, which exposes a `lib` attrset with pure data and helper functions that other outputs can reuse.
|
||||
|
||||
---
|
||||
|
||||
## 1. Why `lib` Is Useful
|
||||
|
||||
Only some output names have special meaning to the `nix` CLI. A flake can still expose arbitrary attrs for consumers.
|
||||
|
||||
`lib` is a common convention for that. It is a good place for:
|
||||
|
||||
- pure helper functions,
|
||||
- derived lookup tables, and
|
||||
- reusable domain data.
|
||||
|
||||
This example keeps the `lib` attrset small so the distinction is clear: the flake exports logic, not just build targets.
|
||||
|
||||
---
|
||||
|
||||
## 2. What the Example Exports
|
||||
|
||||
The `lib` output contains:
|
||||
|
||||
- `rolloutPlan`, a small list of pure data,
|
||||
- `ownerByService`, derived from that list, and
|
||||
- `renderStep` plus `renderPlan`, which turn the data into text.
|
||||
|
||||
The package output then prints `self.lib.renderPlan`, so the runnable artifact is built from the same exported helper values that outside consumers can evaluate.
|
||||
|
||||
---
|
||||
|
||||
## 3. Why the Check Uses `self.lib`
|
||||
|
||||
The check reaches back through the public output path:
|
||||
|
||||
```nix
|
||||
apiOwner = self.lib.ownerByService.api;
|
||||
workerLine = self.lib.renderStep (builtins.elemAt self.lib.rolloutPlan 1);
|
||||
```
|
||||
|
||||
That matters because it proves the helper data is not only local implementation detail in a `let` block. It is part of the flake interface.
|
||||
|
||||
---
|
||||
|
||||
## 4. Commands to Try
|
||||
|
||||
```bash
|
||||
cd 42-lib-outputs
|
||||
|
||||
nix flake show
|
||||
nix eval .#lib.ownerByService.api --raw
|
||||
nix build
|
||||
./result/bin/show-lib-plan
|
||||
nix flake check
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user