please icon indicating copy to clipboard operation
please copied to clipboard

Hardcoded assumptions where tools such as `ls` or `mv` live

Open hzeller opened this issue 2 years ago • 2 comments

I try to build please on nixos, but the ./bootstrap.sh fails due to built-in assumptions where certain tools live.

In nix, different versions of programs can co-exist, but they will not be in the 'common' paths; these tools can be found in the $PATH, but not at hardcoded places (for instance, ls lives in /nix/store/cbzwjj38mvy6sz7k9wpl33sa5mgxx5j3-coreutils-9.3/bin/ls not /bin/ls. Or bash is in /nix/store/zi11gd05qg6ryi81d3difs416anyz7lp-bash-interactive-5.2-p15/bin/bash. You ge the idea (a super-higlevel how nix works page describes some high-level concepts).

The only binary in /bin is /bin/sh, the only binary in /usr/bin is /usr/bin/env). [^1]

So the recommendation to find binaries is either through the $PATH (which typically works; I suspect that inside please you attempt to keep that PATH searching to a fixed set of locations) or via /usr/bin/env. So /usr/bin/env ls or /usr/bin/env dirname would work. Special in nixos is also the path /run/current-system/sw/bin/ which contains symbolic links to the users' preferred installation, so this could be a path to search for as well for successful finding of these binaries. But even that might not exist in a sandboxed environment.

Ok, back to the issue - this is how ./bootstrap.sh fails on my machine, because it can't find some basic binaries:

Bootstrapping please...
Build stopped after 50ms. 1 target failed:
    //plugins:shell
Error building target //plugins:shell: exit status 127
bash: line 1: ls: command not found
bash: line 1: dirname: command not found
bash: line 1: mv: command not found

An strace shows that the 'typical' paths are searched, but that won't work here

$ grep /mv strace.out 
1261910 newfstatat(AT_FDCWD, "/run/user/1000/go-build3207954/b001/exe/mv",  <unfinished ...>
1261910 newfstatat(AT_FDCWD, "/usr/local/bin/mv",  <unfinished ...>
1261910 newfstatat(AT_FDCWD, "/usr/bin/mv",  <unfinished ...>
1261910 newfstatat(AT_FDCWD, "/bin/mv",  <unfinished ...>

I don't know enough about the please code-base yet to figure out where to look, so filing this issue in hopes to get things rolling.

Probable solution

I'd probably recommend to look at the 'common' locations first as you already do (maybe including /run/current-system/sw/bin/ at the end which is the standard path for the user-installed binaries), followed by the actual elements in $PATH (which currently does not seem to happen).

Since you do the 'safe' locations at the beginning of the search and then only use the (potentially user-modified) PATH, you should still be on the safe side.

[^1]: I see that in many shell-scripts within the please codebase, you actually follow that already #!/usr/bin/env bash is perfect to use in shell scripts!

hzeller avatar Aug 01 '23 03:08 hzeller

I don't think we do hardcode any paths like /bin/mv or similar anywhere. The normal answer would be to set the PATH in the config:

[build]
path = /usr/local/bin:/usr/bin:/bin:/nix/store/nonsense/usr/bin

I'm not super familiar with Nix but I get the impression that might be tedious; it is probably a bit of a clash of the two systems. You could set:

[build]
passenv = PATH

although generally I would very much not encourage that since most users tend to customise PATH which will have it pointing to different places (this is maybe more of a concern for us where that would crater our remote execution cache hit rate).

peterebden avatar Sep 30 '23 12:09 peterebden