fix(vendor-gems): redirect bundler stdout to stderr

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.
This commit is contained in:
Gibson Fahnestock 2021-06-02 11:52:01 +01:00
parent d74da6cfc6
commit 07d571bebc
No known key found for this signature in database
GPG Key ID: B01FBB92821C587A
3 changed files with 17 additions and 2 deletions

View File

@ -40,7 +40,7 @@ module Homebrew
end
ohai "bundle install --standalone"
safe_system "bundle", "install", "--standalone"
safe_system_redirect_stdout_to_stderr "bundle", "install", "--standalone"
ohai "bundle pristine"
safe_system "bundle", "pristine"

View File

@ -332,6 +332,19 @@ module Kernel
end
end
# Redirects stdout to stderr, throws exception on command failure.
def safe_system_redirect_stdout_to_stderr(cmd, *args)
return if Homebrew._system(cmd, *args) do
# Redirect stdout stream to stderr stream. This is useful to prevent
# subprocesses from writing to stdout and interfering with the intended
# output, e.g. when running a brew command with `--json` for programs
# automating brew commands.
$stdout.reopen($stderr)
end
raise ErrorDuringExecution.new([cmd, *args], status: $CHILD_STATUS)
end
def which(cmd, path = ENV["PATH"])
PATH.new(path).each do |p|
begin

View File

@ -144,7 +144,9 @@ module Homebrew
# for some reason sometimes the exit code lies so check the output too.
if bundle_check_failed || bundle_check_output.include?("Install missing gems")
unless system bundle, "install"
begin
safe_system_redirect_stdout_to_stderr bundle, "install"
rescue ErrorDuringExecution
message = <<~EOS
failed to run `#{bundle} install`!
EOS