Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return standard output in popen_write #8541

Merged
merged 3 commits into from
Sep 2, 2020
Merged

Return standard output in popen_write #8541

merged 3 commits into from
Sep 2, 2020

Conversation

claui
Copy link
Contributor

@claui claui commented Aug 30, 2020

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew tests with your changes locally?

Expected behaviour

We expect the popen_write method to return the standard output of the child process.

This expectation is evident in how safe_popen_write is written:

  def self.safe_popen_write(*args, **options, &block)
    output = popen_write(*args, **options, &block)
    return output if $CHILD_STATUS.success?

    raise ErrorDuringExecution.new(args, status: $CHILD_STATUS, output: [[:stdout, output]])
  end

Actual behaviour

Contrary to what the above code suggests, no code has been written to actually obtain any output from the child process. Newly-written tests show that popen_write only returns a number ("4") instead of the expected standard output.

For example, given a file foo with the content Foo\n, one of the tests calls popen_write with cat foo - and an input of Bar. The expected output would be Foo\nBar\n but the actual output is the number 4 (which is what Ruby’s IO#write method returns).

Fix

By having popen_write transparently capture standard output, we restore the intended semantics.

The practical purpose of this PR is that when an embedded formula patch fails, it now displays the actual output of the patch binary (instead of the length of the patch).

Fixes #8244.

When using `popen_write`, the expectation is to return the
standard output of the child process.

This expectation is evident in how `safe_popen_write` is written:

```
  def self.safe_popen_write(*args, **options, &block)
    output = popen_write(*args, **options, &block)
    return output if $CHILD_STATUS.success?

    raise ErrorDuringExecution.new(args, status: $CHILD_STATUS, output: [[:stdout, output]])
  end
```

However, no code has been written to actually *obtain* that output
from the child process. The side effects of that are described in
issue #8244. [1]

[1]: #8244

The newly-added tests reveal that `popen_write` only returns the
number 4 instead of the expected standard output.

For example, given a file `foo` with the content `Foo\n`, one test
calls `popen_write` with `cat foo -` and an input of `Bar`.
The expected output would be `Foo\nBar\n` but the actual output is
the number 4 (which is what Ruby’s `IO#write` method returns).
@claui claui added the usability Usability of Homebrew/brew label Aug 30, 2020
Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work @claui!

Fix tests and fulfill intended semantics by having `popen_write`
transparently capture standard output.
Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blocking comments, thanks @claui.

@MikeMcQuaid MikeMcQuaid merged commit 8604cdb into Homebrew:master Sep 2, 2020
@MikeMcQuaid
Copy link
Member

Thanks @claui!

@BrewTestBot BrewTestBot added the outdated PR was locked due to age label Dec 14, 2020
@Homebrew Homebrew locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age usability Usability of Homebrew/brew
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error handler prints number of bytes instead of actual output
3 participants