Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flattenTree returns {} for a simple nested attrset (perhaps user error?) #121

Open
gautammohan opened this issue Jan 9, 2025 · 3 comments
Labels
bug Something isn't working

Comments

@gautammohan
Copy link

Describe the bug

I am trying to use flattenTree to collapse a nested attrset for my flake checks, and it returns an empty set instead of concatenating the keys.

To Reproduce

Steps to reproduce the behavior:
A minimal case in nix repl:

nix-repl> :lf github:numtide/flake-utils/v1.0.0
nix-repl> nixpkgs = import <nixpkgs> {}
nix-repl> pkgs = nixpkgs.pkgs
nix-repl> lib.flattenTree {zip = nixpkgs.pkgs.runCommand "foo" {} "bar";}     
{
  zip = «derivation /nix/store/j43kxmmazclshcr9xzdhic5r3s090ind-foo.drv»;
}

nix-repl> lib.flattenTree {zip.zap = nixpkgs.pkgs.runCommand "foo" {} "bar";}
{ }

Expected behavior

I expect the second command to output an attrset with {zip/zap: <...foo.drv>}, instead of an empty set.

System information

I am using the determinate nix installer (version 0.32.2) with a pinned nixpkgs of 24.05 for my flake. I am unsure about the version of <nixpkgs> in the repl, but this behavior is the same if I run my flake checks directly.

Additional context

I apologize in advance if this is a simple error or misuse of the function; I am still quite new to nix. However, perhaps this is still a useful issue since it feels like "unexpected" behavior, unless I am completely misinterpreting the purpose of flattenTree.

@gautammohan gautammohan added the bug Something isn't working label Jan 9, 2025
@dermetfan
Copy link

dermetfan commented Jan 14, 2025

flattenTree only recurses into an attribute set if it has recurseForDerivations = true, as documented:

(by respecting recurseIntoAttrs)

It can be a bit surprising that it defaults to false, and unfortunately there is no way change the default.

Here's a function that recursively calls recurseIntoAttrs for all non-derivation attribute sets:

recurseIntoDeepAttrs = attrs:
  lib.recurseIntoAttrs (lib.mapAttrs (_: v:
    if builtins.typeOf v == "set" && !lib.isDerivation v
    then recurseIntoDeepAttrs v
    else v
  ) attrs);

With that, flattenTree behaves as you expected:

nix-repl> utils.lib.flattenTree (recurseIntoDeepAttrs {
            zip.zap = pkgs.runCommand "foo" {} "bar";
          })
{
  "zip/zap" = «derivation /nix/store/ds9cnsp8yrja1gm9wqiyhqhqwg64zqsq-foo.drv»;
}

@TheNeikos
Copy link

I just fell into this.

Maybe on could check if the function input is a set, and actually has the recurse property set. And if it doesn't, emit a warning/error? Cause I don't see how calling the function could be useful in that situation.

@gautammohan
Copy link
Author

@dermetfan Thank you so much for the explanation! I suspected my issue was not fully understanding something about nix.

Perhaps this can be added as a cautionary use-case in the documentation for flattenTree. If any maintainers think it's a good idea, I would be happy to work on a PR for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants