Recommended practice for setting PATH

In a few packages I have prefixed path like so

    wrapProgram $out/bin/mn \
      --set JAVA_HOME ${jdk} \
      --prefix PATH : ${jdk}/bin

While this works I’m not sure it is “pure.” Is there a better practice for creating an exact PATH for the script and setting it?

FWIW, wrapProgram is very common throughout Nixpkgs, the manual even says it’s the way to set JAVA_HOME like you are:

Note all JDKs passthru home , so if your application requires environment variables like JAVA_HOME being set, that can be done in a generic fashion with the --set argument of makeWrapper :

--set JAVA_HOME ${jdk.home}

And has examples setting PATH in the same way you are. So you’re not doing something unconventional. You might also be interested in the small helper functions lib.makeBinPath and lib.makeLibraryPath which both take lists of packages and return a string.

Thanks for pointing out the makeBinPath. My question is more about the --prefix PATH I was using this and switched it to --set PATH and realized there were undeclared dependencies like dirname and basename in the script being wrapped. This makes me wonder if setting PATH is better since it forces me to declare all of the dependencies rather than relying on the user’s PATH.

uname is another dependency I have found.

This actually all started because if I don’t add the jdk to PATH the script ends up using jdk14 from my user’s install and fails. I believe for this script to install correctly I need to set JAVA_HOME and provide an exact path that doesn’t use something from the user’s environment.

Now I am really stuck. I do believe that by prefixing PATH, the micronaut package is dependent on global state from the user’s environment. This would be interesting to investigate in other packages. I believe the best practice is to set PATH and never prefix it.

I set PATH to only contain coreutils and jdk. The script starts the program but now the application throws an exception. There is something in the runtime that depends on PATH being setup correctly. I have been debugging the code and I have narrowed it down a bit but it has something to do with classloading a groovy file from a downloaded dependency. I may have more progress to post later.

Ok I think I found something. After debugging the micronaut cli I came across this error.

Cannot run program "sh": error=2, No such file or directory

It looks like sh needs to be on the path. Progress!

The solution is to set PATH and to use the bash package to correctly add sh. This was suggested in a review comment for my nur repo.

--set PATH ${lib.makeBinPath [ gnused coreutils jdk bash ]}