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

Fix usage of tracer gem and add tests #857

Merged
merged 1 commit into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ jobs:
run: bundle exec rubocop
irb:
needs: ruby-versions
name: rake test ${{ matrix.ruby }} ${{ matrix.with_latest_reline && '(latest reline)' || '' }}
name: rake test ${{ matrix.ruby }} ${{ matrix.with_latest_reline && '(latest reline)' || '' }} ${{ matrix.with_tracer && '(with tracer)' || '' }}
strategy:
matrix:
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
with_latest_reline: [true, false]
with_tracer: [true, false]
exclude:
- ruby: truffleruby
fail-fast: false
runs-on: ubuntu-latest
env:
WITH_LATEST_RELINE: ${{matrix.with_latest_reline}}
WITH_TRACER: ${{matrix.with_tracer}}
timeout-minutes: 30
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ gem "test-unit-ruby-core"

gem "rubocop"

gem "tracer" if ENV["WITH_TRACER"] == "true"
st0012 marked this conversation as resolved.
Show resolved Hide resolved
gem "debug", github: "ruby/debug", platforms: [:mri, :mswin]

if RUBY_VERSION >= "3.0.0" && !is_truffleruby
Expand Down
5 changes: 5 additions & 0 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ def initialize(irb, workspace = nil, input_method = nil)

private_constant :KEYWORD_ALIASES

def use_tracer=(val)
require_relative "ext/tracer"
@use_tracer = val
end

private def build_completor
completor_type = IRB.conf[:COMPLETOR]
case completor_type
Expand Down
60 changes: 7 additions & 53 deletions lib/irb/ext/tracer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,30 @@
# irb/lib/tracer.rb -
# by Keiju ISHITSUKA([email protected])
#

# Loading the gem "tracer" will cause it to extend IRB commands with:
# https://github.com/ruby/tracer/blob/v0.2.2/lib/tracer/irb.rb
Comment on lines +6 to +7
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It took me some time to figure this out. Is this helpful?

Copy link
Member

Choose a reason for hiding this comment

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

I added that because IRB currently doesn't have integration with it. Do you think dropping it will make things easier here?

begin
require "tracer"
rescue LoadError
$stderr.puts "Tracer extension of IRB is enabled but tracer gem wasn't found."
module IRB
class Context
def use_tracer=(opt)
# do nothing
end
end
end
return # This is about to disable loading below
end

module IRB

# initialize tracing function
def IRB.initialize_tracer
Tracer.verbose = false
Tracer.add_filter {
|event, file, line, id, binding, *rests|
/^#{Regexp.quote(@CONF[:IRB_LIB_PATH])}/ !~ file and
File::basename(file) != "irb.rb"
}
Comment on lines -25 to -30
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tracer.verbose and Tracer.add_filter were available in v0.1.x and I could not find an equivalent in the 0.2.x API.

end

class Context
# Whether Tracer is used when evaluating statements in this context.
#
# See +lib/tracer.rb+ for more information.
attr_reader :use_tracer
alias use_tracer? use_tracer

# Sets whether or not to use the Tracer library when evaluating statements
# in this context.
#
# See +lib/tracer.rb+ for more information.
def use_tracer=(opt)
if opt
Tracer.set_get_line_procs(@irb_path) {
|line_no, *rests|
@io.line(line_no)
}
elsif !opt && @use_tracer
Tracer.off
end
Comment on lines -45 to -52
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same here, set_get_line_procs, off / on are all method of the v0.1.x API, without an equivalent in v0.2.x

@use_tracer=opt
end
end

class WorkSpace
alias __evaluate__ evaluate
# Evaluate the context of this workspace and use the Tracer library to
# output the exact lines of code are being executed in chronological order.
#
# See +lib/tracer.rb+ for more information.
def evaluate(context, statements, file = nil, line = nil)
if context.use_tracer? && file != nil && line != nil
Tracer.on
begin
# See https://github.com/ruby/tracer for more information.
def evaluate(statements, file = __FILE__, line = __LINE__)
if IRB.conf[:USE_TRACER] == true
CallTracer.new(colorize: Color.colorable?).start do
__evaluate__(statements, file, line)
ensure
Tracer.off
end
else
__evaluate__(statements, file || __FILE__, line || __LINE__)
__evaluate__(statements, file, line)
end
end
end

IRB.initialize_tracer
end
1 change: 0 additions & 1 deletion lib/irb/extend-command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ module ContextExtender

@EXTEND_COMMANDS = [
[:eval_history=, "ext/eval_history.rb"],
[:use_tracer=, "ext/tracer.rb"],
[:use_loader=, "ext/use-loader.rb"],
]

Expand Down
2 changes: 1 addition & 1 deletion test/irb/test_context.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: false
require 'tempfile'
require 'irb'
require 'rubygems' if defined?(Gem)
require 'rubygems'

require_relative "helper"

Expand Down
6 changes: 6 additions & 0 deletions test/irb/test_init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ def test_dash
assert_equal(['-f'], argv)
end

def test_option_tracer
argv = %w[--tracer]
IRB.setup(eval("__FILE__"), argv: argv)
assert_equal(true, IRB.conf[:USE_TRACER])
end

private

def with_argv(argv)
Expand Down
97 changes: 97 additions & 0 deletions test/irb/test_tracer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# frozen_string_literal: false
require 'tempfile'
require 'irb'
require 'rubygems'

require_relative "helper"

module TestIRB
class ContextWithTracerIntegrationTest < IntegrationTestCase
def setup
super

@envs.merge!("NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => '')
end

def example_ruby_file
<<~'RUBY'
class Foo
def self.foo
100
end
end

def bar(obj)
obj.foo
end

binding.irb
RUBY
end

def test_use_tracer_is_disabled_by_default
nunosilva800 marked this conversation as resolved.
Show resolved Hide resolved
write_rc <<~RUBY
IRB.conf[:USE_TRACER] = false
RUBY

write_ruby example_ruby_file

output = run_ruby_file do
type "bar(Foo)"
type "exit!"
end

assert_nil IRB.conf[:USER_TRACER]
assert_not_include(output, "#depth:")
assert_not_include(output, "Foo.foo")
end

def test_use_tracer_enabled_when_gem_is_unavailable
begin
gem 'tracer'
omit "Skipping because 'tracer' gem is available."
rescue Gem::LoadError
nunosilva800 marked this conversation as resolved.
Show resolved Hide resolved
write_rc <<~RUBY
IRB.conf[:USE_TRACER] = true
RUBY

write_ruby example_ruby_file

output = run_ruby_file do
type "bar(Foo)"
type "exit!"
end

assert_include(output, "Tracer extension of IRB is enabled but tracer gem wasn't found.")
end
end

def test_use_tracer_enabled_when_gem_is_available
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.1.0')
omit "Ruby version before 3.1.0 does not support Tracer integration. Skipping this test."
end

begin
gem 'tracer'
rescue Gem::LoadError
omit "Skipping because 'tracer' gem is not available. Enable with WITH_TRACER=true."
end

write_rc <<~RUBY
IRB.conf[:USE_TRACER] = true
RUBY

write_ruby example_ruby_file

output = run_ruby_file do
type "bar(Foo)"
type "exit!"
end

assert_include(output, "Object#bar at")
assert_include(output, "Foo.foo at")
assert_include(output, "Foo.foo #=> 100")
assert_include(output, "Object#bar #=> 100")
end
end
end
Loading