error_highlight 0.7.0 → 0.7.1
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/workflows/ruby.yml +3 -3
- data/.github/workflows/sync-ruby.yml +33 -0
- data/error_highlight.gemspec +1 -1
- data/lib/error_highlight/base.rb +157 -49
- data/lib/error_highlight/core_ext.rb +32 -3
- data/lib/error_highlight/formatter.rb +3 -3
- data/lib/error_highlight/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6a847df9db6582ba1912ba3a2a64a76ba18e38d43c38413ac885fb993cbce07
|
|
4
|
+
data.tar.gz: c6e6872fd7276af7fac719d173da9f07af9fed0760d05385d1b6b6217449b9f0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9699f20efc393a3fc7c09312a29818416bb255c3078c45a4a4f75deda3f2becefe415bc98565928a001ff88638433868d89656d9382b6b736a781f51d17e1901
|
|
7
|
+
data.tar.gz: 48410be2cb3bbfd0c241ded954d11c960abc551fc896c907ed05d6c49ea37ec116ee92556cd713c9b5fe2f033fe3eb16606e788b97a61196f97a2050f839ded2
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -13,7 +13,7 @@ jobs:
|
|
|
13
13
|
uses: ruby/actions/.github/workflows/ruby_versions.yml@master
|
|
14
14
|
with:
|
|
15
15
|
engine: cruby
|
|
16
|
-
min_version: 3.
|
|
16
|
+
min_version: 3.2
|
|
17
17
|
|
|
18
18
|
build:
|
|
19
19
|
needs: ruby-versions
|
|
@@ -22,7 +22,7 @@ jobs:
|
|
|
22
22
|
matrix:
|
|
23
23
|
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
|
|
24
24
|
steps:
|
|
25
|
-
- uses: actions/checkout@
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
26
|
- uses: ruby/setup-ruby@v1
|
|
27
27
|
with:
|
|
28
28
|
ruby-version: ${{ matrix.ruby }}
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
prism:
|
|
37
37
|
runs-on: ubuntu-latest
|
|
38
38
|
steps:
|
|
39
|
-
- uses: actions/checkout@
|
|
39
|
+
- uses: actions/checkout@v6
|
|
40
40
|
- uses: ruby/setup-ruby@v1
|
|
41
41
|
with:
|
|
42
42
|
ruby-version: head
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Sync ruby
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [master]
|
|
5
|
+
jobs:
|
|
6
|
+
sync:
|
|
7
|
+
name: Sync ruby
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
if: ${{ github.repository_owner == 'ruby' }}
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v6
|
|
12
|
+
|
|
13
|
+
- name: Create GitHub App token
|
|
14
|
+
id: app-token
|
|
15
|
+
uses: actions/create-github-app-token@v2
|
|
16
|
+
with:
|
|
17
|
+
app-id: 2060836
|
|
18
|
+
private-key: ${{ secrets.RUBY_SYNC_DEFAULT_GEMS_PRIVATE_KEY }}
|
|
19
|
+
owner: ruby
|
|
20
|
+
repositories: ruby
|
|
21
|
+
|
|
22
|
+
- name: Sync to ruby/ruby
|
|
23
|
+
uses: convictional/trigger-workflow-and-wait@v1.6.5
|
|
24
|
+
with:
|
|
25
|
+
owner: ruby
|
|
26
|
+
repo: ruby
|
|
27
|
+
workflow_file_name: sync_default_gems.yml
|
|
28
|
+
github_token: ${{ steps.app-token.outputs.token }}
|
|
29
|
+
ref: master
|
|
30
|
+
client_payload: |
|
|
31
|
+
{"gem":"${{ github.event.repository.name }}","before":"${{ github.event.before }}","after":"${{ github.event.after }}"}
|
|
32
|
+
propagate_failure: true
|
|
33
|
+
wait_interval: 10
|
data/error_highlight.gemspec
CHANGED
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.homepage = "https://github.com/ruby/error_highlight"
|
|
19
19
|
|
|
20
20
|
spec.license = "MIT"
|
|
21
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 3.
|
|
21
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.2.0")
|
|
22
22
|
|
|
23
23
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
24
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
data/lib/error_highlight/base.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
require_relative "version"
|
|
2
2
|
|
|
3
3
|
module ErrorHighlight
|
|
4
|
-
# Identify the code fragment
|
|
4
|
+
# Identify the code fragment where a given exception occurred.
|
|
5
5
|
#
|
|
6
6
|
# Options:
|
|
7
7
|
#
|
|
8
8
|
# point_type: :name | :args
|
|
9
|
-
# :name (default) points the method/variable name
|
|
10
|
-
# :args points the arguments of the method call
|
|
9
|
+
# :name (default) points to the method/variable name where the exception occurred.
|
|
10
|
+
# :args points to the arguments of the method call where the exception occurred.
|
|
11
11
|
#
|
|
12
12
|
# backtrace_location: Thread::Backtrace::Location
|
|
13
13
|
# It locates the code fragment of the given backtrace_location.
|
|
@@ -113,7 +113,7 @@ module ErrorHighlight
|
|
|
113
113
|
snippet = @node.script_lines[lineno - 1 .. last_lineno - 1].join("")
|
|
114
114
|
snippet += "\n" unless snippet.end_with?("\n")
|
|
115
115
|
|
|
116
|
-
# It
|
|
116
|
+
# It requires some work to support Unicode (or multibyte) characters.
|
|
117
117
|
# Tentatively, we stop highlighting if the code snippet has non-ascii characters.
|
|
118
118
|
# See https://github.com/ruby/error_highlight/issues/4
|
|
119
119
|
raise NonAscii unless snippet.ascii_only?
|
|
@@ -122,56 +122,51 @@ module ErrorHighlight
|
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
OPT_GETCONSTANT_PATH = (RUBY_VERSION.split(".").map {|s| s.to_i } <=> [3, 2]) >= 0
|
|
126
|
-
private_constant :OPT_GETCONSTANT_PATH
|
|
127
|
-
|
|
128
125
|
def spot
|
|
129
126
|
return nil unless @node
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if node.
|
|
148
|
-
if node.children.first == @name
|
|
149
|
-
subnodes << node
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# If we found only one sub-node whose name is equal to @name, use it
|
|
153
|
-
return nil if subnodes.size != 1
|
|
154
|
-
@node = subnodes.first
|
|
155
|
-
else
|
|
156
|
-
# Do nothing; opt_getconstant_path is used only when the const base is
|
|
157
|
-
# NODE_CONST (`Foo`) or NODE_COLON3 (`::Foo`)
|
|
158
|
-
end
|
|
159
|
-
when :constant_path_node
|
|
160
|
-
subnodes = []
|
|
161
|
-
node = @node
|
|
162
|
-
|
|
163
|
-
begin
|
|
164
|
-
subnodes << node if node.name == @name
|
|
165
|
-
end while (node = node.parent).is_a?(Prism::ConstantPathNode)
|
|
166
|
-
|
|
167
|
-
if node.is_a?(Prism::ConstantReadNode) && node.name == @name
|
|
128
|
+
# In Ruby 3.2 or later, a nested constant access (like `Foo::Bar::Baz`)
|
|
129
|
+
# is compiled to one instruction (opt_getconstant_path).
|
|
130
|
+
# @node points to the node of the whole `Foo::Bar::Baz` even if `Foo`
|
|
131
|
+
# or `Foo::Bar` causes NameError.
|
|
132
|
+
# So we try to spot the sub-node that causes the NameError by using
|
|
133
|
+
# `NameError#name`.
|
|
134
|
+
case @node.type
|
|
135
|
+
when :COLON2
|
|
136
|
+
subnodes = []
|
|
137
|
+
node = @node
|
|
138
|
+
while node.type == :COLON2
|
|
139
|
+
node2, const = node.children
|
|
140
|
+
subnodes << node if const == @name
|
|
141
|
+
node = node2
|
|
142
|
+
end
|
|
143
|
+
if node.type == :CONST || node.type == :COLON3
|
|
144
|
+
if node.children.first == @name
|
|
168
145
|
subnodes << node
|
|
169
146
|
end
|
|
170
147
|
|
|
171
148
|
# If we found only one sub-node whose name is equal to @name, use it
|
|
172
149
|
return nil if subnodes.size != 1
|
|
173
150
|
@node = subnodes.first
|
|
151
|
+
else
|
|
152
|
+
# Do nothing; opt_getconstant_path is used only when the const base is
|
|
153
|
+
# NODE_CONST (`Foo`) or NODE_COLON3 (`::Foo`)
|
|
174
154
|
end
|
|
155
|
+
when :constant_path_node
|
|
156
|
+
subnodes = []
|
|
157
|
+
node = @node
|
|
158
|
+
|
|
159
|
+
begin
|
|
160
|
+
subnodes << node if node.name == @name
|
|
161
|
+
end while (node = node.parent).is_a?(Prism::ConstantPathNode)
|
|
162
|
+
|
|
163
|
+
if node.is_a?(Prism::ConstantReadNode) && node.name == @name
|
|
164
|
+
subnodes << node
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# If we found only one sub-node whose name is equal to @name, use it
|
|
168
|
+
return nil if subnodes.size != 1
|
|
169
|
+
@node = subnodes.first
|
|
175
170
|
end
|
|
176
171
|
|
|
177
172
|
case @node.type
|
|
@@ -239,6 +234,20 @@ module ErrorHighlight
|
|
|
239
234
|
when :OP_CDECL
|
|
240
235
|
spot_op_cdecl
|
|
241
236
|
|
|
237
|
+
when :DEFN
|
|
238
|
+
raise NotImplementedError if @point_type != :name
|
|
239
|
+
spot_defn
|
|
240
|
+
|
|
241
|
+
when :DEFS
|
|
242
|
+
raise NotImplementedError if @point_type != :name
|
|
243
|
+
spot_defs
|
|
244
|
+
|
|
245
|
+
when :LAMBDA
|
|
246
|
+
spot_lambda
|
|
247
|
+
|
|
248
|
+
when :ITER
|
|
249
|
+
spot_iter
|
|
250
|
+
|
|
242
251
|
when :call_node
|
|
243
252
|
case @point_type
|
|
244
253
|
when :name
|
|
@@ -280,6 +289,30 @@ module ErrorHighlight
|
|
|
280
289
|
when :constant_path_operator_write_node
|
|
281
290
|
prism_spot_constant_path_operator_write
|
|
282
291
|
|
|
292
|
+
when :def_node
|
|
293
|
+
case @point_type
|
|
294
|
+
when :name
|
|
295
|
+
prism_spot_def_for_name
|
|
296
|
+
when :args
|
|
297
|
+
raise NotImplementedError
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
when :lambda_node
|
|
301
|
+
case @point_type
|
|
302
|
+
when :name
|
|
303
|
+
prism_spot_lambda_for_name
|
|
304
|
+
when :args
|
|
305
|
+
raise NotImplementedError
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
when :block_node
|
|
309
|
+
case @point_type
|
|
310
|
+
when :name
|
|
311
|
+
prism_spot_block_for_name
|
|
312
|
+
when :args
|
|
313
|
+
raise NotImplementedError
|
|
314
|
+
end
|
|
315
|
+
|
|
283
316
|
end
|
|
284
317
|
|
|
285
318
|
if @snippet && @beg_column && @end_column && @beg_column < @end_column
|
|
@@ -344,6 +377,7 @@ module ErrorHighlight
|
|
|
344
377
|
end
|
|
345
378
|
elsif mid.to_s =~ /\A\W+\z/ && lines.match(/\G\s*(#{ Regexp.quote(mid) })=.*\n/, nd_recv.last_column)
|
|
346
379
|
@snippet = $` + $&
|
|
380
|
+
@beg_lineno = @end_lineno = lineno
|
|
347
381
|
@beg_column = $~.begin(1)
|
|
348
382
|
@end_column = $~.end(1)
|
|
349
383
|
end
|
|
@@ -470,7 +504,6 @@ module ErrorHighlight
|
|
|
470
504
|
def spot_fcall_for_args
|
|
471
505
|
_mid, nd_args = @node.children
|
|
472
506
|
if nd_args && nd_args.first_lineno == nd_args.last_lineno
|
|
473
|
-
# binary operator
|
|
474
507
|
fetch_line(nd_args.first_lineno)
|
|
475
508
|
@beg_column = nd_args.first_column
|
|
476
509
|
@end_column = nd_args.last_column
|
|
@@ -582,8 +615,9 @@ module ErrorHighlight
|
|
|
582
615
|
@beg_column = nd_parent.last_column
|
|
583
616
|
@end_column = @node.last_column
|
|
584
617
|
else
|
|
585
|
-
@
|
|
618
|
+
fetch_line(@node.last_lineno)
|
|
586
619
|
if @snippet[...@node.last_column].match(/#{ Regexp.quote(const) }\z/)
|
|
620
|
+
@beg_lineno = @end_lineno = @node.last_lineno
|
|
587
621
|
@beg_column = $~.begin(0)
|
|
588
622
|
@end_column = $~.end(0)
|
|
589
623
|
end
|
|
@@ -597,7 +631,7 @@ module ErrorHighlight
|
|
|
597
631
|
nd_lhs, op, _nd_rhs = @node.children
|
|
598
632
|
*nd_parent_lhs, _const = nd_lhs.children
|
|
599
633
|
if @name == op
|
|
600
|
-
|
|
634
|
+
fetch_line(nd_lhs.last_lineno)
|
|
601
635
|
if @snippet.match(/\G\s*(#{ Regexp.quote(op) })=/, nd_lhs.last_column)
|
|
602
636
|
@beg_column = $~.begin(1)
|
|
603
637
|
@end_column = $~.end(1)
|
|
@@ -607,18 +641,67 @@ module ErrorHighlight
|
|
|
607
641
|
@end_column = nd_lhs.last_column
|
|
608
642
|
if nd_parent_lhs.empty? # example: ::C += 1
|
|
609
643
|
if nd_lhs.first_lineno == nd_lhs.last_lineno
|
|
610
|
-
|
|
644
|
+
fetch_line(nd_lhs.last_lineno)
|
|
611
645
|
@beg_column = nd_lhs.first_column
|
|
612
646
|
end
|
|
613
647
|
else # example: Foo::Bar::C += 1
|
|
614
648
|
if nd_parent_lhs.last.last_lineno == nd_lhs.last_lineno
|
|
615
|
-
|
|
649
|
+
fetch_line(nd_lhs.last_lineno)
|
|
616
650
|
@beg_column = nd_parent_lhs.last.last_column
|
|
617
651
|
end
|
|
618
652
|
end
|
|
619
653
|
end
|
|
620
654
|
end
|
|
621
655
|
|
|
656
|
+
# Example:
|
|
657
|
+
# def bar; end
|
|
658
|
+
# ^^^
|
|
659
|
+
def spot_defn
|
|
660
|
+
mid, = @node.children
|
|
661
|
+
fetch_line(@node.first_lineno)
|
|
662
|
+
if @snippet.match(/\Gdef\s+(#{ Regexp.quote(mid) }\b)/, @node.first_column)
|
|
663
|
+
@beg_column = $~.begin(1)
|
|
664
|
+
@end_column = $~.end(1)
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
# Example:
|
|
669
|
+
# def Foo.bar; end
|
|
670
|
+
# ^^^^
|
|
671
|
+
def spot_defs
|
|
672
|
+
nd_recv, mid, = @node.children
|
|
673
|
+
fetch_line(nd_recv.last_lineno)
|
|
674
|
+
if @snippet.match(/\G\s*(\.\s*#{ Regexp.quote(mid) }\b)/, nd_recv.last_column)
|
|
675
|
+
@beg_column = $~.begin(1)
|
|
676
|
+
@end_column = $~.end(1)
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
# Example:
|
|
681
|
+
# -> { ... }
|
|
682
|
+
# ^^
|
|
683
|
+
def spot_lambda
|
|
684
|
+
fetch_line(@node.first_lineno)
|
|
685
|
+
if @snippet.match(/\G->/, @node.first_column)
|
|
686
|
+
@beg_column = $~.begin(0)
|
|
687
|
+
@end_column = $~.end(0)
|
|
688
|
+
end
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
# Example:
|
|
692
|
+
# lambda { ... }
|
|
693
|
+
# ^
|
|
694
|
+
# define_method :foo do
|
|
695
|
+
# ^^
|
|
696
|
+
def spot_iter
|
|
697
|
+
_nd_fcall, nd_scope = @node.children
|
|
698
|
+
fetch_line(nd_scope.first_lineno)
|
|
699
|
+
if @snippet.match(/\G(?:do\b|\{)/, nd_scope.first_column)
|
|
700
|
+
@beg_column = $~.begin(0)
|
|
701
|
+
@end_column = $~.end(0)
|
|
702
|
+
end
|
|
703
|
+
end
|
|
704
|
+
|
|
622
705
|
def fetch_line(lineno)
|
|
623
706
|
@beg_lineno = @end_lineno = lineno
|
|
624
707
|
@snippet = @fetch[lineno]
|
|
@@ -824,6 +907,31 @@ module ErrorHighlight
|
|
|
824
907
|
prism_location(@node.binary_operator_loc.chop)
|
|
825
908
|
end
|
|
826
909
|
end
|
|
910
|
+
|
|
911
|
+
# Example:
|
|
912
|
+
# def foo()
|
|
913
|
+
# ^^^
|
|
914
|
+
def prism_spot_def_for_name
|
|
915
|
+
location = @node.name_loc
|
|
916
|
+
location = @node.operator_loc.join(location) if @node.operator_loc
|
|
917
|
+
prism_location(location)
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
# Example:
|
|
921
|
+
# -> x, y { }
|
|
922
|
+
# ^^
|
|
923
|
+
def prism_spot_lambda_for_name
|
|
924
|
+
prism_location(@node.operator_loc)
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
# Example:
|
|
928
|
+
# lambda { }
|
|
929
|
+
# ^
|
|
930
|
+
# define_method :foo do |x, y|
|
|
931
|
+
# ^
|
|
932
|
+
def prism_spot_block_for_name
|
|
933
|
+
prism_location(@node.opening_loc)
|
|
934
|
+
end
|
|
827
935
|
end
|
|
828
936
|
|
|
829
937
|
private_constant :Spotter
|
|
@@ -3,9 +3,38 @@ require_relative "formatter"
|
|
|
3
3
|
module ErrorHighlight
|
|
4
4
|
module CoreExt
|
|
5
5
|
private def generate_snippet
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
if ArgumentError === self && message =~ /\A(?:wrong number of arguments|missing keyword[s]?|unknown keyword[s]?|no keywords accepted)\b/
|
|
7
|
+
locs = self.backtrace_locations
|
|
8
|
+
return "" if locs.size < 2
|
|
9
|
+
callee_loc, caller_loc = locs
|
|
10
|
+
callee_spot = ErrorHighlight.spot(self, backtrace_location: callee_loc, point_type: :name)
|
|
11
|
+
caller_spot = ErrorHighlight.spot(self, backtrace_location: caller_loc, point_type: :name)
|
|
12
|
+
if caller_spot && callee_spot &&
|
|
13
|
+
caller_loc.path == callee_loc.path &&
|
|
14
|
+
caller_loc.lineno == callee_loc.lineno &&
|
|
15
|
+
caller_spot == callee_spot
|
|
16
|
+
callee_loc = callee_spot = nil
|
|
17
|
+
end
|
|
18
|
+
ret = +"\n"
|
|
19
|
+
[["caller", caller_loc, caller_spot], ["callee", callee_loc, callee_spot]].each do |header, loc, spot|
|
|
20
|
+
out = nil
|
|
21
|
+
if loc
|
|
22
|
+
out = " #{ header }: #{ loc.path }:#{ loc.lineno }"
|
|
23
|
+
if spot
|
|
24
|
+
_, _, snippet, highlight = ErrorHighlight.formatter.message_for(spot).lines
|
|
25
|
+
out += "\n | #{ snippet } #{ highlight }"
|
|
26
|
+
else
|
|
27
|
+
# do nothing
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
ret << "\n" + out if out
|
|
31
|
+
end
|
|
32
|
+
ret
|
|
33
|
+
else
|
|
34
|
+
spot = ErrorHighlight.spot(self)
|
|
35
|
+
return "" unless spot
|
|
36
|
+
return ErrorHighlight.formatter.message_for(spot)
|
|
37
|
+
end
|
|
9
38
|
end
|
|
10
39
|
|
|
11
40
|
if Exception.method_defined?(:detailed_message)
|
|
@@ -56,11 +56,11 @@ module ErrorHighlight
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def self.terminal_width
|
|
59
|
-
# lazy load io/console
|
|
59
|
+
# lazy load io/console to avoid loading it when 'max_snippet_width' is manually set
|
|
60
60
|
require "io/console"
|
|
61
|
-
|
|
61
|
+
$stderr.winsize[1] if $stderr.tty?
|
|
62
62
|
rescue LoadError, NoMethodError, SystemCallError
|
|
63
|
-
#
|
|
63
|
+
# skip truncation when terminal window size is unavailable
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: error_highlight
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
|
-
original_platform: ''
|
|
7
6
|
authors:
|
|
8
7
|
- Yusuke Endoh
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
12
|
description: The gem enhances Exception#message by adding a short explanation where
|
|
14
13
|
the exception is raised
|
|
@@ -20,6 +19,7 @@ extra_rdoc_files: []
|
|
|
20
19
|
files:
|
|
21
20
|
- ".github/dependabot.yml"
|
|
22
21
|
- ".github/workflows/ruby.yml"
|
|
22
|
+
- ".github/workflows/sync-ruby.yml"
|
|
23
23
|
- ".gitignore"
|
|
24
24
|
- Gemfile
|
|
25
25
|
- LICENSE.txt
|
|
@@ -42,14 +42,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
42
42
|
requirements:
|
|
43
43
|
- - ">="
|
|
44
44
|
- !ruby/object:Gem::Version
|
|
45
|
-
version: 3.
|
|
45
|
+
version: 3.2.0
|
|
46
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
47
|
requirements:
|
|
48
48
|
- - ">="
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
50
|
version: '0'
|
|
51
51
|
requirements: []
|
|
52
|
-
rubygems_version:
|
|
52
|
+
rubygems_version: 4.0.1
|
|
53
53
|
specification_version: 4
|
|
54
54
|
summary: Shows a one-line code snippet with an underline in the error backtrace
|
|
55
55
|
test_files: []
|