Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ The second argument to `with-inputs` is an attribute set that
can be used to drive input resolution, for example to use local
checkout or to specify flake-like follows.

See [tests.nix](./tests.nix) for usage examples.

```nix
{
# Local checkout — loaded as a flake if a flake.nix is present
Expand Down Expand Up @@ -92,6 +94,9 @@ checkout or to specify flake-like follows.
inputs.nixpkgs.follows = "nixpkgs";
inputs.utils.follows = "flake-utils";
};

# Takes the original sources.otherFlake and avoids flake call
otherFlake = source: source // { flake = false; };
}
```

Expand Down
18 changes: 13 additions & 5 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ let

isFollows = v: builtins.isAttrs v && v ? follows;

specKeys = [
"follows"
"inputs"
];

# A spec is an attrset whose only keys are "follows" and/or "inputs",
# where every inputs.* value is itself a follows spec.
# Anything with outPath, lib, packages, … is a direct value, not a spec.
isSpec =
v:
builtins.isAttrs v
&& (v ? follows || v ? inputs)
&& builtins.all (k: k == "follows" || k == "inputs") (builtins.attrNames v)
&& builtins.all (x: builtins.elem x specKeys) (builtins.attrNames v)
&& (!(v ? inputs) || builtins.all (k: isFollows v.inputs.${k}) (builtins.attrNames v.inputs));

# Returns the resolved input, or null if any segment in the path is missing.
Expand Down Expand Up @@ -58,7 +62,9 @@ let
# Values with outPath but no _type go through mkInput so their flake.nix is loaded.
resolveInput =
name: v:
if isFollows v then
if builtins.isFunction v then
resolveInput name (v sources.${name})
else if isFollows v then
if v.follows == "" then { } else walkPath v.follows
else if isSpec v then
resolvedSources.${name} or { }
Expand Down Expand Up @@ -90,12 +96,14 @@ let
mkInput =
name: sourceInfo:
let
isFlake = sourceInfo.flake or true;
flakePath = sourceInfo.outPath + "/flake.nix";
flakeExists = sourceInfo ? outPath && builtins.pathExists flakePath;
in
if sourceInfo ? outPath && builtins.pathExists flakePath then
if isFlake && flakeExists then
mkFlakeInput name sourceInfo (import flakePath)
else
sourceInfo;
sourceInfo // { inherit sourceInfo; };

mkFlakeInput =
name: sourceInfo: flake:
Expand Down
26 changes: 26 additions & 0 deletions tests.nix
Original file line number Diff line number Diff line change
Expand Up @@ -362,4 +362,30 @@ in
expected = npins.nixpkgs.outPath;
};

"test non flakes are not evaluated" = {
expr =
(with-inputs
{
yesFlake.outPath = ./fixtures/fake-flake;
nonFlake.outPath = ./fixtures/fake-flake;
}
{
nonFlake = source: source // { flake = false; };
}
(inputs: {
result.yes.hasOutputs = inputs.yesFlake ? outputs;
result.non.hasOutputs = inputs.nonFlake ? outputs;

result.non.sourceInfo = inputs.nonFlake.sourceInfo;
})
).result;
expected = {
yes.hasOutputs = true;
non.hasOutputs = false;

non.sourceInfo.flake = false;
non.sourceInfo.outPath = ./fixtures/fake-flake;
};
};

}
Loading