Closed noverby closed 1 year ago
Yeah, that is trying to use {hello, ...}: x: hello
as the bundler which is failing since its not the intended x: hello
. To make that work I'll have to test a bit. Right now a bundlers/foo.nix
containing x: x
would work.
For bundlers.nix
the following works right now:
{ hello, ... }:
{
default = x: hello;
}
We can do the above since bundlers should be an attrset, so if we are given a function, we just apply the args and expect an attrset.
For bundlers/foo.nix
, we expect a bundler with a function. It is not trivial to tell x: x
apart from pkgs: x: x
. Both are functions. It would need to be applied, which in the latter case returns a function, and in the former a derivation. Though we also need to apply appropriate parameters.
We can tell { hello, ... }: x: hello
apart from x: x
since we can inspect a function's named arguments. There is also precedence for requiring named arguments as with pkgs.callPackage
.
The first issue is that this makes { hello, ... }: x: hello
work but not pkgs: x: pkgs.hello
. I also find callPackage not defaulting to passing the whole set surprising at first discovery. Though this could be acceptable as the intent is clear in the named arguments case, though leaves the pkgs
case as an unintuitive error.
Second is that { src, ... }: src
is a valid bundler, though this is a really edge case so would be fine to ignore (if needed, perSystem
with bundlers
can be used).
Third is that wrapping the function removes named arguments. let f = { hello, ... }: x: hello; in x: f x;
returns a function with same behavior but where the arguments can't be inspected. This is likely not an issue for direct use, but causes issues when dealing directly with the module system for example.
Ideally there is a way to tell apart x: x
from pkgs: x: x
; if so that can be used to determine whether to apply module args. There may be a way to do so abusing lazy eval or with tryEval; I'll have to play around with it a bit.
Evaluating a bundler during flake evaluation might also not be a good idea since the bundler could use IFD.
Somewhat interesting:
nix-repl> builtins.attrNames (builtins.intersectAttrs pkgs.hello pkgs)
[ "src" "stdenv" "system" "tests" ]
Apparently there is a package named src.
We cannot rely on builtins.functionArgs
after all, since pkgs: { hello, ... }: (x: hello) pkgs
is the same as the inner function but with args hidden.
Applying function to determine if pkgs: x: x
or x: x
should work if the arg used is pkgs // pkgs.hello
since that is both a valid derivation, so should result in a derivation for the bundler, and is a set with all pkgs names so should result in a function if it is a function that takes pkgs.
Downsides are that the bundler must support bundling pkgs.hello, and evaluating the flake output would result in IFD if the bundler uses IFD. The former is fine, and the second might be solvable by wrapping the bundler, capturing pkgs, and determining whether to apply pkgs at bundler eval time instead of at flake output eval time (need to check if that interferes with any nix flake check warnings).
Fixed with ff24d5d4330db69a4dc4e6fdb97ca3ce9f8881a2.
With the wrapper, also do not need to rely on pkgs.hello as can use the passed derivation.
@accelbread Is pkgs suppose to be exposed?
error: anonymous function at /nix/store/n0cyhxv3v8878mqcv4cz46zh69cqq4ad-source/nix/bundlers/bundler.nix:1:1 called without required argument 'pkgs'
Do you have an example flake?
I am not able to reproduce that error.
I have tested the following contents of bundler.nix: x: x
, pkgs: x: pkgs.hello
, { hello, ... }: x: hello
, { pkgs, ... }: x: pkgs.hello
, and all work.
@accelbread Oh sorry, the flakelight input didn't properly update, it actually works. Thanks!
With flake:
And bundler foo:
Results in the error: