Cannot access `inputs.self.outPath` in top level `imports`
Opened this issue · 4 comments
Given
# flake.nix
{
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = inputs@{ self, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } ({inputs, ...}: {
imports = [
"${inputs.self.outPath}/my-module.nix"
];
});
}
# my-module.nix
{
flake.lib.myFunction = x: x;
}
When running
nix flake show
Got
error: infinite recursion encountered
Root cause
Workaround
# flake.nix
{
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = inputs@{ self, flake-parts, ... }:
{
inherit (
flake-parts.lib.mkFlake { inherit inputs; } ({inputs, ...}: {
imports = [
"${inputs.self.outPath}/my-module.nix"
];
})
) lib;
};
}
Workaround 2
Instead of self.outPath
, you could use the equivalent ./.
(edit: unless you're writing a reusable flakeModule):
# flake.nix
{
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } ({inputs, ...}: {
imports = [
./my-module.nix
];
});
}
It's not equivalent when your flake is used in another flake
So I guess you're writing a framework with a fixed location for a flake module then?
With the Nix we have, you can only imports
from a self
where you've already decided the set of outputs attrNames.
In other words, there's no workaround for NixOS/nix#8300.
There might be a solution in the form of NixOS/nix#4154, but otherwise, the best we can do is workarounds.
Workaround 3, perSystem only
Maybe this helps you or someone. perSystem
generally does not affect the attrNames
of the flake
option.
# flake.nix
{
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = inputs@{ self, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } ({inputs, ...}: {
perSystem = {
imports = [
"${inputs.self.outPath}/my-module.nix"
];
};
});
}
Workaround 4, specialArgs
specialArgs
was designed for imports
.
You might require specialArgs.root = ./.
to be passed by users. I don't think it's the right tradeoff between inconveniences, but you could require this for your framework.
Users would call
mkFlake { inherit inputs; specialArgs.root = ./.; } <module>
You would write a module such as
{ root, ... }:
{
imports = [ (root + "/my-module.nix") ];
}