Skip to content

nixos/direnv: fix silent option... again #402399

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

Merged
merged 1 commit into from
May 21, 2025
Merged

nixos/direnv: fix silent option... again #402399

merged 1 commit into from
May 21, 2025

Conversation

Gerg-L
Copy link
Contributor

@Gerg-L Gerg-L commented Apr 27, 2025

wrapping direnv with DIRENV_CONFIG was working... until it stopped.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 25.05 Release Notes (or backporting 24.11 and 25.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. labels Apr 27, 2025
Copy link
Contributor

@eclairevoyant eclairevoyant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would it suddenly stop working? Is makeBinaryWrapper broken? Does it work with makeShellWrapper?

And, could we also add a test for this?

@Gerg-L
Copy link
Contributor Author

Gerg-L commented Apr 29, 2025

Why would it suddenly stop working?

not a clue, direnv wasn't updated, nix-direnv wasn't updated, the module wasn't touched...

@eclairevoyant
Copy link
Contributor

eclairevoyant commented Apr 29, 2025

Oh, I see the problem.
You wrapped the direnv that gets added to environment.systemPackages - but config.programs.direnv.package is used in multiple places, including the shell hook.

So now there's two direnvs floating around, the shell hook is unwrapped but the direnv on PATH is wrapped. Actually it's surprising it even worked before.

Rather than overriding cfg.package in-place, we should have a finalPackage (perhaps even exposed as a readonly option) that's set to the overridden cfg.package, then use that throughout the direnv module. (Or the baseline package expression should add the wrapper. Not sure if that's detrimental for non-NixOS users? But it'd save the finalPackage boilerplate.)

@Gerg-L Gerg-L closed this Apr 29, 2025
@Gerg-L Gerg-L reopened this Apr 29, 2025
@Gerg-L Gerg-L marked this pull request as draft April 29, 2025 01:31
@Gerg-L
Copy link
Contributor Author

Gerg-L commented Apr 29, 2025

@eclairevoyant pushed you suggested changes, still isn't working.

i think we have to set DIRENV_CONFIG in environment.variables

@Gerg-L Gerg-L marked this pull request as ready for review May 3, 2025 14:16
@Gerg-L
Copy link
Contributor Author

Gerg-L commented May 3, 2025

i kept the finalPackage machinery, set environment.variables.DIRENV_CONFIG

@Gerg-L Gerg-L force-pushed the direnv branch 2 times, most recently from 6f9d461 to 3c61c7e Compare May 3, 2025 17:29
@wegank wegank added the 12.approvals: 1 This PR was reviewed and approved by one person. label May 4, 2025
@lyynd
Copy link

lyynd commented May 6, 2025

So I was investigating this on my own because I didn't find this PR. finalPackage does not work because the code inside the hook still references original unwrapped direnv. I don't know if there is a way to wrap a binary and rewrite all the references to self inside it.

@eclairevoyant
Copy link
Contributor

eclairevoyant commented May 6, 2025

That's basically what I said in #402399 (comment), unless you're saying something else.

Or maybe better as a question: what code are you referring to?

@lyynd
Copy link

lyynd commented May 6, 2025

The output of direnv hook fish for example contains reference (path) to direnv itself. But this is the path of the original package, not the wrapped one, because (I assume) wrapProgram does not rewrite paths inside the binary.
It never worked for me on fish and bash after the change which added the wrapper, but xonsh works right now (because it does not use the hooks from direnv).

@eclairevoyant
Copy link
Contributor

Oh, okay, what I was saying was different then. It seems like it's because of using symlinkJoin instead of (say) an override, which would preserve the store path and ensure it points to the wrapped binary. So going back to what you pointed out regarding replacing all the references to the unwrapped store path, adding a sed to postBuild might work, I'll play around with that.

@eclairevoyant
Copy link
Contributor

eclairevoyant commented May 6, 2025

Hmm actually I guess the problem will still arise because the wrapped program would call the unwrapped one, thereby introducing unwrapped code as part of the hook? We'd need some sort of "wrap-propagation" which I can't think of a clean way to do. I guess wrapping is just the wrong approach, and we should stick with the PR as written here.

EDIT: even finalPackage may not even work, I'm not sure how to test it.

@lyynd
Copy link

lyynd commented May 6, 2025

@eclairevoyant I tried and you are right, the problem is that we use symlinkJoin. If we do it like this:

finalPackage = cfg.package.overrideAttrs (old : {
  postBuild = (old.postBuild or "") + ''
    wrapProgram "$out/bin/direnv" \
      --set-default 'DIRENV_CONFIG' '/etc/direnv'
    rm -rf "$out/share/fish"
  '';
});

Then it correctly uses the final build path in direnv hook.

@Gerg-L
Copy link
Contributor Author

Gerg-L commented May 6, 2025

Direnv is a fairly small build, so the reduced environmental pollution is probably worth the build, I'll test it then change this PR tonight

@lyynd
Copy link

lyynd commented May 6, 2025

Oh, I see, the problem with this is that direnv will need to be rebuilt.
I tried doing substituteInPlace with symlinkJoin, but it seems it does not work on binaries (which is a bit unexpected).

@Gerg-L
Copy link
Contributor Author

Gerg-L commented May 6, 2025

overrideAttrs+ makeWrapper is not working in my testing

@lyynd
Copy link

lyynd commented May 6, 2025

Strange. I did this inside nixos-rebuild repl:

:b pkgs.direnv.overrideAttrs (old : {
  postBuild = (old.postBuild or "") + ''
    wrapProgram "$out/bin/direnv" \
      --set-default 'DIRENV_CONFIG' '/etc/direnv'
    rm -rf "$out/share/fish"
  '';
})

The resulting package has the correct direnv in direnv hook fish (itself) and direnv status shows that DIRENV_CONFIG is set correctly.

@lyynd
Copy link

lyynd commented May 6, 2025

By the way, I think that the approach that is currently in this PR should be merged, because it works (unlike what is in master right now) and improvements can be made after that.

@eclairevoyant
Copy link
Contributor

True, but I think none of us (?) are committers

@eclairevoyant
Copy link
Contributor

Some interesting ideas for future PRs in #404692 btw

@lyynd
Copy link

lyynd commented May 7, 2025

You are right, DIRENV_CONFIG is not being set with what I wrote, it was set from my global environment. Sorry for misleading. I don't know why wrapping in postBuild does not work, it doesn't in postInstall either.

@r-vdp r-vdp merged commit 6f9a8cf into NixOS:master May 21, 2025
32 checks passed
@voronind-com
Copy link
Contributor

voronind-com commented May 24, 2025

I have this issue on a freshly updated 25.05.
Are there plans to port this to the release branch?

Edit: I can confirm that using this fix worked for me on 25.05.

@Gerg-L Gerg-L added the backport release-25.05 Backport PR automatically label May 24, 2025
@nixpkgs-ci
Copy link
Contributor

nixpkgs-ci bot commented May 24, 2025

Successfully created backport PR for release-25.05:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 8.has: port to stable This PR already has a backport to the stable release. 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 12.approvals: 1 This PR was reviewed and approved by one person. backport release-25.05 Backport PR automatically
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants