error_highlight 0.3.0 → 0.5.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 +4 -4
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/ruby.yml +2 -2
- data/lib/error_highlight/base.rb +60 -7
- data/lib/error_highlight/core_ext.rb +29 -39
- data/lib/error_highlight/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb083cc3162d22724aa838cfc6c8a6d3473436c9fa276d731c07a840bdab1466
|
4
|
+
data.tar.gz: 3fb0a3ac24c77556f3343a9da1f43de5fdbe4a6bdf70d96a468cbcae129f3a1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d40e91d23f06e0f62db5c9945dc27c96590c0a36448e987e7d2c23b8b5947a978ba2f7918bc5d934342075d3926a525e64df159120c0c0026f19b8bc4203f4d
|
7
|
+
data.tar.gz: e7cb628e3cf5c60147a97ed96e02898ff9f444230aeed640c61c4998722e1cab6ea97149931340298ee525c72d5c2e663cc3f835fa116a9dbf22167ecad36e69
|
data/.github/workflows/ruby.yml
CHANGED
@@ -13,9 +13,9 @@ jobs:
|
|
13
13
|
runs-on: ubuntu-latest
|
14
14
|
strategy:
|
15
15
|
matrix:
|
16
|
-
ruby: [ 'ruby-head' ]
|
16
|
+
ruby: [ 'ruby-head', '3.1' ]
|
17
17
|
steps:
|
18
|
-
- uses: actions/checkout@
|
18
|
+
- uses: actions/checkout@v3
|
19
19
|
- uses: ruby/setup-ruby@v1
|
20
20
|
with:
|
21
21
|
ruby-version: ${{ matrix.ruby }}
|
data/lib/error_highlight/base.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
require_relative "version"
|
2
2
|
|
3
3
|
module ErrorHighlight
|
4
|
-
# Identify the code fragment that
|
4
|
+
# Identify the code fragment at that a given exception occurred.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
6
|
+
# Options:
|
7
|
+
#
|
8
|
+
# point_type: :name | :args
|
9
|
+
# :name (default) points the method/variable name that the exception occurred.
|
10
|
+
# :args points the arguments of the method call that the exception occurred.
|
11
|
+
#
|
12
|
+
# backtrace_location: Thread::Backtrace::Location
|
13
|
+
# It locates the code fragment of the given backtrace_location.
|
14
|
+
# By default, it uses the first frame of backtrace_locations of the given exception.
|
10
15
|
#
|
11
16
|
# Returns:
|
12
17
|
# {
|
@@ -15,9 +20,56 @@ module ErrorHighlight
|
|
15
20
|
# last_lineno: Integer,
|
16
21
|
# last_column: Integer,
|
17
22
|
# snippet: String,
|
23
|
+
# script_lines: [String],
|
18
24
|
# } | nil
|
19
|
-
|
20
|
-
|
25
|
+
#
|
26
|
+
# Limitations:
|
27
|
+
#
|
28
|
+
# Currently, ErrorHighlight.spot only supports a single-line code fragment.
|
29
|
+
# Therefore, if the return value is not nil, first_lineno and last_lineno will have
|
30
|
+
# the same value. If the relevant code fragment spans multiple lines
|
31
|
+
# (e.g., Array#[] of +ary[(newline)expr(newline)]+), the method will return nil.
|
32
|
+
# This restriction may be removed in the future.
|
33
|
+
def self.spot(obj, **opts)
|
34
|
+
case obj
|
35
|
+
when Exception
|
36
|
+
exc = obj
|
37
|
+
loc = opts[:backtrace_location]
|
38
|
+
opts = { point_type: opts.fetch(:point_type, :name) }
|
39
|
+
|
40
|
+
unless loc
|
41
|
+
case exc
|
42
|
+
when TypeError, ArgumentError
|
43
|
+
opts[:point_type] = :args
|
44
|
+
end
|
45
|
+
|
46
|
+
locs = exc.backtrace_locations
|
47
|
+
return nil unless locs
|
48
|
+
|
49
|
+
loc = locs.first
|
50
|
+
return nil unless loc
|
51
|
+
|
52
|
+
opts[:name] = exc.name if NameError === obj
|
53
|
+
end
|
54
|
+
|
55
|
+
return nil unless Thread::Backtrace::Location === loc
|
56
|
+
|
57
|
+
node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
|
58
|
+
|
59
|
+
Spotter.new(node, **opts).spot
|
60
|
+
|
61
|
+
when RubyVM::AbstractSyntaxTree::Node
|
62
|
+
Spotter.new(obj, **opts).spot
|
63
|
+
|
64
|
+
else
|
65
|
+
raise TypeError, "Exception is expected"
|
66
|
+
end
|
67
|
+
|
68
|
+
rescue SyntaxError,
|
69
|
+
SystemCallError, # file not found or something
|
70
|
+
ArgumentError # eval'ed code
|
71
|
+
|
72
|
+
return nil
|
21
73
|
end
|
22
74
|
|
23
75
|
class Spotter
|
@@ -122,6 +174,7 @@ module ErrorHighlight
|
|
122
174
|
last_lineno: @end_lineno,
|
123
175
|
last_column: @end_column,
|
124
176
|
snippet: @snippet,
|
177
|
+
script_lines: @node.script_lines,
|
125
178
|
}
|
126
179
|
else
|
127
180
|
return nil
|
@@ -2,51 +2,41 @@ require_relative "formatter"
|
|
2
2
|
|
3
3
|
module ErrorHighlight
|
4
4
|
module CoreExt
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def to_s
|
12
|
-
msg = super.dup
|
13
|
-
|
14
|
-
locs = backtrace_locations
|
15
|
-
return msg unless locs
|
16
|
-
|
17
|
-
loc = locs.first
|
18
|
-
begin
|
19
|
-
node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
|
20
|
-
opts = {}
|
5
|
+
private def generate_snippet
|
6
|
+
spot = ErrorHighlight.spot(self)
|
7
|
+
return "" unless spot
|
8
|
+
return ErrorHighlight.formatter.message_for(spot)
|
9
|
+
end
|
21
10
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
11
|
+
if Exception.method_defined?(:detailed_message)
|
12
|
+
def detailed_message(highlight: false, error_highlight: true, **)
|
13
|
+
return super unless error_highlight
|
14
|
+
snippet = generate_snippet
|
15
|
+
if highlight
|
16
|
+
snippet = snippet.gsub(/.+/) { "\e[1m" + $& + "\e[m" }
|
28
17
|
end
|
29
|
-
|
30
|
-
spot = ErrorHighlight.spot(node, **opts)
|
31
|
-
|
32
|
-
rescue SyntaxError
|
33
|
-
rescue SystemCallError # file not found or something
|
34
|
-
rescue ArgumentError # eval'ed code
|
18
|
+
super + snippet
|
35
19
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
20
|
+
else
|
21
|
+
# This is a marker to let `DidYouMean::Correctable#original_message` skip
|
22
|
+
# the following method definition of `to_s`.
|
23
|
+
# See https://github.com/ruby/did_you_mean/pull/152
|
24
|
+
SKIP_TO_S_FOR_SUPER_LOOKUP = true
|
25
|
+
private_constant :SKIP_TO_S_FOR_SUPER_LOOKUP
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
msg = super
|
29
|
+
snippet = generate_snippet
|
30
|
+
if snippet != "" && !msg.include?(snippet)
|
31
|
+
msg + snippet
|
32
|
+
else
|
33
|
+
msg
|
34
|
+
end
|
40
35
|
end
|
41
|
-
|
42
|
-
msg
|
43
36
|
end
|
44
37
|
end
|
45
38
|
|
46
39
|
NameError.prepend(CoreExt)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
#TypeError.prepend(CoreExt)
|
51
|
-
#ArgumentError.prepend(CoreExt)
|
40
|
+
TypeError.prepend(CoreExt)
|
41
|
+
ArgumentError.prepend(CoreExt)
|
52
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: error_highlight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yusuke Endoh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: The gem enhances Exception#message by adding a short explanation where
|
14
14
|
the exception is raised
|
@@ -18,6 +18,7 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ".github/dependabot.yml"
|
21
22
|
- ".github/workflows/ruby.yml"
|
22
23
|
- ".gitignore"
|
23
24
|
- Gemfile
|
@@ -49,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
50
|
- !ruby/object:Gem::Version
|
50
51
|
version: '0'
|
51
52
|
requirements: []
|
52
|
-
rubygems_version: 3.3.
|
53
|
+
rubygems_version: 3.3.7
|
53
54
|
signing_key:
|
54
55
|
specification_version: 4
|
55
56
|
summary: Shows a one-line code snippet with an underline in the error backtrace
|