nix-community / home-manager

Manage a user environment using Nix [maintainer=@rycee]
https://nix-community.github.io/home-manager/
MIT License
6.67k stars 1.75k forks source link

Prepending directories to $PATH #3324

Open ralismark opened 1 year ago

ralismark commented 1 year ago

Description

Currently, the entries in home.sessionPath are only appended to $PATH, and there is no way to add entries before the existing path. My main issue with this is that I'm unable to override binaries that are installed from other places.

Adding packages to home.packages with the appropriate contents isn't an option if the contents of the directory I want to add to PATH is allowed to change without requiring a home-manager switch.

I see there's the following closed PRs:

The former was closed as the latter supersedes it, but the latter became stale and was eventually closed, and I'm kinda wondering if that's intentional or not?

ralismark commented 1 year ago

I had a go at this and came up with this. It's not the full dag-based solution, and I haven't extensively tested it, but at least it seems decently backwards compatible with the existing definition of home.sessionPath

{ config, lib, pkgs, ... }:
with lib;
let
  cfg = config.home;
in {
  options.home = {
    sessionPath2 = mkOption {
      type = with types; listOf str;
      default = [ ];
      description = ''
        Extra directories to add to <envar>PATH</envar>.

        (rest of description)
      '';
    };
  };

  config = {
    # Include inherited $PATH people can mkBefore on it
    home.sessionPath2 = [ "$PATH" ];

    home.packages = [
      (
        pkgs.writeTextFile {
          name = "path.sh";
          destination = "/etc/profile.d/path.sh";
          text = let
            replaceMatch = match: lib.replaceStrings
              [ ":\$${match}:" ":\$${match}" "\$${match}:" ]
              [ "\${${match}:+:\$${match}:}" "\${${match}:+:\$${match}}" "\${${match}:+\$${match}:}" ];
            pathvar = replaceMatch "PATH" (lib.concatStringsSep ":" cfg.sessionPath2);
          in lib.optionalString (cfg.sessionPath2 != [ "$PATH" ]) ''
            export PATH="${pathvar}"
          '';
        }
      )
    ];
  };
}

If this kind of solution seems good I'm happy to clean this up and open a PR!

srid commented 1 year ago

On macOS, we need this to be able to put git on $PATH ahead of /usr/bin (which has Apple's own git binary). Which in turn is necessary for programs that shell out to git, like lazygit to work:

❯ lg
2022/12/04 10:08:31 Git version must be at least 2.0 (i.e. from 2014 onwards). Please upgrade your git version. Alternatively raise an issue at https://github.com/jesseduffield/lazygit/issues for lazygit to be more backwards compatible.
stale[bot] commented 1 year ago

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

teutat3s commented 1 year ago

Experiencing this issue as well. Use case: programs.neovim.extraPackages Adding pkgs.universal-ctags to that option does not allow me to use pkgs.vimPlugins.vim-gutentags. /usr/bin/ctags takes preference as is appears earlier in $PATH.

gutentags: [job stderr]: ['/Library/Developer/CommandLineTools/usr/bin/ctags: illegal option -- -', 'usage: ctags [-BFadtuwvx] [-f tagsfile] file ...', '']
...
gutentags: ctags job failed, returned: 1
:!echo $PATH
/nix/store/pcmlzfwxy62lkwl31mg84sxa8hx1yz8a-zplug-2.4.2/share/zplug/bin:/Users/teutat3s/.nix-profile/bin:/etc/profiles/per-user/teutat3s/bin:/run/current-system/sw/bin:/nix/var/n
profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin:/nix/store/x71vkdfmb45j2drlzx7y98da46nnq880-neovim-ruby-env/bin:/nix/store/vivhx8mwldwzcmnaqibmxp2d9jqz71hl-node
18.16.1/bin:/nix/store/kfkh4xv41xcv884ahbx38b1wmva3hsld-universal-ctags-6.0.0/bin

Is there a workaround for this issue?

EDIT: hacky but works for now: programs.zsh.initExtra

''
  # Workaround PATH priority for vim-gutentags
  # https://github.com/nix-community/home-manager/issues/3324
  export PATH=${pkgs.universal-ctags}/bin:$PATH
'';
stale[bot] commented 11 months ago

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

ambroisie commented 9 months ago

Looking at the original PR it looks like the decision to make home.sessionPath append to PATH was quite arbitrary. The question of how to prepend to it instead was asked and promptly dismissed.

The original intent of the PR was to add executables which did not shadow any in PATH. The issue of it appending to PATH makes it difficult to have one's dot-files shadow existing system executables without doing manual PATH manipulation, which is exactly what home.sessionPath set out to avoid.

Therefore I believe it should instead be changed so that home.sessionPath prepends to PATH: it is clearly what the user would expect to be done, follows what NixOS does for environment.homeBinInPath and environment.localBinInPath, and doesn't break anything for people that don't care about it (like the original author of #1292).

stale[bot] commented 6 months ago

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

ambroisie commented 6 months ago

Still relevant. @rycee could you please take a look at the PR?