dead_end 3.1.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f35aa207ae1ff3904d39f5c0ddca5b8a0f68ae157f5c0a999cd3f2f1530e461b
4
- data.tar.gz: b08307eb152fc12b84493409bfd8a9b8f23905180ad5ed9168a58d152913bc6e
3
+ metadata.gz: 655326e21a4ad4ae77a34020b69ce404f2405b2695b2e2e977c685352fcc0e79
4
+ data.tar.gz: 4a85b498c7d039a1ab016dae09775cb7a0a456c02a234ce83c5ac5776af97f0f
5
5
  SHA512:
6
- metadata.gz: 02b4ec64732eea9dbb55594c130d2fade4838a855bf3366408a5846683c3d2866e21844c7d3a2797adc865e177e7edf3bffaad0b87f555627f75fcac3d2aa219
7
- data.tar.gz: '029add7304c46c97a8a04b564f5798a2e5d43afe24472ae51268226e2dd5e71c56b9c48bf889232d4c3f2759b6edb7ea4c4f332688d6995ddaac0f7ec8ae5803'
6
+ metadata.gz: 409e22fe3a76ca5cc64a1886f58aaf8bcccc9b1f8564e580f8f1d70a63ba8a32216b6c2e9ac1e0c670b26e06a4a4b977d98562e4b9d2ea28a8bc30c3b096342f
7
+ data.tar.gz: 379bda579f643647303c39d409c4a675711e5c9679da123961b81b30b86d5b4133e8ea8636cf24eab757b4b262a2f8e93e977360b9a7ba68a5dfaa029e02fba2
data/.circleci/config.yml CHANGED
@@ -47,23 +47,25 @@ jobs:
47
47
 
48
48
  "ruby-3-1":
49
49
  docker:
50
- - image: 'cimg/base:stable'
50
+ - image: 'cimg/ruby:3.1'
51
51
  steps:
52
52
  - checkout
53
- - ruby/install:
54
- version: '3.1.2'
55
- - run: ruby -v
56
53
  - ruby/install-deps
57
54
  - <<: *unit
58
55
 
59
56
  "ruby-3-2":
60
57
  docker:
61
- - image: 'cimg/base:stable'
58
+ - image: 'ruby:3.2.0-preview1'
62
59
  steps:
63
60
  - checkout
64
- - ruby/install:
65
- version: '3.2.0-preview1'
66
- - run: ruby -v
61
+ - ruby/install-deps
62
+ - <<: *unit
63
+ "ruby-3-2-yjit":
64
+ docker:
65
+ - image: 'ruby:3.2.0-preview1'
66
+ steps:
67
+ - run: echo "export RUBY_YJIT_ENABLE=1" >> $BASH_ENV
68
+ - checkout
67
69
  - ruby/install-deps
68
70
  - <<: *unit
69
71
 
@@ -85,4 +87,5 @@ workflows:
85
87
  - "ruby-3-0"
86
88
  - "ruby-3-1"
87
89
  - "ruby-3-2"
90
+ - "ruby-3-2-yjit"
88
91
  - "lint"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## HEAD (unreleased)
2
2
 
3
+ ## 4.0.0
4
+
5
+ - 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)
6
+ - [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)
7
+ - Monkeypatch `SyntaxError#detailed_message` in Ruby 3.2+ instead of `require`, `load`, and `require_relative` (https://github.com/zombocom/dead_end/pull/139)
8
+
3
9
  ## 3.1.2
4
10
 
5
11
  - Fixed internal class AroundBlockScan, minor changes in outputs (https://github.com/zombocom/dead_end/pull/131)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dead_end (3.1.2)
4
+ dead_end (4.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/dead_end.gemspec CHANGED
@@ -8,7 +8,7 @@ end
8
8
 
9
9
  Gem::Specification.new do |spec|
10
10
  spec.name = "dead_end"
11
- spec.version = DeadEnd::VERSION
11
+ spec.version = UnloadedDeadEnd::VERSION
12
12
  spec.authors = ["schneems"]
13
13
  spec.email = ["richard.schneeman+foo@gmail.com"]
14
14
 
data/exe/dead_end CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative "../lib/dead_end"
3
+ require_relative "../lib/dead_end/api"
4
4
 
5
5
  DeadEnd::Cli.new(
6
6
  argv: ARGV
data/lib/dead_end/api.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "version"
2
4
 
3
5
  require "tmpdir"
@@ -7,6 +9,8 @@ require "ripper"
7
9
  require "timeout"
8
10
 
9
11
  module DeadEnd
12
+ VERSION = UnloadedDeadEnd::VERSION
13
+
10
14
  # Used to indicate a default value that cannot
11
15
  # be confused with another input.
12
16
  DEFAULT_VALUE = Object.new.freeze
@@ -16,7 +20,7 @@ module DeadEnd
16
20
 
17
21
  # DeadEnd.handle_error [Public]
18
22
  #
19
- # Takes a `SyntaxError`` exception, uses the
23
+ # Takes a `SyntaxError` exception, uses the
20
24
  # error message to locate the file. Then the file
21
25
  # will be analyzed to find the location of the syntax
22
26
  # error and emit that location to stderr.
@@ -1,35 +1,88 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Monkey patch kernel to ensure that all `require` calls call the same
4
- # method
5
- module Kernel
6
- module_function
7
-
8
- alias_method :dead_end_original_require, :require
9
- alias_method :dead_end_original_require_relative, :require_relative
10
- alias_method :dead_end_original_load, :load
11
-
12
- def load(file, wrap = false)
13
- dead_end_original_load(file)
14
- rescue SyntaxError => e
15
- DeadEnd.handle_error(e)
16
- end
3
+ # Allow lazy loading, only load code if/when there's a syntax error
4
+ autoload :DeadEnd, "dead_end/api"
5
+
6
+ # Ruby 3.2+ has a cleaner way to hook into Ruby that doesn't use `require`
7
+ if SyntaxError.new.respond_to?(:detailed_message)
8
+ module DeadEndUnloaded
9
+ class MiniStringIO
10
+ def initialize(isatty: $stderr.isatty)
11
+ @string = +""
12
+ @isatty = isatty
13
+ end
17
14
 
18
- def require(file)
19
- dead_end_original_require(file)
20
- rescue SyntaxError => e
21
- DeadEnd.handle_error(e)
15
+ attr_reader :isatty
16
+ def puts(value = $/, **)
17
+ @string << value
18
+ end
19
+
20
+ attr_reader :string
21
+ end
22
22
  end
23
23
 
24
- def require_relative(file)
25
- if Pathname.new(file).absolute?
26
- dead_end_original_require file
27
- else
28
- relative_from = caller_locations(1..1).first
29
- relative_from_path = relative_from.absolute_path || relative_from.path
30
- dead_end_original_require File.expand_path("../#{file}", relative_from_path)
24
+ SyntaxError.prepend Module.new {
25
+ def detailed_message(highlight: nil, **)
26
+ message = super
27
+ file = DeadEnd::PathnameFromMessage.new(message).call.name
28
+ io = DeadEndUnloaded::MiniStringIO.new
29
+
30
+ if file
31
+ DeadEnd.call(
32
+ io: io,
33
+ source: file.read,
34
+ filename: file
35
+ )
36
+ annotation = io.string
37
+
38
+ annotation + message
39
+ else
40
+ message
41
+ end
42
+ rescue => e
43
+ if ENV["DEBUG"]
44
+ $stderr.warn(e.message)
45
+ $stderr.warn(e.backtrace)
46
+ end
47
+
48
+ # Ignore internal errors
49
+ message
50
+ end
51
+ }
52
+ else
53
+ autoload :Pathname, "pathname"
54
+
55
+ # Monkey patch kernel to ensure that all `require` calls call the same
56
+ # method
57
+ module Kernel
58
+ module_function
59
+
60
+ alias_method :dead_end_original_require, :require
61
+ alias_method :dead_end_original_require_relative, :require_relative
62
+ alias_method :dead_end_original_load, :load
63
+
64
+ def load(file, wrap = false)
65
+ dead_end_original_load(file)
66
+ rescue SyntaxError => e
67
+ DeadEnd.handle_error(e)
68
+ end
69
+
70
+ def require(file)
71
+ dead_end_original_require(file)
72
+ rescue SyntaxError => e
73
+ DeadEnd.handle_error(e)
74
+ end
75
+
76
+ def require_relative(file)
77
+ if Pathname.new(file).absolute?
78
+ dead_end_original_require file
79
+ else
80
+ relative_from = caller_locations(1..1).first
81
+ relative_from_path = relative_from.absolute_path || relative_from.path
82
+ dead_end_original_require File.expand_path("../#{file}", relative_from_path)
83
+ end
84
+ rescue SyntaxError => e
85
+ DeadEnd.handle_error(e)
31
86
  end
32
- rescue SyntaxError => e
33
- DeadEnd.handle_error(e)
34
87
  end
35
88
  end
@@ -13,6 +13,8 @@ module DeadEnd
13
13
  # # => "/tmp/scratch.rb"
14
14
  #
15
15
  class PathnameFromMessage
16
+ EVAL_RE = /^\(eval\):\d+/
17
+ STREAMING_RE = /^-:\d+/
16
18
  attr_reader :name
17
19
 
18
20
  def initialize(message, io: $stderr)
@@ -24,14 +26,20 @@ module DeadEnd
24
26
  end
25
27
 
26
28
  def call
27
- until stop?
28
- @guess << @parts.shift
29
- @name = Pathname(@guess.join(":"))
30
- end
29
+ if skip_missing_file_name?
30
+ if ENV["DEBUG"]
31
+ @io.puts "DeadEnd: Could not find filename from #{@line.inspect}"
32
+ end
33
+ else
34
+ until stop?
35
+ @guess << @parts.shift
36
+ @name = Pathname(@guess.join(":"))
37
+ end
31
38
 
32
- if @parts.empty?
33
- @io.puts "DeadEnd: Could not find filename from #{@line.inspect}"
34
- @name = nil
39
+ if @parts.empty?
40
+ @io.puts "DeadEnd: Could not find filename from #{@line.inspect}"
41
+ @name = nil
42
+ end
35
43
  end
36
44
 
37
45
  self
@@ -43,5 +51,9 @@ module DeadEnd
43
51
 
44
52
  @name&.exist?
45
53
  end
54
+
55
+ def skip_missing_file_name?
56
+ @line.match?(EVAL_RE) || @line.match?(STREAMING_RE)
57
+ end
46
58
  end
47
59
  end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DeadEnd
4
- VERSION = "3.1.2"
3
+ # Calling `DeadEnd::VERSION` forces an eager load due to
4
+ # an `autoload` on the `DeadEnd` constant.
5
+ #
6
+ # This is used for gemspec access in tests
7
+ module UnloadedDeadEnd
8
+ VERSION = "4.0.0"
5
9
  end
data/lib/dead_end.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "dead_end/api"
4
3
  require_relative "dead_end/core_ext"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dead_end
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.2
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - schneems
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-18 00:00:00.000000000 Z
11
+ date: 2022-06-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: When you get an "unexpected end" in your syntax this gem helps you find
14
14
  it
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  requirements: []
85
- rubygems_version: 3.3.14
85
+ rubygems_version: 3.3.7
86
86
  signing_key:
87
87
  specification_version: 4
88
88
  summary: Find syntax errors in your source in a snap