When running brew commands and interpreting the output, e.g. running
`brew livecheck --json`, it's necessary to stop other programs Homebrew
happens to execute from writing logging output to stdout. Most programs
don't do this, but `bundle install` does seem to.
To reproduce the issue you can run:
```shell
git -C "$(brew --prefix)" clean -ffdx Library/Homebrew/vendor
stdout=$(HOMEBREW_FORCE_VENDOR_RUBY=1 brew livecheck --newer-only --json --cask $(brew --repo homebrew/cask)/Casks/grid.rb)
echo "^^^ was stderr, >>> is stdout: $stdout"
```
If you run it without this change it will print a bunch of output like
this to the stdout before printing out the livecheck JSON output:
```text
Using bundler 1.17.3
Fetching byebug 11.1.3
Fetching coderay 1.1.3
Installing byebug 11.1.3 with native extensions
Installing coderay 1.1.3
Fetching colorize 0.8.1
Installing colorize 0.8.1
[
# Contents of the JSON block.
]
```
With this change the stdout from `bundle install` will be redirected to
brew's stderr, meaning only the JSON goes to stdout, and the rest goes
to stderr.
- further refactor nested conditional to make it clearer
- allow running on Linux while still excluding Apple Silicon
- only warn on `bundle install` failures
This fixes an issue where at least in Xcode 11.0, `make` uses
`/var/tmp` as a fallback for temporary files unless `TMPDIR` is set:
```
$ strings "$(xcrun -f make)" | grep -B 3 fopen
TMPDIR
/var/tmp/
GmXXXXXX
fopen (temporary file)
```
Given that Homebrew filtered `TMPDIR`, and the `/var/tmp` directory may
not be writable for non-root users, this would cause Homebrew’s
build environment to error out:
```
$ brew ruby -e 'puts ENV["TMPDIR"]; puts `: | make -f -`'
```
```
Ignoring bigdecimal-2.0.0 because its extensions are not built. Try: gem pristine bigdecimal --version 2.0.0
[…]
Ignoring zlib-1.1.0 because its extensions are not built. Try: gem pristine zlib --version 1.1.0
make: *** fopen (temporary file): Permission denied. Stop.
```
In practice, this would break `brew audit`, `brew style`, and other
commands, which would run `make` to build native gem extensions.
This commit sets `TMPDIR` to `${HOMEBREW_TEMP}` in the gem environment, which
mirrors the behaviour we already have in other places.
We choose `HOMEBREW_TEMP` because that’s user-controlled but also falls
back to `/tmp` in case `TMPDIR` is not set in the user’s environment.
Thanks to Bo Anderson for helping find the bug.
CC: Bo Anderson <mail@boanderson.me>
Now Ruby comes with its own bundler let's favour using it when we can
over requiring a system one be installed.
This avoids needing to have anything in `~/.gem` again.
I am somewhat optimistic this may help with #6579 but it's useful
by itself.