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

Bye byebug, hi debug! #17010

Merged
merged 8 commits into from Apr 18, 2024
Merged

Bye byebug, hi debug! #17010

merged 8 commits into from Apr 18, 2024

Conversation

issyl0
Copy link
Member

@issyl0 issyl0 commented Apr 2, 2024

  • 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 typecheck with your changes locally?
  • Have you successfully run brew tests with your changes locally?


image

But the (minimal, basic) testing I did seems to drop me at a prompt that I can use.

❯ git diff
diff --git a/Library/Homebrew/test/migrator_spec.rb b/Library/Homebrew/test/migrator_spec.rb
index 87fadd5e95..db4700810a 100644
--- a/Library/Homebrew/test/migrator_spec.rb
+++ b/Library/Homebrew/test/migrator_spec.rb
@@ -69,6 +69,8 @@ RSpec.describe Migrator do
       tab.source["tap"] = "homebrew/core"
       tab.write

+      binding.break
+
       expect do
         described_class.new(new_formula, "oldname")
       end.to raise_error(Migrator::MigratorDifferentTapsError)

issyl0 at pictor in /opt/homebrew on bye-byebug
❯ brew tests --only=migrator --debug
Randomized with seed 59158
1 process for 1 spec, ~ 1 spec per process
.==> Relinking newname
.==> Unlinking oldname
...==> Moving oldname versions to /private/tmp/homebrew-tests-20240403-85464-3uogqr/cellar/newname
....==> Migrating formula oldname to newname
==> Unlinking oldname
==> Moving oldname versions to /private/tmp/homebrew-tests-20240403-85464-3uogqr/cellar/newname
==> Relinking newname
....[67, 76] in ~/migrator_spec.rb
    67|       tab = Tab.empty
    68|       tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
    69|       tab.source["tap"] = "homebrew/core"
    70|       tab.write
    71|
=>  72|       binding.break
    73|
    74|       expect do
    75|         described_class.new(new_formula, "oldname")
    76|       end.to raise_error(Migrator::MigratorDifferentTapsError)
=>#0    block in <top (required)> (3 levels) at ~/migrator_spec.rb:72
  #1    [C] BasicObject#instance_exec at /opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263
  # and 68 frames (use `bt' command for all frames)
(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p tab
(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p    # command(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p     # command t    # command ta    # command tab    # command(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p tab    # command
=> #<Tab:0x0000000107156be0 @Aliases=[], @Arch=nil, @built_as_bottle=false, @built_on={"os"=>"Macintosh", "os_version"=>"macOS 14", "cpu_family"=>"arm_firestorm_icestorm"}, @Compiler=:clang, @homebrew_version="4.2.16-55-gc8f60ec-dirty", @installed_as_dependency=false, @installed_on_request=false, @loaded_from_api=false, @poured_from_bottle=false, @runtime_dependencies=nil, @source={"path"=>nil, "tap"=>"homebrew/core", "tap_git_head"=>nil, "spec"=>"stable", "versions"=>{"stable"=>nil, "head"=>nil, "version_scheme"=>0}}, @source_modified_time=0, @stdlib=nil, @tabfile=#<Pathname:/private/tmp/homebrew-tests-20240403-85464-3uogqr/cellar/oldname/0.1/INSTALL_RECEIPT.json>, @time=nil, @unused_options=[], @used_options=[]>
(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464)

@Bo98
Copy link
Member

Bo98 commented Apr 3, 2024

Hmm, I wonder if instead of the debug dependency we can do (in standalone/init.rb just before the stuff at line 42):

if RUBY_PATH.to_s.include?("/vendor/portable-ruby/")
  $LOAD_PATH.unshift "#{RbConfig::CONFIG["rubylibprefix"]}/gems/#{RbConfig::CONFIG["ruby_version"]}/gems/debug-1.6.3/lib"
end

(I'll figure out a way to do this more magically rather than a hardcoded version - maybe on the Portable Ruby side)

This does limit it to Portable Ruby only, but for such a niche developer-only feature I'm OK with that given it avoids juggling more native gems.

@apainintheneck
Copy link
Contributor

@issyl0 You got to it before I did. This will be helpful when working on #16895.

@Bo98 If we could handle the debug dependency on the portable Ruby side, that would be ideal.

@MikeMcQuaid
Copy link
Member

Great work @issyl0 and good idea!

This does limit it to Portable Ruby only, but for such a niche developer-only feature I'm OK with that given it avoids juggling more native gems.

Same, as long as it gets a nice error message 👍🏻

Copy link
Sponsor Member

@dduugg dduugg left a comment

Choose a reason for hiding this comment

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

I realize this in draft mode, I hope the early feedback doesn't come off as pestering.
Love to see this being investigated!

Library/Homebrew/dev-cmd/tests.rb Outdated Show resolved Hide resolved
Library/Homebrew/dev-cmd/tests.rb Show resolved Hide resolved
Library/Homebrew/test/spec_helper.rb Outdated Show resolved Hide resolved
@issyl0
Copy link
Member Author

issyl0 commented Apr 4, 2024

(I'll figure out a way to do this more magically rather than a hardcoded version - maybe on the Portable Ruby side.)

@Bo98 Did you figure this out? Or can we ship this and do that in the future? Not that it's urgent, of course.

@Bo98
Copy link
Member

Bo98 commented Apr 4, 2024

well, hardcoded version will be fine as it won't change until we update Portable Ruby - the debug gem ships with our Portable Ruby

@issyl0
Copy link
Member Author

issyl0 commented Apr 5, 2024

Ahh yes I see what you mean. I'll try to get that working later. 👍🏻

@issyl0 issyl0 force-pushed the bye-byebug branch 2 times, most recently from 8fe8515 to b830b3e Compare April 7, 2024 19:27
@issyl0
Copy link
Member Author

issyl0 commented Apr 10, 2024

If anyone's got any suggestions for why this doesn't work with the debug from portable Ruby, I'm marking this as non-draft, so please comment and/or push commits!

@issyl0 issyl0 marked this pull request as ready for review April 10, 2024 19:33
@Bo98
Copy link
Member

Bo98 commented Apr 10, 2024

Ah in addition to the gems/debug-1.6.3/lib path you will also need extensions/#{RUBY_PLATFORM}/#{ruby_version}-static/debug-1.6.3

@issyl0
Copy link
Member Author

issyl0 commented Apr 10, 2024

Oooh, because .so is libraries, and those are "extensions"? Thanks again, Bo!

@issyl0
Copy link
Member Author

issyl0 commented Apr 10, 2024

🤔 I don't have an extensions?

/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/extensions/arm64-darwin20/3.1.0-static/debug-1.6.3: No such file or directory

❯ ls /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/
3.1.0   gems

@Bo98
Copy link
Member

Bo98 commented Apr 10, 2024

portable-ruby/3.1.4/lib/ruby/gems/3.1.0/extensions/

@issyl0
Copy link
Member Author

issyl0 commented Apr 10, 2024

That's weird...

❯ ls /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/extensions/arm64-darwin20/3.1.0-static/debug-1.6.3
ls: /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/extensions/arm64-darwin20/3.1.0-static/debug-1.6.3: No such file or directory

but

❯ ls /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/extensions/arm64-darwin-20/3.1.0-static           
debug-1.6.3     rbs-2.7.0

So RUBY_PLATFORM is reporting arm64-darwin20 when the path is actually arm64-darwin-20? What am I doing wrong?

I refer once again to the confused dog in the PR description. 😆

@Bo98
Copy link
Member

Bo98 commented Apr 10, 2024

Ah, right. Gem::Platform.local should work instead of RUBY_PLATFORM

@issyl0
Copy link
Member Author

issyl0 commented Apr 10, 2024

@Bo98 Thanks. Getting there!

@Bo98
Copy link
Member

Bo98 commented Apr 17, 2024

if I add require "debug" to the spec_helper again it gives:

LoadError:
 cannot load such file -- debug

The require in dev-cmd/tests is useless and can go. The one in spec_helper will need to be after the ../global require.

Though we want it to be conditional of --debug being passed (since require "debug" may fail on non-Portable Ruby) so you'll need to pass some tag/variable and make the require conditional on that.

@issyl0
Copy link
Member Author

issyl0 commented Apr 17, 2024

Thanks for the extra guidance, Bo! I made brew tests --debug set ENV["HOMEBREW_DEBUG"] and then required the "debug" gem in spec_helper.rb based on that. It works!

- Byebug was introduced in [2020](#7577) for hooking into tests for debugging.
- It does not work anymore in so far as it does not stop at breakpoints when following the instructions to trigger them in tests.
- This processed that we'd requested a debugger, but didn't drop us into
  a debugging console until I
  [stopped the stdin disablement](#16708 (comment)).

Usage:

```
❯ git diff
diff --git a/Library/Homebrew/test/migrator_spec.rb b/Library/Homebrew/test/migrator_spec.rb
index 87fadd5e95..db4700810a 100644
--- a/Library/Homebrew/test/migrator_spec.rb
+++ b/Library/Homebrew/test/migrator_spec.rb
@@ -69,6 +69,8 @@ RSpec.describe Migrator do
       tab.source["tap"] = "homebrew/core"
       tab.write

+      binding.break
+
       expect do
         described_class.new(new_formula, "oldname")
       end.to raise_error(Migrator::MigratorDifferentTapsError)

issyl0 at pictor in /opt/homebrew on bye-byebug
❯ brew tests --only=migrator --debug
Randomized with seed 59158
1 process for 1 spec, ~ 1 spec per process
.==> Relinking newname
.==> Unlinking oldname
...==> Moving oldname versions to /private/tmp/homebrew-tests-20240403-85464-3uogqr/cellar/newname
....==> Migrating formula oldname to newname
==> Unlinking oldname
==> Moving oldname versions to /private/tmp/homebrew-tests-20240403-85464-3uogqr/cellar/newname
==> Relinking newname
....[67, 76] in ~/migrator_spec.rb
    67|       tab = Tab.empty
    68|       tab.tabfile = HOMEBREW_CELLAR/"oldname/0.1/INSTALL_RECEIPT.json"
    69|       tab.source["tap"] = "homebrew/core"
    70|       tab.write
    71|
=>  72|       binding.break
    73|
    74|       expect do
    75|         described_class.new(new_formula, "oldname")
    76|       end.to raise_error(Migrator::MigratorDifferentTapsError)
=>#0    block in <top (required)> (3 levels) at ~/migrator_spec.rb:72
  #1    [C] BasicObject#instance_exec at /opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263
  # and 68 frames (use `bt' command for all frames)
(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p tab
(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p    # command(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p     # command t    # command ta    # command tab    # command(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464) p tab    # command
=> #<Tab:0x0000000107156be0 @Aliases=[], @Arch=nil, @built_as_bottle=false, @built_on={"os"=>"Macintosh", "os_version"=>"macOS 14", "cpu_family"=>"arm_firestorm_icestorm"}, @Compiler=:clang, @homebrew_version="4.2.16-55-gc8f60ec-dirty", @installed_as_dependency=false, @installed_on_request=false, @loaded_from_api=false, @poured_from_bottle=false, @runtime_dependencies=nil, @source={"path"=>nil, "tap"=>"homebrew/core", "tap_git_head"=>nil, "spec"=>"stable", "versions"=>{"stable"=>nil, "head"=>nil, "version_scheme"=>0}}, @source_modified_time=0, @stdlib=nil, @tabfile=#<Pathname:/private/tmp/homebrew-tests-20240403-85464-3uogqr/cellar/oldname/0.1/INSTALL_RECEIPT.json>, @time=nil, @unused_options=[], @used_options=[]>
(rdbg@/opt/homebrew/Library/Homebrew/vendor/bundle/ruby/3.1.0/bin/rspec#85464)
```
- This is cleaner than vendoring a whole bunch of new gems and pinning `psych`.
- Thanks for the pointer, Bo!
- It doesn't work, though?

```
❯ brew tests --only=migrator --debug
Error: cannot load such file -- debug/debug.so
Warning: Removed Sorbet lines from backtrace!
Rerun with `--verbose` to see the original backtrace
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug/frame_info.rb:16:in `require'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug/frame_info.rb:16:in `rescue in <module:DEBUGGER__>'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug/frame_info.rb:13:in `<module:DEBUGGER__>'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug/frame_info.rb:3:in `<top (required)>'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug/session.rb:31:in `require_relative'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug/session.rb:31:in `<top (required)>'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug.rb:3:in `require_relative'
/opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.1.4/lib/ruby/gems/3.1.0/gems/debug-1.6.3/lib/debug.rb:3:in `<top (required)>'
/opt/homebrew/Library/Homebrew/dev-cmd/tests.rb:48:in `require'
/opt/homebrew/Library/Homebrew/dev-cmd/tests.rb:48:in `run'
/opt/homebrew/Library/Homebrew/brew.rb:89:in `<main>'
```
- This doesn't work still, but now for new reasons.

```
     NoMethodError:
       undefined method `b' for #<Binding:0x0000000107a7e088>

             binding.b
                    ^^
     # ./test/migrator_spec.rb:72:in `block (3 levels) in <top (required)>'
```

and if I add `require "debug"` to the spec_helper again it gives:

```
LoadError:
  cannot load such file -- debug
```

but, doing a `require "debug"; binding.b` in `migrator_spec` _does_ work.

Where is the require coming from where it works some of the time but not through all of the layers we have?
- This will cause the "debug" gem to be required in `spec_helper.rb`, so we can do interactive debugging.
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.

Looks good to me, thanks @issyl0! Only non-blocking feedback is on the hardcoded debug gem version; feels likely we'll forget to update that when portable Ruby is updated.

ruby_version = RbConfig::CONFIG["ruby_version"]
ruby_path = "#{RbConfig::CONFIG["rubylibprefix"]}/gems/#{ruby_version}"

$LOAD_PATH.unshift "#{ruby_path}/extensions/#{Gem::Platform.local}/#{ruby_version}-static/debug-1.6.3"
Copy link
Member

Choose a reason for hiding this comment

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

Might be nice to glob or use a Gem method here so the version isn't hardcoded.

@issyl0 issyl0 merged commit 151e2fa into master Apr 18, 2024
28 checks passed
@issyl0 issyl0 deleted the bye-byebug branch April 18, 2024 09:30
@@ -38,6 +37,8 @@

require_relative "../global"

require "debug" if ENV["HOMEBREW_DEBUG"]
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

i wonder if we should just do this for any command run with --debug?

Copy link
Member

@Bo98 Bo98 Apr 22, 2024

Choose a reason for hiding this comment

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

Unlike brew tests which is a developer-only command, we ask end users to run --debug and we do not want this behaviour for them. Or if we do then it should catch a LoadError and fail silently.

@MikeMcQuaid
Copy link
Member

Thanks @issyl0, great work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix byebug when running tests
5 participants