Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## HEAD (unreleased)

- Code that does not have an associated file (eval and streamed) no longer produce a warning saying that the file could not be found. To produce a warning with these code types run with DEBUG=1 environment variable. (https://github.com/zombocom/dead_end/pull/143)
- [Breaking] Lazy load DeadEnd internals only if there is a Syntax error. Use `require "dead_end"; require "dead_end/api"` to load eagerly all internals. Otherwise `require "dead_end"` will set up an autoload for the first time the DeadEnd module is used in code. This should only happen on a syntax error. (https://github.com/zombocom/dead_end/pull/142)
- Monkeypatch `SyntaxError#detailed_message` in Ruby 3.2+ instead of `require`, `load`, and `require_relative` (https://github.com/zombocom/dead_end/pull/139)

Expand Down
26 changes: 19 additions & 7 deletions lib/dead_end/pathname_from_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ module DeadEnd
# # => "/tmp/scratch.rb"
#
class PathnameFromMessage
EVAL_RE = /^\(eval\):\d+/
STREAMING_RE = /^-:\d+/
attr_reader :name

def initialize(message, io: $stderr)
Expand All @@ -24,14 +26,20 @@ def initialize(message, io: $stderr)
end

def call
until stop?
@guess << @parts.shift
@name = Pathname(@guess.join(":"))
end
if skip_missing_file_name?
if ENV["DEBUG"]
@io.puts "DeadEnd: Could not find filename from #{@line.inspect}"
end
else
until stop?
@guess << @parts.shift
@name = Pathname(@guess.join(":"))
end

if @parts.empty?
@io.puts "DeadEnd: Could not find filename from #{@line.inspect}"
@name = nil
if @parts.empty?
@io.puts "DeadEnd: Could not find filename from #{@line.inspect}"
@name = nil
end
end

self
Expand All @@ -43,5 +51,9 @@ def stop?

@name&.exist?
end

def skip_missing_file_name?
@line.match?(EVAL_RE) || @line.match?(STREAMING_RE)
end
end
end
19 changes: 19 additions & 0 deletions spec/integration/ruby_command_line_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,24 @@ class Dog
expect(out).to include("DeadEnd is NOT loaded").once
end
end

it "ignores eval" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~'EOM'
$stderr = STDOUT
eval("def lol")
EOM

out = `ruby -I#{lib_dir} -rdead_end #{script} 2>&1`

expect($?.success?).to be_falsey
expect(out).to include("(eval):1")

expect(out).to_not include("DeadEnd")
expect(out).to_not include("Could not find filename")
end
end
end
end
21 changes: 21 additions & 0 deletions spec/unit/pathname_from_message_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ module DeadEnd
dir = Pathname(dir)

file = dir.join("scratch.rb")
# No touch, file does not exist
expect(file.exist?).to be_falsey

message = "#{file}:2:in `require_relative': /private/tmp/bad.rb:1: syntax error, unexpected `end' (SyntaxError)"
io = StringIO.new
Expand All @@ -31,5 +33,24 @@ module DeadEnd
expect(file).to be_falsey
end
end

it "does not output error message on syntax error inside of an (eval)" do
message = "(eval):1: invalid multibyte char (UTF-8) (SyntaxError)\n"
io = StringIO.new
file = PathnameFromMessage.new(message, io: io).call.name

expect(io.string).to eq("")
expect(file).to be_falsey
end

it "does not output error message on syntax error inside of streamed code" do
# An example of streamed code is: $ echo "def foo" | ruby
message = "-:1: syntax error, unexpected end-of-input\n"
io = StringIO.new
file = PathnameFromMessage.new(message, io: io).call.name

expect(io.string).to eq("")
expect(file).to be_falsey
end
end
end