Skip to content

Commit 15650f1

Browse files
committed
feat: allow overrides of inputs of with-inputs-based project
1 parent bae062d commit 15650f1

3 files changed

Lines changed: 80 additions & 7 deletions

File tree

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Download our `default.nix` into your project `./with-inputs.nix`.
7272
curl https://raw.githubusercontent.com/vic/with-inputs/refs/heads/main/default.nix -o with-inputs.nix
7373
```
7474

75-
Or use npins or `builtins.fetchTarball` with a fixed revision of it. [^output-trick]
75+
Or use npins or `builtins.fetchTarball` with a fixed revision of it. [^output-trick] [^output-trick-2]
7676

7777
```shell
7878
npins add github vic with-inputs
@@ -90,11 +90,35 @@ let
9090
in
9191
with-inputs outputs
9292
```
93+
or if you want to allow overrides of inputs from a consumer project:
94+
```nix
95+
# default.nix
96+
{
97+
inputsOverrides ? { },
98+
}:
99+
let
100+
sources = import ./npins; # example with npins. use any other sources.
101+
with-inputs = import sources.with-inputs sources {
102+
# keep reading for follows and local inputs
103+
};
104+
105+
outputs = localInputs: let inputs = localInputs // inputsOverrides; in
106+
{ }; # your flake-like outputs function
107+
in
108+
with-inputs outputs
109+
```
93110

94111
[^output-trick]: To use the experimental `nix` cli commands, create a `flake.nix` containing only
95112
```nix
96113
{ outputs = _: import ./.; }
97114
```
115+
[^output-trick-2]: To additionally allow inputs overrides (eg, by a `with-inputs`-based consummer project):
116+
```nix
117+
{ outputs = inputsOverrides: import ./. { inherit inputsOverrides; }
118+
```
119+
120+
### Flake backed by non-flake pins
121+
When `with-inputs` detect a flake dependency which does not declare any inputs, that flake `output` function is still called with the all available inputs, so they could be used as overrides.
98122
99123
### Follows and local checkout overrides
100124

tests.nix

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,19 +316,19 @@ in
316316

317317
# ── Dependency introspection ────────────────────────────────────────────────
318318

319-
introsepction.test-access-sub-flake-inputs = {
319+
introspection.test-access-sub-flake-inputs = {
320320
# inputs.someFlake.inputs.dep — traverse a dependency's own inputs
321321
expr = (with-inputs { } { a = mkFlake { dep = mkSrc "/dep"; } { }; }).a.inputs.dep.outPath;
322322
expected = "/dep";
323323
};
324324

325-
introsepction.test-access-sub-flake-outputs = {
325+
introspection.test-access-sub-flake-outputs = {
326326
# inputs.someFlake.outputs.lib — explicit outputs access
327327
expr = (with-inputs { } { a = mkFlake { } { lib = "mylib"; }; }).a.outputs.lib;
328328
expected = "mylib";
329329
};
330330

331-
introsepction.test-sub-flake-output-attrs-merged-at-top-level = {
331+
introspection.test-sub-flake-output-attrs-merged-at-top-level = {
332332
# inputs.someFlake.lib ≡ inputs.someFlake.outputs.lib
333333
expr =
334334
let
@@ -346,6 +346,21 @@ in
346346
expected = "mylib";
347347
};
348348

349+
introspection.test-follow-sub-npins-with-inputs-input = {
350+
# my-lib.inputs.nixpkgs.follows = "with-inputs-dep/nixpkgs" → traverse native inputs
351+
expr =
352+
(with-inputs
353+
{
354+
my-lib = mkSrc ./fixtures/fake-flake;
355+
with-inputs-dep = mkSrc ./fixtures/with-inputs-flake;
356+
}
357+
{
358+
my-lib.inputs.nixpkgs.follows = "with-inputs-dep/nixpkgs";
359+
}
360+
).my-lib.inputs.nixpkgs.outPath;
361+
expected = npins.nixpkgs.outPath;
362+
};
363+
349364
real-flakes.test-npins-nix-maid-nixosModules-output-is-readable = {
350365
expr =
351366
(with-inputs npins { } (inputs: {
@@ -378,6 +393,26 @@ in
378393
expected = npins.nixpkgs.outPath;
379394
};
380395

396+
real-flakes.test-sub-npins-with-inputs-nested-follows = {
397+
# with-inputs-dep.inputs.nixpkgs.follows = "inputs/nixpkgs" → "blind" override of with-inputs-dep.inputs.nixpkgs
398+
expr =
399+
(with-inputs
400+
{
401+
inputs = mkFlake { nixpkgs = mkSrc "/nested-nixpkgs"; } { };
402+
with-inputs-dep = mkSrc ./fixtures/with-inputs-flake;
403+
}
404+
{
405+
with-inputs-dep.inputs.nixpkgs.follows = "inputs/nixpkgs";
406+
}
407+
(inputs: {
408+
check = inputs.with-inputs-dep.usedNixpkgs;
409+
})
410+
).check;
411+
expected = {
412+
outPath = "/nested-nixpkgs";
413+
};
414+
};
415+
381416
non-flakes.test-non-flakes-are-not-evaluated = {
382417
expr =
383418
(with-inputs

with-inputs.nix

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,33 @@ let
109109

110110
mkFlakeInput =
111111
name: sourceInfo: flake:
112+
let
113+
topLevelInputs = inputs;
114+
in
112115
let
113116
specs = flake.inputs or { };
114-
inputs = builtins.mapAttrs (sub: spec: resolveSubInput name sub spec) specs;
117+
direct = builtins.mapAttrs (sub: spec: resolveSubInput name sub spec) specs;
115118
indirect = builtins.mapAttrs (sub: _: resolveSubInput name sub { }) (
116119
builtins.functionArgs flake.outputs
117120
);
118-
outputs = flake.outputs (indirect // inputs // { inherit self; });
121+
nonEmptyInputs = direct != { } || indirect != { };
122+
inputs =
123+
if nonEmptyInputs then
124+
indirect // direct
125+
else
126+
# Assume inputs are not handled by flake, but output function may still accept inputs overrides
127+
builtins.removeAttrs allInputs [ name ]
128+
// (builtins.mapAttrs (sub: spec: resolveSubInput name sub spec) (
129+
topLevelInputs.${name}.inputs or { }
130+
));
131+
outputs = flake.outputs (inputs // { inherit self; });
119132
self =
120133
sourceInfo
121134
// outputs
122135
// {
123136
_type = "flake";
124-
inherit inputs outputs sourceInfo;
137+
inputs = if nonEmptyInputs then inputs else outputs.inputs or { inherit self; };
138+
inherit outputs sourceInfo;
125139
};
126140
in
127141
self;

0 commit comments

Comments
 (0)