mirror of
https://gitlab.com/rensa-nix/core.git
synced 2026-02-02 07:15:08 +01:00
Compare commits
9 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5f47b57ae | |||
| 9bbb923a35 | |||
| c8ae0ceb2e | |||
| 2aaf40e5f3 | |||
| 1d63c19f2a | |||
| e6c13290bb | |||
| 50d96d43ce | |||
| 761cf28ced | |||
|
|
50c71a2278 |
22 changed files with 628 additions and 67 deletions
|
|
@ -3,8 +3,19 @@
|
|||
in
|
||||
cilib.mkCI {
|
||||
pipelines."default" = {
|
||||
stages = ["build" "deploy"];
|
||||
stages = ["test" "build" "deploy"];
|
||||
jobs = {
|
||||
"test:lib" = {
|
||||
stage = "test";
|
||||
script = [
|
||||
"nix run .#tests -- --junit=junit.xml"
|
||||
];
|
||||
allow_failure = true;
|
||||
artifacts = {
|
||||
when = "always";
|
||||
reports.junit = "junit.xml";
|
||||
};
|
||||
};
|
||||
"docs" = {
|
||||
stage = "build";
|
||||
script = [
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ in
|
|||
{"API Reference" = "api.md";}
|
||||
{"Related Libraries" = "libraries.md";}
|
||||
{"Direnv Integration" = "direnv.md";}
|
||||
{"Debugging" = "debugging.md";}
|
||||
];
|
||||
markdown_extensions = [
|
||||
{
|
||||
|
|
|
|||
43
cells/repo/flake.lock
generated
43
cells/repo/flake.lock
generated
|
|
@ -3,11 +3,11 @@
|
|||
"devshell": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1758204313,
|
||||
"narHash": "sha256-ainbY0Oajb1HMdvy+A8QxF/P5qwcbEzJGEY5pzKdDdc=",
|
||||
"lastModified": 1767218348,
|
||||
"narHash": "sha256-8MJqwH9sRMuHH+RsB7iqWyWD30TgmpiYKEvegAULggs=",
|
||||
"owner": "rensa-nix",
|
||||
"repo": "devshell",
|
||||
"rev": "7d0c4bc78d9f017a739b0c7eb2f4e563118353e6",
|
||||
"rev": "7a9b7e5d9f162a1fa3edfdc0169cdc29d3a67f8e",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -20,11 +20,11 @@
|
|||
"devtools-lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1766237846,
|
||||
"narHash": "sha256-7n3WFabnf49SFHXD/e4zfLit3BniZZOecUXfBm3d1d0=",
|
||||
"lastModified": 1767214272,
|
||||
"narHash": "sha256-gvW7flZ60xdv3Z3Ksec5jcRjW2sqRHsGoJdwsNWQVPk=",
|
||||
"owner": "rensa-nix",
|
||||
"repo": "devtools",
|
||||
"rev": "5c8712f48c5bcb6b79d3da1afd1268f84f5e35e3",
|
||||
"rev": "f40e59c32c48cdbf4cbc621c2f0f11e7bb80dbd3",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -55,11 +55,11 @@
|
|||
"nixmkdocs": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1766062227,
|
||||
"narHash": "sha256-jhr5CUi9eDeMIAJn7ayXP8Wr+Y2loV5EhdDIKDkRIdw=",
|
||||
"lastModified": 1766404754,
|
||||
"narHash": "sha256-EjBe6x6BT8ckPirMWhSf1GfaFxORYxR/Uu71FvSAm60=",
|
||||
"owner": "TECHNOFAB",
|
||||
"repo": "nixmkdocs",
|
||||
"rev": "cb0bb5dc3382e8ba5d81324a2f1fd94ccd5a5df4",
|
||||
"rev": "cfa9606eeeb9288e2799896d7d42b3d3860f9ccb",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -69,12 +69,31 @@
|
|||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"nixtest-lib": {
|
||||
"locked": {
|
||||
"dir": "lib",
|
||||
"lastModified": 1765728058,
|
||||
"narHash": "sha256-V3FXECl1oTxEtGteNz3o3GJs/X8asSn1TxRpZ2F+htU=",
|
||||
"owner": "TECHNOFAB",
|
||||
"repo": "nixtest",
|
||||
"rev": "2477ad31ae3aa4134e1bb5eeddbebe0cb64ccb57",
|
||||
"type": "gitlab"
|
||||
},
|
||||
"original": {
|
||||
"dir": "lib",
|
||||
"owner": "TECHNOFAB",
|
||||
"ref": "v1.2.1",
|
||||
"repo": "nixtest",
|
||||
"type": "gitlab"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devshell": "devshell",
|
||||
"devtools-lib": "devtools-lib",
|
||||
"nix-gitlab-ci-lib": "nix-gitlab-ci-lib",
|
||||
"nixmkdocs": "nixmkdocs",
|
||||
"nixtest-lib": "nixtest-lib",
|
||||
"soonix-lib": "soonix-lib",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
|
|
@ -99,11 +118,11 @@
|
|||
"treefmt-nix": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1766000401,
|
||||
"narHash": "sha256-+cqN4PJz9y0JQXfAK5J1drd0U05D5fcAGhzhfVrDlsI=",
|
||||
"lastModified": 1767122417,
|
||||
"narHash": "sha256-yOt/FTB7oSEKQH9EZMFMeuldK1HGpQs2eAzdS9hNS/o=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "42d96e75aa56a3f70cab7e7dc4a32868db28e8fd",
|
||||
"rev": "dec15f37015ac2e774c84d0952d57fcdf169b54d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
soonix-lib.url = "gitlab:TECHNOFAB/soonix?dir=lib";
|
||||
nix-gitlab-ci-lib.url = "gitlab:TECHNOFAB/nix-gitlab-ci/3.1.2?dir=lib";
|
||||
devtools-lib.url = "gitlab:rensa-nix/devtools?dir=lib";
|
||||
nixtest-lib.url = "gitlab:TECHNOFAB/nixtest/v1.2.1?dir=lib";
|
||||
treefmt-nix = {
|
||||
url = "github:numtide/treefmt-nix";
|
||||
flake = false;
|
||||
|
|
@ -18,6 +19,8 @@
|
|||
doclib = i.nixmkdocs.lib {inherit (i.parent) pkgs;};
|
||||
soonix = i.soonix-lib.lib {inherit (i.parent) pkgs;};
|
||||
cilib = i.nix-gitlab-ci-lib.lib {inherit (i.parent) pkgs;};
|
||||
ntlib = i.nixtest-lib.lib {inherit (i.parent) pkgs;};
|
||||
rensa = import "${i.parent.self}/lib" {inherit (i.parent.pkgs) lib;};
|
||||
treefmt = import i.treefmt-nix;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
10
cells/repo/tests.nix
Normal file
10
cells/repo/tests.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{inputs, ...}: let
|
||||
inherit (inputs) pkgs ntlib rensa;
|
||||
in {
|
||||
tests = ntlib.mkNixtest {
|
||||
modules = ntlib.autodiscover {dir = "${inputs.self}/tests";};
|
||||
args = {
|
||||
inherit pkgs ntlib rensa;
|
||||
};
|
||||
};
|
||||
}
|
||||
43
docs/api.md
43
docs/api.md
|
|
@ -8,7 +8,7 @@ The main entry point for creating a Rensa flake.
|
|||
|
||||
- `inputs`: The flake inputs.
|
||||
- `cellsFrom`: Path to the directory containing your cells.
|
||||
- `cellBlocks`: A list of blocks to load for each cell.
|
||||
- `cellBlocks`: A list of blocks to load for each cell. Defaults to `[rensa.blocks.autodiscover]`.
|
||||
- `transformInputs` (optional): A function to transform inputs before they are passed to cells.
|
||||
|
||||
### Returns
|
||||
|
|
@ -23,7 +23,7 @@ The underlying builder function used by `buildWith`. It returns the raw Rensa ou
|
|||
|
||||
- `inputs`: The flake inputs.
|
||||
- `cellsFrom`: Path to the directory containing your cells.
|
||||
- `cellBlocks`: A list of blocks to load for each cell.
|
||||
- `cellBlocks`: A list of blocks to load for each cell. Defaults to `[rensa.blocks.autodiscover]`.
|
||||
- `transformInputs` (optional): A function to transform inputs.
|
||||
|
||||
### Returns
|
||||
|
|
@ -56,6 +56,45 @@ by passing through actions etc. from a cell.
|
|||
|
||||
Currently not really used.
|
||||
|
||||
### `autodiscover`
|
||||
|
||||
```nix
|
||||
autodiscover
|
||||
# or
|
||||
(autodiscover "cellName")
|
||||
```
|
||||
|
||||
Automatically discovers and loads all cell blocks by scanning the cells directory for `.nix` files.
|
||||
When `autodiscover` is present in `cellBlocks`, Rensa will:
|
||||
|
||||
1. Walk through all cells in `cellsFrom` (or specific cell if provided).
|
||||
1. Find all `.nix` files (excluding `flake.nix`).
|
||||
1. Find all directories containing `default.nix`.
|
||||
1. Generate `simple` block definitions for each discovered block.
|
||||
|
||||
**Usage patterns:**
|
||||
|
||||
```nix
|
||||
# full autodiscovery
|
||||
cellBlocks = with rensa.blocks; [
|
||||
autodiscover
|
||||
];
|
||||
# or
|
||||
cellBlocks = with rensa.blocks; [
|
||||
(autodiscover "backend") # only discover blocks from backend cell
|
||||
(autodiscover "frontend") # only discover blocks from frontend cell
|
||||
];
|
||||
# mixed
|
||||
cellBlocks = with rensa.blocks; [
|
||||
(simple "myBlock") # explicit block (takes precedence)
|
||||
autodiscover # discover all others
|
||||
];
|
||||
```
|
||||
|
||||
!!! note
|
||||
|
||||
When a block is both explicitly defined and discovered, the explicit definition takes precedence.
|
||||
|
||||
## `rensa.select`
|
||||
|
||||
Helper to select specific outputs from the generated flake.
|
||||
|
|
|
|||
38
docs/debugging.md
Normal file
38
docs/debugging.md
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Debugging
|
||||
|
||||
## Error Context
|
||||
|
||||
To help with debugging, Rensa uses Nix's `builtins.addErrorContext` to add context
|
||||
about where an error is happening.
|
||||
|
||||
Use the following command to get just these logs from Rensa and please include that (or the whole stacktrace) in any issues or bug reports :)
|
||||
|
||||
```sh
|
||||
nix ... --show-trace 2> >(grep "… \[ren\]")
|
||||
```
|
||||
|
||||
## Trace Verbose
|
||||
|
||||
There are also some `traceVerbose` calls in Rensa, so to debug non-failing executions
|
||||
just run Nix with the `--trace-verbose` flag.
|
||||
|
||||
The output could look like this (example with this repo's flake):
|
||||
|
||||
```sh
|
||||
trace: [ren] loading cell block ci, type ci, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-darwin
|
||||
trace: [ren] loading cell block devShells, type devShells, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-darwin
|
||||
trace: [ren] loading cell block docs, type docs, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-darwin
|
||||
trace: [ren] loading cell block soonix, type soonix, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-darwin
|
||||
trace: [ren] loading cell block ci, type ci, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-linux
|
||||
trace: [ren] loading cell block devShells, type devShells, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-linux
|
||||
trace: [ren] loading cell block docs, type docs, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-linux
|
||||
trace: [ren] loading cell block soonix, type soonix, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system aarch64-linux
|
||||
trace: [ren] loading cell block ci, type ci, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-darwin
|
||||
trace: [ren] loading cell block devShells, type devShells, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-darwin
|
||||
trace: [ren] loading cell block docs, type docs, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-darwin
|
||||
trace: [ren] loading cell block soonix, type soonix, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-darwin
|
||||
trace: [ren] loading cell block ci, type ci, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-linux
|
||||
trace: [ren] loading cell block devShells, type devShells, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-linux
|
||||
trace: [ren] loading cell block docs, type docs, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-linux
|
||||
trace: [ren] loading cell block soonix, type soonix, from cell /nix/store/7acz6q9360fkg0x187yx43d1vwpv850l-cells/repo, for system x86_64-linux
|
||||
```
|
||||
12
flake.lock
generated
12
flake.lock
generated
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1766125104,
|
||||
"narHash": "sha256-l/YGrEpLromL4viUo5GmFH3K5M1j0Mb9O+LiaeCPWEM=",
|
||||
"lastModified": 1767151656,
|
||||
"narHash": "sha256-ujL2AoYBnJBN262HD95yer7QYUmYp5kFZGYbyCCKxq8=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7d853e518814cca2a657b72eeba67ae20ebf7059",
|
||||
"rev": "f665af0cdb70ed27e1bd8f9fdfecaf451260fc55",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -18,11 +18,11 @@
|
|||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1765674936,
|
||||
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
||||
"lastModified": 1766884708,
|
||||
"narHash": "sha256-x8nyRwtD0HMeYtX60xuIuZJbwwoI7/UKAdCiATnQNz0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
||||
"rev": "15177f81ad356040b4460a676838154cbf7f6213",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@
|
|||
(simple "docs")
|
||||
(simple "ci")
|
||||
(simple "soonix")
|
||||
(simple "tests")
|
||||
];
|
||||
} {
|
||||
packages = rensa.select inputs.self [
|
||||
["repo" "docs"]
|
||||
["repo" "ci" "packages"]
|
||||
["repo" "soonix" "packages"]
|
||||
["repo" "tests"]
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,17 @@
|
|||
dynamic = name: {
|
||||
inherit name;
|
||||
type = name;
|
||||
cli = true;
|
||||
actions = args: {};
|
||||
# TODO: dynamic actions
|
||||
};
|
||||
autodiscover = {
|
||||
name = "__autodiscover";
|
||||
type = "__autodiscover";
|
||||
_functor = self: cell:
|
||||
self
|
||||
// {
|
||||
inherit cell;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
98
lib/core/autodiscover.nix
Normal file
98
lib/core/autodiscover.nix
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
l,
|
||||
cellsFrom,
|
||||
cellBlocks,
|
||||
}: let
|
||||
# find autodiscover blocks
|
||||
autodiscoverBlocks = l.filter (block: block.name or "" == "__autodiscover") cellBlocks;
|
||||
explicitBlocks = l.filter (block: block.name or "" != "__autodiscover") cellBlocks;
|
||||
hasAutodiscover = (l.length autodiscoverBlocks) > 0;
|
||||
|
||||
# discover all block names from a single cell's directory
|
||||
discoverBlocksFromCell = cellPath: let
|
||||
cellContents = l.readDir cellPath;
|
||||
# filter for .nix files (but not flake.nix) and dirs with default.nix
|
||||
blockNames = l.unique (
|
||||
l.filter (name: name != null) (
|
||||
l.mapAttrsToList (
|
||||
name: type:
|
||||
if type == "regular" && l.hasSuffix ".nix" name && name != "flake.nix"
|
||||
then l.removeSuffix ".nix" name
|
||||
else if type == "directory" && l.pathExists (cellPath + "/${name}/default.nix")
|
||||
then name
|
||||
else null
|
||||
)
|
||||
cellContents
|
||||
)
|
||||
);
|
||||
in
|
||||
builtins.addErrorContext "[ren] while discovering blocks from cell ${cellPath}"
|
||||
blockNames;
|
||||
|
||||
# discover all blocks from all cells or specific cells
|
||||
discoverAllBlocks = let
|
||||
# check if any autodiscover blocks have cell-specific targets (eg. `autodiscover "a"`)
|
||||
cellSpecificDiscoveries = l.filter (block: block ? cell) autodiscoverBlocks;
|
||||
globalDiscoveries = l.filter (block: !(block ? cell)) autodiscoverBlocks;
|
||||
|
||||
cellSpecificBlocks = l.flatten (
|
||||
l.map (
|
||||
block: let
|
||||
cellPath = cellsFrom + "/${block.cell}";
|
||||
in
|
||||
if l.pathExists cellPath
|
||||
then discoverBlocksFromCell cellPath
|
||||
else []
|
||||
)
|
||||
cellSpecificDiscoveries
|
||||
);
|
||||
|
||||
# global autodiscover
|
||||
globalBlocks = builtins.addErrorContext "[ren] while discovering global blocks" (
|
||||
if (l.length globalDiscoveries) > 0
|
||||
then let
|
||||
cells = l.readDir cellsFrom;
|
||||
allBlockNames = l.unique (
|
||||
l.flatten (
|
||||
l.mapAttrsToList (
|
||||
cellName: cellType:
|
||||
if cellType == "directory"
|
||||
then discoverBlocksFromCell (cellsFrom + "/${cellName}")
|
||||
else []
|
||||
)
|
||||
cells
|
||||
)
|
||||
);
|
||||
in
|
||||
allBlockNames
|
||||
else []
|
||||
);
|
||||
|
||||
allBlockNames = l.unique (cellSpecificBlocks ++ globalBlocks);
|
||||
in
|
||||
builtins.addErrorContext "[ren] while discovering all blocks"
|
||||
l.map (name: {
|
||||
inherit name;
|
||||
type = name;
|
||||
})
|
||||
allBlockNames;
|
||||
|
||||
discoveredBlocks =
|
||||
if hasAutodiscover
|
||||
then discoverAllBlocks
|
||||
else [];
|
||||
|
||||
# merge the explicit and autodiscovered blocks (explicit taking precedence)
|
||||
allBlocks = explicitBlocks ++ discoveredBlocks;
|
||||
uniqueBlocks =
|
||||
l.foldl' (
|
||||
acc: block:
|
||||
# first occurence of name wins
|
||||
if l.any (b: b.name == block.name) acc
|
||||
then acc
|
||||
else acc ++ [block]
|
||||
) []
|
||||
allBlocks;
|
||||
in
|
||||
builtins.addErrorContext "[ren] while autodiscovering cell blocks"
|
||||
uniqueBlocks
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
l,
|
||||
utils,
|
||||
loader,
|
||||
autodiscover,
|
||||
blocks,
|
||||
}: let
|
||||
inherit (utils) accumulate;
|
||||
inherit (loader) createCellLoader;
|
||||
|
|
@ -9,7 +11,7 @@
|
|||
build = {
|
||||
inputs,
|
||||
cellsFrom,
|
||||
cellBlocks,
|
||||
cellBlocks ? [blocks.autodiscover],
|
||||
transformInputs ? system: i: i,
|
||||
...
|
||||
} @ args: let
|
||||
|
|
@ -28,26 +30,31 @@
|
|||
]
|
||||
);
|
||||
|
||||
cellBlocks' = autodiscover {inherit l cellsFrom cellBlocks;};
|
||||
|
||||
cells = res.output;
|
||||
|
||||
loadOutputFor = system: let
|
||||
loadCell = createCellLoader {
|
||||
inherit inputs system cells cellsFrom cellBlocks transformInputs;
|
||||
inherit inputs system cells cellsFrom transformInputs;
|
||||
cellBlocks = cellBlocks';
|
||||
};
|
||||
|
||||
cells' = l.mapAttrsToList (cell: type: cell) (l.readDir cellsFrom);
|
||||
res = accumulate (l.map loadCell cells');
|
||||
in [
|
||||
{${system} = res.output;}
|
||||
{${system} = res.actions;}
|
||||
{
|
||||
name = system;
|
||||
value = res.init;
|
||||
}
|
||||
];
|
||||
in
|
||||
builtins.addErrorContext "[ren] while loading output for ${system}" [
|
||||
{${system} = res.output;}
|
||||
{${system} = res.actions;}
|
||||
{
|
||||
name = system;
|
||||
value = res.init;
|
||||
}
|
||||
];
|
||||
|
||||
res = accumulate (l.map loadOutputFor systems);
|
||||
in
|
||||
builtins.addErrorContext "[ren] while building rensa output"
|
||||
res.output
|
||||
// {
|
||||
__ren = {
|
||||
|
|
@ -89,10 +96,12 @@
|
|||
recursiveUpdate = lhs: rhs:
|
||||
recursiveUpdateUntil g lhs rhs;
|
||||
in
|
||||
build args
|
||||
// {
|
||||
__functor = l.flip recursiveUpdate;
|
||||
};
|
||||
builtins.addErrorContext "[ren] while building rensa output (buildWith)" (
|
||||
build args
|
||||
// {
|
||||
__functor = l.flip recursiveUpdate;
|
||||
}
|
||||
);
|
||||
in {
|
||||
inherit build buildWith;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,4 +112,5 @@ ref: inputOverrides: let
|
|||
)
|
||||
lockFile.nodes;
|
||||
in
|
||||
builtins.addErrorContext "[ren] while loading flake lockfile ${ref}"
|
||||
allNodes.${lockFile.root}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
l,
|
||||
utils,
|
||||
blocks,
|
||||
}: let
|
||||
paths = import ./paths.nix;
|
||||
callFlake = import ./call-flake.nix;
|
||||
autodiscover = import ./autodiscover.nix;
|
||||
loader = import ./loader.nix {inherit l utils paths callFlake;};
|
||||
builder = import ./builder.nix {inherit l utils loader;};
|
||||
builder = import ./builder.nix {inherit l utils loader autodiscover blocks;};
|
||||
in {
|
||||
inherit (builder) build buildWith;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,14 +33,18 @@
|
|||
}).outputs
|
||||
else {};
|
||||
in
|
||||
importSignatureFor system updatedCell cells additionalInputs;
|
||||
builtins.addErrorContext "[ren] while getting input signature for ${blockP}" (
|
||||
importSignatureFor system updatedCell cells additionalInputs
|
||||
);
|
||||
|
||||
import' = importPath: let
|
||||
block = import importPath;
|
||||
in
|
||||
if l.typeOf block == "set"
|
||||
then block
|
||||
else block signature;
|
||||
else
|
||||
builtins.addErrorContext "[ren] while importing block at ${importPath}"
|
||||
(block signature);
|
||||
|
||||
importPaths =
|
||||
if isFile
|
||||
|
|
@ -101,18 +105,20 @@
|
|||
in
|
||||
optionalLoad (isFile || isDir) (
|
||||
assert l.assertMsg isAttrs "cell block does not return an attrset: ${importPaths.displayPath}";
|
||||
l.traceVerbose "[ren] loading cell block ${cellBlock.name}, type ${cellBlock.type}, from cell ${cellP}"
|
||||
[
|
||||
{${cellBlock.name} = imported;}
|
||||
{${cellBlock.name} = l.mapAttrs (_: set: set.actions) extracted;}
|
||||
({
|
||||
cellBlock = cellBlock.name;
|
||||
blockType = cellBlock.type;
|
||||
targets = l.mapAttrsToList (_: set: set.init) extracted;
|
||||
}
|
||||
// (l.optionalAttrs (l.pathExists blockP.readmeDir) {readme = blockP.readmeDir;})
|
||||
// (l.optionalAttrs (l.pathExists blockP.readme) {inherit (blockP) readme;}))
|
||||
]
|
||||
l.traceVerbose "[ren] loading cell block ${cellBlock.name}, type ${cellBlock.type}, from cell ${cellP}, for system ${system}" (
|
||||
builtins.addErrorContext "[ren] loading cell block ${cellBlock.name}, type ${cellBlock.type}, from cell ${cellP}, for system ${system}"
|
||||
[
|
||||
{${cellBlock.name} = imported;}
|
||||
{${cellBlock.name} = l.mapAttrs (_: set: set.actions) extracted;}
|
||||
({
|
||||
cellBlock = cellBlock.name;
|
||||
blockType = cellBlock.type;
|
||||
targets = l.mapAttrsToList (_: set: set.init) extracted;
|
||||
}
|
||||
// (l.optionalAttrs (l.pathExists blockP.readmeDir) {readme = blockP.readmeDir;})
|
||||
// (l.optionalAttrs (l.pathExists blockP.readme) {inherit (blockP) readme;}))
|
||||
]
|
||||
)
|
||||
);
|
||||
in
|
||||
loadCellBlock;
|
||||
|
|
@ -133,7 +139,7 @@
|
|||
# fixes `ìnfinite recursion` errors when accessing cell attributes from sibling blocks
|
||||
# example: cells/test/a.nix returns `cell.b`, so the same thing as cells/test/b.nix.
|
||||
# this would previously fail with infinite recursion, this makes it work:
|
||||
cell = l.listToAttrs (l.concatMap (
|
||||
cell = builtins.addErrorContext "[ren] while accessing cell '${cellName}' siblings" (l.listToAttrs (l.concatMap (
|
||||
block: let
|
||||
blockP = paths.cellBlockPath cellP block;
|
||||
exists = l.pathExists blockP.file || l.pathExists blockP.dir;
|
||||
|
|
@ -148,18 +154,19 @@
|
|||
]
|
||||
else []
|
||||
)
|
||||
cellBlocks');
|
||||
cellBlocks'));
|
||||
loadCellBlock = createCellBlockLoader {inherit inputs system cells cell transformInputs;};
|
||||
res = accumulate (l.map (loadCellBlock cellName cellP) cellBlocks');
|
||||
in [
|
||||
{${cellName} = res.output;}
|
||||
{${cellName} = res.actions;}
|
||||
({
|
||||
cell = cellName;
|
||||
cellBlocks = res.init;
|
||||
}
|
||||
// (l.optionalAttrs (l.pathExists cellP.readme) {inherit (cellP) readme;}))
|
||||
];
|
||||
in
|
||||
builtins.addErrorContext "[ren] while loading cell ${cellName}" [
|
||||
{${cellName} = res.output;}
|
||||
{${cellName} = res.actions;}
|
||||
({
|
||||
cell = cellName;
|
||||
cellBlocks = res.init;
|
||||
}
|
||||
// (l.optionalAttrs (l.pathExists cellP.readme) {inherit (cellP) readme;}))
|
||||
];
|
||||
in
|
||||
loadCell;
|
||||
in {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{lib}: let
|
||||
l = builtins // lib;
|
||||
utils = import ./utils {inherit l;};
|
||||
core = import ./core {inherit l utils;};
|
||||
compat = import ./compat {inherit l;};
|
||||
blocks = import ./blocks;
|
||||
utils = import ./utils {inherit l;};
|
||||
compat = import ./compat {inherit l;};
|
||||
core = import ./core {inherit l utils blocks;};
|
||||
in {
|
||||
inherit (compat) filter select get;
|
||||
inherit (core) build buildWith;
|
||||
|
|
|
|||
6
lib/flake.lock
generated
6
lib/flake.lock
generated
|
|
@ -2,11 +2,11 @@
|
|||
"nodes": {
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1754184128,
|
||||
"narHash": "sha256-AjhoyBL4eSyXf01Bmc6DiuaMrJRNdWopmdnMY0Pa/M0=",
|
||||
"lastModified": 1766884708,
|
||||
"narHash": "sha256-x8nyRwtD0HMeYtX60xuIuZJbwwoI7/UKAdCiATnQNz0=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "02e72200e6d56494f4a7c0da8118760736e41b60",
|
||||
"rev": "15177f81ad356040b4460a676838154cbf7f6213",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
63
tests/autodiscovery_test.nix
Normal file
63
tests/autodiscovery_test.nix
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
pkgs,
|
||||
ntlib,
|
||||
...
|
||||
}: {
|
||||
suites."Autodiscovery" = {
|
||||
pos = __curPos;
|
||||
tests = [
|
||||
{
|
||||
name = "find nix files";
|
||||
type = "script";
|
||||
script = ''
|
||||
${ntlib.helpers.path [pkgs.gnugrep pkgs.coreutils pkgs.nix]}
|
||||
${ntlib.helpers.scriptHelpers}
|
||||
|
||||
mkdir -p "testcell"
|
||||
echo '{ foo = "bar"; }' > "testcell/packages.nix"
|
||||
echo '{ baz = "qux"; }' > "testcell/devShells.nix"
|
||||
echo '{ ignored = true; }' > "testcell/flake.nix"
|
||||
|
||||
result=$(nix eval --impure --expr '
|
||||
let
|
||||
lib = import ${pkgs.path}/lib;
|
||||
autodiscover = import ${../lib/core/autodiscover.nix} {
|
||||
l = builtins // lib;
|
||||
cellsFrom = ./.;
|
||||
cellBlocks = [ { name = "__autodiscover"; } ];
|
||||
};
|
||||
in
|
||||
builtins.length (builtins.filter (b: b.name == "packages" || b.name == "devShells") autodiscover)
|
||||
')
|
||||
|
||||
assert_eq "$result" "2" "should discover 2 blocks"
|
||||
'';
|
||||
}
|
||||
{
|
||||
name = "finds directories";
|
||||
type = "script";
|
||||
script = ''
|
||||
${ntlib.helpers.path [pkgs.gnugrep pkgs.coreutils pkgs.nix]}
|
||||
${ntlib.helpers.scriptHelpers}
|
||||
|
||||
mkdir -p "testcell/packages"
|
||||
echo '{ hello = "world"; }' > "testcell/packages/default.nix"
|
||||
|
||||
result=$(nix eval --impure --expr '
|
||||
let
|
||||
lib = import ${pkgs.path}/lib;
|
||||
autodiscover = import ${../lib/core/autodiscover.nix} {
|
||||
l = builtins // lib;
|
||||
cellsFrom = ./.;
|
||||
cellBlocks = [ { name = "__autodiscover"; } ];
|
||||
};
|
||||
in
|
||||
builtins.any (b: b.name == "packages") autodiscover
|
||||
')
|
||||
|
||||
assert "$result == true" "Should discover directory with default.nix"
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
90
tests/builder_test.nix
Normal file
90
tests/builder_test.nix
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
pkgs,
|
||||
ntlib,
|
||||
rensa,
|
||||
...
|
||||
}: {
|
||||
suites."Builder" = {
|
||||
pos = __curPos;
|
||||
tests = [
|
||||
{
|
||||
name = "has system outputs";
|
||||
expected = true;
|
||||
actual = let
|
||||
testFlake = rensa.build {
|
||||
inputs = {};
|
||||
cellsFrom = ../cells;
|
||||
cellBlocks = with rensa.blocks; [
|
||||
(simple "test")
|
||||
];
|
||||
systems = ["x86_64-linux"];
|
||||
};
|
||||
in
|
||||
builtins.hasAttr "x86_64-linux" testFlake;
|
||||
}
|
||||
{
|
||||
name = "has ren metadata";
|
||||
expected = true;
|
||||
actual = let
|
||||
testFlake = rensa.build {
|
||||
inputs = {};
|
||||
cellsFrom = ../cells;
|
||||
cellBlocks = with rensa.blocks; [
|
||||
(simple "test")
|
||||
];
|
||||
systems = ["x86_64-linux"];
|
||||
};
|
||||
in
|
||||
builtins.hasAttr "__ren" testFlake;
|
||||
}
|
||||
{
|
||||
name = "merges outputs";
|
||||
expected = {
|
||||
packages = {
|
||||
test-package = "merged";
|
||||
};
|
||||
};
|
||||
actual = let
|
||||
testFlake =
|
||||
rensa.buildWith {
|
||||
inputs = {};
|
||||
cellsFrom = ../cells;
|
||||
cellBlocks = with rensa.blocks; [
|
||||
(simple "test")
|
||||
];
|
||||
systems = ["x86_64-linux"];
|
||||
} {
|
||||
packages = {
|
||||
test-package = "merged";
|
||||
};
|
||||
};
|
||||
in {
|
||||
packages = testFlake.packages;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "eval test";
|
||||
type = "script";
|
||||
script = ''
|
||||
${ntlib.helpers.path [pkgs.gnugrep pkgs.coreutils pkgs.nix]}
|
||||
${ntlib.helpers.scriptHelpers}
|
||||
|
||||
result=$(nix eval --impure --expr '
|
||||
let
|
||||
rensa = import ${../lib} {lib = import ${pkgs.path}/lib;};
|
||||
testFlake = rensa.build {
|
||||
inputs = { test = "value"; };
|
||||
cellsFrom = ${../cells};
|
||||
cellBlocks = [];
|
||||
systems = [ "x86_64-linux" ];
|
||||
};
|
||||
in
|
||||
testFlake.__ren.__schema
|
||||
')
|
||||
|
||||
assert "$result == \"v0\"" "should contain version"
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
51
tests/filter_test.nix
Normal file
51
tests/filter_test.nix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
{rensa, ...}: {
|
||||
suites."Filter" = {
|
||||
pos = __curPos;
|
||||
tests = [
|
||||
{
|
||||
name = "filter by cell";
|
||||
expected = {
|
||||
x86_64-linux = {};
|
||||
};
|
||||
actual = let
|
||||
testFlake = {
|
||||
__ren = {
|
||||
cells = ["repo" "other"];
|
||||
};
|
||||
x86_64-linux = {
|
||||
repo = {
|
||||
docs = {value = "docs-value";};
|
||||
ci = {value = "ci-value";};
|
||||
};
|
||||
other = {
|
||||
packages = {value = "other-packages";};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
rensa.filter (_: cell: cell == "repo") testFlake [["*" "*"]];
|
||||
}
|
||||
{
|
||||
name = "filter by block";
|
||||
expected = {
|
||||
x86_64-linux = {};
|
||||
};
|
||||
actual = let
|
||||
testFlake = {
|
||||
__ren = {
|
||||
cells = ["repo"];
|
||||
};
|
||||
x86_64-linux = {
|
||||
repo = {
|
||||
docs = {value = "docs-value";};
|
||||
ci = {value = "ci-value";};
|
||||
packages = {value = "packages-value";};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
rensa.filter (block: _: block == "docs") testFlake [["repo" "*"]];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
57
tests/loader_test.nix
Normal file
57
tests/loader_test.nix
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
pkgs,
|
||||
ntlib,
|
||||
rensa,
|
||||
...
|
||||
}: {
|
||||
suites."Loader" = {
|
||||
pos = __curPos;
|
||||
tests = [
|
||||
{
|
||||
name = "cell sibling access";
|
||||
expected = {
|
||||
hello = "world";
|
||||
};
|
||||
actual = let
|
||||
testFlake = rensa.build {
|
||||
inputs = {};
|
||||
cellsFrom = ../cells;
|
||||
cellBlocks = with rensa.blocks; [
|
||||
(simple "test")
|
||||
];
|
||||
systems = ["x86_64-linux"];
|
||||
};
|
||||
in
|
||||
testFlake.x86_64-linux.test.test;
|
||||
}
|
||||
{
|
||||
name = "load file";
|
||||
type = "script";
|
||||
script = ''
|
||||
${ntlib.helpers.path [pkgs.gnugrep pkgs.coreutils pkgs.nix]}
|
||||
${ntlib.helpers.scriptHelpers}
|
||||
|
||||
mkdir -p "cells/testcell"
|
||||
echo '{ hello = "world"; }' > "cells/testcell/packages.nix"
|
||||
|
||||
cat > "flake.nix" << 'EOF'
|
||||
{
|
||||
outputs = inputs: let
|
||||
rensa = import ${../lib} { lib = import "${pkgs.path}/lib"; };
|
||||
in rensa.build {
|
||||
inputs = {};
|
||||
cellsFrom = ./cells;
|
||||
cellBlocks = with rensa.blocks; [ (simple "packages") ];
|
||||
systems = [ "x86_64-linux" ];
|
||||
};
|
||||
}
|
||||
EOF
|
||||
|
||||
result=$(nix eval --impure .#x86_64-linux.testcell.packages.hello)
|
||||
|
||||
assert "$result == \"world\"" "should equal to world"
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
49
tests/select_test.nix
Normal file
49
tests/select_test.nix
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
{rensa, ...}: {
|
||||
suites."Select" = {
|
||||
pos = __curPos;
|
||||
tests = [
|
||||
{
|
||||
name = "single block";
|
||||
expected = {
|
||||
x86_64-linux = {value = "test-value";};
|
||||
};
|
||||
actual = let
|
||||
testFlake = {
|
||||
__ren = {
|
||||
cells = ["repo"];
|
||||
};
|
||||
x86_64-linux = {
|
||||
repo = {
|
||||
docs = {value = "test-value";};
|
||||
ci = {packages = {value = "ci-packages";};};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
rensa.select testFlake [["repo" "docs"]];
|
||||
}
|
||||
{
|
||||
name = "multiple blocks";
|
||||
expected = {
|
||||
x86_64-linux = {value = "ci-packages";};
|
||||
};
|
||||
actual = let
|
||||
testFlake = {
|
||||
__ren = {
|
||||
cells = ["repo"];
|
||||
};
|
||||
x86_64-linux = {
|
||||
repo = {
|
||||
ci = {packages = {value = "ci-packages";};};
|
||||
other = {value = "ignored";};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
rensa.select testFlake [
|
||||
["repo" "ci" "packages"]
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue