eturem 0.4.0 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +9 -9
- data/CODE_OF_CONDUCT.md +74 -74
- data/Gemfile +7 -6
- data/LICENSE.txt +21 -21
- data/README.ja.md +223 -180
- data/README.md +31 -27
- data/Rakefile +11 -11
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/eturem.gemspec +30 -36
- data/exe/eturem +15 -0
- data/lib/eturem.rb +79 -42
- data/lib/eturem/base.rb +262 -259
- data/lib/eturem/en.rb +1 -215
- data/lib/eturem/en/main.rb +215 -0
- data/lib/eturem/en/warning.rb +11 -0
- data/lib/eturem/ja.rb +1 -382
- data/lib/eturem/ja/argument_error.rb +56 -0
- data/lib/eturem/ja/dxruby_error.rb +13 -0
- data/lib/eturem/ja/error_enoent.rb +19 -0
- data/lib/eturem/ja/interrupt.rb +12 -0
- data/lib/eturem/ja/load_error.rb +14 -0
- data/lib/eturem/ja/main.rb +222 -0
- data/lib/eturem/ja/name_error.rb +50 -0
- data/lib/eturem/ja/no_memory_error.rb +12 -0
- data/lib/eturem/ja/syntax_error.rb +88 -0
- data/lib/eturem/ja/system_stack_error.rb +10 -0
- data/lib/eturem/ja/type_error.rb +13 -0
- data/lib/eturem/ja/uncaught_throw_error.rb +11 -0
- data/lib/eturem/ja/warning.rb +42 -0
- data/lib/eturem/ja/zero_division_error.rb +10 -0
- data/lib/eturem/version.rb +3 -3
- data/lib/eturem/warning.rb +13 -0
- metadata +31 -52
data/README.md
CHANGED
@@ -1,27 +1,31 @@
|
|
1
|
-
# Eturem
|
2
|
-
|
3
|
-
Easy To Understand Ruby Error Message.
|
4
|
-
|
5
|
-
[日本語説明(こちらの方が詳細)](https://github.com/nodai2hITC/eturem/blob/master/README.ja.md)
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
install it yourself as:
|
10
|
-
|
11
|
-
$ gem install eturem
|
12
|
-
|
13
|
-
## Usage
|
14
|
-
|
15
|
-
$ ruby -returem <your_script.rb>
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
##
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
##
|
26
|
-
|
27
|
-
|
1
|
+
# Eturem
|
2
|
+
|
3
|
+
Easy To Understand Ruby Error Message.
|
4
|
+
|
5
|
+
[日本語説明(こちらの方が詳細)](https://github.com/nodai2hITC/eturem/blob/master/README.ja.md)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
install it yourself as:
|
10
|
+
|
11
|
+
$ gem install eturem
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
$ ruby -returem <your_script.rb>
|
16
|
+
|
17
|
+
or
|
18
|
+
|
19
|
+
$ eturem <your_script.rb>
|
20
|
+
|
21
|
+
## Contributing
|
22
|
+
|
23
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/nodai2hITC/eturem. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
24
|
+
|
25
|
+
## License
|
26
|
+
|
27
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
28
|
+
|
29
|
+
## Code of Conduct
|
30
|
+
|
31
|
+
Everyone interacting in the Eturem project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/nodai2hITC/eturem/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
require "rake/testtask"
|
3
|
-
|
4
|
-
Rake::TestTask.new(:test) do |t|
|
5
|
-
t.libs << "test"
|
6
|
-
t.libs << "lib"
|
7
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
-
t.warning = false
|
9
|
-
end
|
10
|
-
|
11
|
-
task :default => :test
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
+
t.warning = false
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => :test
|
data/bin/console
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "eturem"
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "eturem"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
set -euo pipefail
|
3
|
-
IFS=$'\n\t'
|
4
|
-
set -vx
|
5
|
-
|
6
|
-
bundle install
|
7
|
-
|
8
|
-
# Do any other automated setup that you need to do here
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
set -euo pipefail
|
3
|
+
IFS=$'\n\t'
|
4
|
+
set -vx
|
5
|
+
|
6
|
+
bundle install
|
7
|
+
|
8
|
+
# Do any other automated setup that you need to do here
|
data/eturem.gemspec
CHANGED
@@ -1,36 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
spec.
|
8
|
-
spec.
|
9
|
-
|
10
|
-
spec.
|
11
|
-
|
12
|
-
spec.
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
spec.
|
30
|
-
|
31
|
-
spec.require_paths = ["lib"]
|
32
|
-
|
33
|
-
spec.add_development_dependency "bundler", "~> 1.16"
|
34
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
-
spec.add_development_dependency "minitest", "~> 5.0"
|
36
|
-
end
|
1
|
+
|
2
|
+
require_relative 'lib/eturem/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "eturem"
|
6
|
+
spec.version = Eturem::VERSION
|
7
|
+
spec.authors = ["nodai2hITC"]
|
8
|
+
spec.email = ["nodai2h.itc@gmail.com"]
|
9
|
+
|
10
|
+
spec.summary = %q{Easy To Understand Ruby Error Message.}
|
11
|
+
spec.description = %q{Easy To Understand Ruby Error Message.}
|
12
|
+
spec.homepage = "https://github.com/nodai2hITC/eturem"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
15
|
+
|
16
|
+
# spec.metadata["allowed_push_host"] = "Set to 'http://mygemserver.com'"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
20
|
+
# spec.metadata["changelog_uri"] = spec.homepage
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
end
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
end
|
data/exe/eturem
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lang = nil
|
4
|
+
if ARGV.first.to_s =~ /^lang=(.+)$/
|
5
|
+
lang = $1
|
6
|
+
ARGV.shift
|
7
|
+
end
|
8
|
+
|
9
|
+
if ARGV.empty?
|
10
|
+
puts "usage: eturem (lang=**) script.rb"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
|
14
|
+
$PROGRAM_NAME = ARGV.shift
|
15
|
+
require lang ? "eturem/#{lang}" : "eturem"
|
data/lib/eturem.rb
CHANGED
@@ -1,42 +1,79 @@
|
|
1
|
-
enable = true
|
2
|
-
debug = false
|
3
|
-
lang = "en"
|
4
|
-
output_backtrace = true
|
5
|
-
output_original = true
|
6
|
-
output_script = true
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
1
|
+
enable = true
|
2
|
+
debug = false
|
3
|
+
lang = "en"
|
4
|
+
output_backtrace = true
|
5
|
+
output_original = true
|
6
|
+
output_script = true
|
7
|
+
override_warning = true
|
8
|
+
use_coderay = false
|
9
|
+
before_line_num = 2
|
10
|
+
after_line_num = 2
|
11
|
+
repl = nil
|
12
|
+
|
13
|
+
config_file = File.exist?("./.eturem") ? "./.eturem" : File.join(Dir.home, ".eturem")
|
14
|
+
if File.exist?(config_file)
|
15
|
+
config = File.read(config_file).gsub(/#.*/, "")
|
16
|
+
enable = false if config.match(/^enable\s*\:\s*(?:false|off|0)/i)
|
17
|
+
debug = true if config.match(/^debug\s*\:\s*(?:true|on|1)/i)
|
18
|
+
lang = Regexp.last_match(:lang) if config.match(/^lang\s*\:\s*(?<lang>\S+)/i)
|
19
|
+
output_backtrace = false if config.match(/^output_backtrace\s*\:\s*(?:false|off|0)/i)
|
20
|
+
output_original = false if config.match( /^output_original\s*\:\s*(?:false|off|0)/i)
|
21
|
+
output_script = false if config.match( /^output_script\s*\:\s*(?:false|off|0)/i)
|
22
|
+
override_warning = false if config.match(/^override_warning\s*\:\s*(?:false|off|0)/i)
|
23
|
+
use_coderay = true if config.match( /^use_coderay\s*\:\s*(?:true|on|1)/i)
|
24
|
+
before_line_num = Regexp.last_match(:num).to_i if config.match(/^before_line_num\s*\:\s*(?<num>\d+)/i)
|
25
|
+
after_line_num = Regexp.last_match(:num).to_i if config.match( /^after_line_num\s*\:\s*(?<num>\d+)/i)
|
26
|
+
repl = Regexp.last_match(:repl).downcase if config.match(/^repl\s*\:\s*(?<repl>irb|pry)/i)
|
27
|
+
end
|
28
|
+
|
29
|
+
if enable
|
30
|
+
require "eturem/#{lang}/main" unless defined?(Eturem)
|
31
|
+
require "eturem/warning" if override_warning
|
32
|
+
Eturem::Base.output_backtrace = output_backtrace
|
33
|
+
Eturem::Base.output_original = output_original
|
34
|
+
Eturem::Base.output_script = output_script
|
35
|
+
Eturem::Base.use_coderay = use_coderay
|
36
|
+
Eturem::Base.before_line_num = before_line_num
|
37
|
+
Eturem::Base.after_line_num = after_line_num
|
38
|
+
|
39
|
+
if File.exist?($PROGRAM_NAME)
|
40
|
+
program_file = File.open($PROGRAM_NAME, "rb")
|
41
|
+
script = program_file.read
|
42
|
+
if script.match(/^__END__\R/)
|
43
|
+
program_file.pos = Regexp.last_match.end(0)
|
44
|
+
encoding = "utf-8"
|
45
|
+
if script.match(/\A(?:#!.*\R)?#.*coding *[:=] *(?<encoding>[^\s:]+)/)
|
46
|
+
encoding = Regexp.last_match(:encoding)
|
47
|
+
end
|
48
|
+
program_file.set_encoding(encoding)
|
49
|
+
Object.const_set(:DATA, program_file)
|
50
|
+
program_file
|
51
|
+
else
|
52
|
+
program_file.close
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
eturem_path = File.expand_path("..", __FILE__)
|
57
|
+
last_binding = nil
|
58
|
+
tracepoint = TracePoint.trace(:raise) do |tp|
|
59
|
+
last_binding = tp.binding unless File.expand_path(tp.path).start_with?(eturem_path)
|
60
|
+
end
|
61
|
+
exception = Eturem.load(File.expand_path(Eturem.program_name))
|
62
|
+
tracepoint.disable
|
63
|
+
|
64
|
+
if exception.is_a?(Exception)
|
65
|
+
begin
|
66
|
+
Eturem.extend_exception(exception)
|
67
|
+
$stderr.write exception.eturem_full_message
|
68
|
+
rescue Exception => e
|
69
|
+
raise debug ? e : exception
|
70
|
+
end
|
71
|
+
|
72
|
+
repl ||= $eturem_repl if defined?($eturem_repl)
|
73
|
+
if repl && last_binding && exception.is_a?(StandardError)
|
74
|
+
require repl
|
75
|
+
last_binding.public_send(repl)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
exit
|
79
|
+
end
|
data/lib/eturem/base.rb
CHANGED
@@ -1,309 +1,312 @@
|
|
1
1
|
require "eturem/version"
|
2
2
|
|
3
3
|
module Eturem
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Kernel.load(file)
|
12
|
-
rescue Exception => exception
|
13
|
-
raise exception if exception.is_a? SystemExit
|
14
|
-
eturem.exception = exception
|
15
|
-
end
|
16
|
-
eturem.exception ? eturem : nil
|
4
|
+
@program_name = $PROGRAM_NAME.encode("utf-8")
|
5
|
+
|
6
|
+
def self.rescue
|
7
|
+
yield
|
8
|
+
rescue Exception => exception
|
9
|
+
raise exception if exception.is_a? SystemExit
|
10
|
+
exception
|
17
11
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
begin
|
27
|
-
TOPLEVEL_BINDING.eval(script, file, 1)
|
28
|
-
tp.disable
|
29
|
-
eturem.comeback_stderr
|
30
|
-
rescue Exception => exception
|
31
|
-
tp.disable
|
32
|
-
eturem.comeback_stderr
|
33
|
-
raise exception if exception.is_a? SystemExit
|
34
|
-
repl ||= $eturem_repl
|
35
|
-
use_repl = repl && last_binding && exception.is_a?(StandardError)
|
36
|
-
begin
|
37
|
-
eturem.exception = exception
|
38
|
-
$stderr.write eturem.inspect
|
39
|
-
rescue Exception => e
|
40
|
-
raise debug ? e : eturem.exception
|
41
|
-
end
|
42
|
-
return unless use_repl
|
43
|
-
require repl
|
44
|
-
last_binding.public_send(repl)
|
12
|
+
|
13
|
+
# load script and return exception if exception raised
|
14
|
+
# @param [String] filename script file
|
15
|
+
# @return [Exception] if exception raised
|
16
|
+
# @return [true] if exception did not raise
|
17
|
+
def self.load(filename, wrap = false)
|
18
|
+
self.rescue do
|
19
|
+
Kernel.load(filename, wrap)
|
45
20
|
end
|
46
21
|
end
|
47
|
-
|
22
|
+
|
48
23
|
def self.eval(expr, bind = nil, fname = "(eval)", lineno = 1)
|
49
|
-
|
50
|
-
begin
|
24
|
+
self.rescue do
|
51
25
|
bind ? Kernel.eval(expr, bind, fname, lineno) : Kernel.eval(expr)
|
52
|
-
rescue Exception => exception
|
53
|
-
raise exception if exception.is_a? SystemExit
|
54
|
-
eturem.exception = exception
|
55
26
|
end
|
56
|
-
return eturem.exception ? eturem : nil
|
57
27
|
end
|
58
|
-
|
59
|
-
def self.
|
60
|
-
|
28
|
+
|
29
|
+
def self.extend_exception(exception)
|
30
|
+
ext = _extend_exception(exception) ||
|
31
|
+
case exception
|
32
|
+
when SyntaxError then SyntaxErrorExt
|
33
|
+
when NameError then NameErrorExt
|
34
|
+
when ArgumentError then ArgumentErrorExt
|
35
|
+
else ExceptionExt
|
36
|
+
end
|
37
|
+
exception.extend ext
|
38
|
+
exception.eturem_prepare
|
61
39
|
end
|
62
|
-
|
63
|
-
def self.
|
64
|
-
|
65
|
-
if File.exist?(file)
|
66
|
-
script = File.binread(file)
|
67
|
-
encoding = "utf-8"
|
68
|
-
if script.match(/\A(?:#!.*\R)?#.*coding *[:=] *(?<encoding>[^\s:]+)/)
|
69
|
-
encoding = Regexp.last_match(:encoding)
|
70
|
-
end
|
71
|
-
script.force_encoding(encoding)
|
72
|
-
end
|
73
|
-
return script
|
40
|
+
|
41
|
+
def self.program_name
|
42
|
+
@program_name
|
74
43
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
@@
|
80
|
-
@@
|
81
|
-
@@
|
82
|
-
@@
|
83
|
-
@@
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
def self.inspect_methods
|
89
|
-
return @inspect_methods
|
44
|
+
|
45
|
+
|
46
|
+
module Base
|
47
|
+
@@eturem_output_backtrace = true
|
48
|
+
@@eturem_output_original = true
|
49
|
+
@@eturem_output_script = true
|
50
|
+
@@eturem_use_coderay = false
|
51
|
+
@@eturem_before_line_num = 2
|
52
|
+
@@eturem_after_line_num = 2
|
53
|
+
|
54
|
+
def self.output_backtrace=(value)
|
55
|
+
@@eturem_output_backtrace = value
|
90
56
|
end
|
91
|
-
|
92
|
-
def self.
|
93
|
-
@@
|
94
|
-
@@output_original = config[:output_original] if config.has_key?(:output_original)
|
95
|
-
@@output_script = config[:output_script] if config.has_key?(:output_script)
|
96
|
-
@@use_coderay = config[:use_coderay] if config.has_key?(:use_coderay)
|
97
|
-
@@before_line_num = config[:before_line_num] if config.has_key?(:before_line_num)
|
98
|
-
@@after_line_num = config[:after_line_num] if config.has_key?(:after_line_num)
|
57
|
+
|
58
|
+
def self.output_original=(value)
|
59
|
+
@@eturem_output_original = value
|
99
60
|
end
|
100
|
-
|
101
|
-
def
|
102
|
-
|
103
|
-
@scripts = {}
|
104
|
-
@decoration = {}
|
105
|
-
if replace_stderr
|
106
|
-
@stderr = $stderr
|
107
|
-
$stderr = self
|
108
|
-
end
|
61
|
+
|
62
|
+
def self.output_script=(value)
|
63
|
+
@@eturem_output_script = value
|
109
64
|
end
|
110
|
-
|
111
|
-
def
|
112
|
-
|
113
|
-
@exception_s = exception.to_s
|
114
|
-
|
115
|
-
eturem_path = File.dirname(File.expand_path(__FILE__))
|
116
|
-
@backtrace_locations = (@exception.backtrace_locations || []).reject do |location|
|
117
|
-
path = File.expand_path(location.path)
|
118
|
-
path.start_with?(eturem_path) || path.end_with?("/rubygems/core_ext/kernel_require.rb")
|
119
|
-
end
|
120
|
-
|
121
|
-
if @exception.is_a?(SyntaxError) && @exception_s.match(/\A(?<path>.+?)\:(?<lineno>\d+)/)
|
122
|
-
@path = Regexp.last_match(:path)
|
123
|
-
@lineno = Regexp.last_match(:lineno).to_i
|
124
|
-
else
|
125
|
-
backtrace_locations_shift
|
126
|
-
end
|
127
|
-
|
128
|
-
@script_lines = read_script(@path) || []
|
129
|
-
@output_linenos = default_output_linenos
|
130
|
-
prepare
|
65
|
+
|
66
|
+
def self.use_coderay=(value)
|
67
|
+
@@eturem_use_coderay = value
|
131
68
|
end
|
132
|
-
|
133
|
-
def
|
134
|
-
|
135
|
-
error_message = exception_inspect
|
136
|
-
if error_message.empty?
|
137
|
-
str << original_exception_inspect
|
138
|
-
else
|
139
|
-
str = "#{original_exception_inspect}\n#{str}" if @@output_original
|
140
|
-
str << "#{error_message}\n"
|
141
|
-
end
|
142
|
-
str << script_inspect if @@output_script
|
143
|
-
return str
|
69
|
+
|
70
|
+
def self.before_line_num=(value)
|
71
|
+
@@eturem_before_line_num = value
|
144
72
|
end
|
145
|
-
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
str = "#{traceback_most_recent_call_last}\n"
|
150
|
-
backtraces = []
|
151
|
-
size = @backtrace_locations.size
|
152
|
-
format = "%#{8 + size.to_s.length}d: %s\n"
|
153
|
-
@backtrace_locations.reverse.each_with_index do |location, i|
|
154
|
-
backtraces.push(sprintf(format, size - i, location_inspect(location)))
|
155
|
-
end
|
156
|
-
|
157
|
-
if @exception_s == "stack level too deep"
|
158
|
-
str << backtraces[0..7].join
|
159
|
-
str << " ... #{backtraces.size - 12} levels...\n"
|
160
|
-
str << backtraces[-4..-1].join
|
161
|
-
else
|
162
|
-
str << backtraces.join
|
163
|
-
end
|
164
|
-
return str
|
73
|
+
|
74
|
+
def self.after_line_num=(value)
|
75
|
+
@@eturem_after_line_num = value
|
165
76
|
end
|
166
|
-
|
167
|
-
def
|
168
|
-
|
169
|
-
inspect_methods.keys.reverse_each do |key|
|
170
|
-
if (key.is_a?(Class) && @exception.is_a?(key)) ||
|
171
|
-
(key.is_a?(String) && @exception.class.to_s == key)
|
172
|
-
method = inspect_methods[key]
|
173
|
-
return method ? public_send(method) : ""
|
174
|
-
end
|
175
|
-
end
|
176
|
-
return ""
|
77
|
+
|
78
|
+
def self.highlight(str, pattern, highlight)
|
79
|
+
str.sub!(pattern) { "#{highlight}#{$1 || $&}\e[0m#{$2}" } if str
|
177
80
|
end
|
178
|
-
|
179
|
-
def
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
81
|
+
|
82
|
+
def self.unhighlight(str)
|
83
|
+
str.gsub(/\e\[[0-9;]*m/, "")
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.read_script(filename)
|
87
|
+
return [] unless File.exist?(filename)
|
88
|
+
script = File.binread(filename)
|
89
|
+
encoding = "utf-8"
|
90
|
+
if script.match(/\A(?:#!.*\R)?#.*coding *[:=] *(?<encoding>[^\s:]+)/)
|
91
|
+
encoding = Regexp.last_match(:encoding)
|
187
92
|
end
|
93
|
+
script.force_encoding(encoding).encode!("utf-8")
|
94
|
+
if @@eturem_use_coderay
|
95
|
+
require "coderay"
|
96
|
+
script = CodeRay.scan(script, :ruby).terminal
|
97
|
+
end
|
98
|
+
[""] + script.lines(chomp: true)
|
188
99
|
end
|
189
|
-
|
190
|
-
def
|
191
|
-
script_lines = read_script(path)
|
192
|
-
return "" unless script_lines
|
193
|
-
|
100
|
+
|
101
|
+
def self.script(lines, linenos, lineno)
|
194
102
|
str = ""
|
195
103
|
max_lineno_length = linenos.max.to_s.length
|
196
|
-
last_i = linenos.min - 1
|
104
|
+
last_i = linenos.min.to_i - 1
|
197
105
|
linenos.uniq.sort.each do |i|
|
198
|
-
line =
|
199
|
-
|
200
|
-
str
|
201
|
-
str
|
202
|
-
str
|
106
|
+
line = lines[i]
|
107
|
+
next unless line
|
108
|
+
str += " #{' ' * max_lineno_length} :\n" if last_i + 1 != i
|
109
|
+
str += (lineno == i ? " => " : " ")
|
110
|
+
str += sprintf("\e[1;34m%#{max_lineno_length}d\e[0m: %s\e[0m\n", i, line)
|
203
111
|
last_i = i
|
204
112
|
end
|
205
|
-
|
113
|
+
str
|
206
114
|
end
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
115
|
+
|
116
|
+
|
117
|
+
def eturem_prepare
|
118
|
+
this_dirpath = File.dirname(File.expand_path(__FILE__))
|
119
|
+
@eturem_backtrace_locations = (self.backtrace_locations || []).reject do |location|
|
120
|
+
File.expand_path(location.path).start_with?(this_dirpath) ||
|
121
|
+
location.path.end_with?(
|
122
|
+
"/rubygems/core_ext/kernel_require.rb",
|
123
|
+
"/rubygems/core_ext/kernel_require.rb>"
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
program_filepath = File.expand_path(Eturem.program_name)
|
128
|
+
@eturem_backtrace_locations.each do |location|
|
129
|
+
if File.expand_path(location.path) == program_filepath
|
130
|
+
def location.path; Eturem.program_name; end
|
131
|
+
if location.label == "<top (required)>"
|
132
|
+
def location.label; "<main>"; end
|
133
|
+
end
|
134
|
+
end
|
213
135
|
end
|
214
|
-
|
215
|
-
|
136
|
+
|
137
|
+
@eturem_message = self.message
|
138
|
+
unless @eturem_message.encoding == Encoding::UTF_8
|
139
|
+
@eturem_message.force_encoding("utf-8")
|
140
|
+
unless @eturem_message.valid_encoding?
|
141
|
+
@eturem_message.force_encoding(Encoding.locale_charmap).encode!("utf-8")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
if self.is_a?(SyntaxError) && @eturem_message.match(/\A(?<path>.+?)\:(?<lineno>\d+):\s*/)
|
146
|
+
@eturem_path = Regexp.last_match(:path)
|
147
|
+
@eturem_lineno = Regexp.last_match(:lineno).to_i
|
148
|
+
@eturem_message = Regexp.last_match.post_match
|
149
|
+
@eturem_path = Eturem.program_name if @eturem_path == program_filepath
|
216
150
|
else
|
217
|
-
|
151
|
+
eturem_backtrace_locations_shift
|
218
152
|
end
|
153
|
+
|
154
|
+
@eturem_script_lines = Eturem::Base.read_script(@eturem_path)
|
155
|
+
@eturem_output_linenos = eturem_default_output_linenos
|
219
156
|
end
|
220
|
-
|
221
|
-
def
|
222
|
-
|
157
|
+
|
158
|
+
def eturem_original_error_message()
|
159
|
+
@eturem_message.match(/\A(?<first_line>.*)/)
|
160
|
+
"#{@eturem_path}:#{@eturem_lineno}:in `#{@eturem_label}': " +
|
161
|
+
"\e[1m#{Regexp.last_match(:first_line)} (\e[4m#{self.class}\e[0;1m)" +
|
162
|
+
"#{Regexp.last_match.post_match.chomp}\e[0m\n"
|
223
163
|
end
|
224
|
-
|
225
|
-
def
|
226
|
-
@
|
164
|
+
|
165
|
+
def eturem_backtrace_str(order = :top)
|
166
|
+
str = @eturem_backtrace_locations.empty? ? "" : eturem_traceback(order)
|
167
|
+
str + (order == :top ? eturem_backtrace_str_top : eturem_backtrace_str_bottom)
|
227
168
|
end
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
case @exception
|
233
|
-
when NameError then prepare_name_error
|
234
|
-
when ArgumentError then prepare_argument_error
|
169
|
+
|
170
|
+
def eturem_backtrace
|
171
|
+
eturem_backtrace_locations.map do |location|
|
172
|
+
eturem_location_to_s(location)
|
235
173
|
end
|
236
174
|
end
|
237
|
-
|
238
|
-
def
|
239
|
-
|
240
|
-
@did_you_mean = Regexp.last_match.post_match.strip.scan(/\S+/)
|
241
|
-
@decoration[@lineno] = [@exception.name.to_s, "\e[1;31m\e[4m"]
|
242
|
-
|
243
|
-
@did_you_mean.each do |name|
|
244
|
-
index = @script_lines.index { |line| line.include?(name) }
|
245
|
-
next unless index
|
246
|
-
@decoration[index] = [name, "\e[1;33m"]
|
247
|
-
@output_linenos.push(index)
|
248
|
-
end
|
175
|
+
|
176
|
+
def eturem_location_to_s(location)
|
177
|
+
"#{location.path}:#{location.lineno}:in `#{location.label}'"
|
249
178
|
end
|
250
|
-
|
251
|
-
def
|
252
|
-
@
|
253
|
-
backtrace_locations_shift
|
254
|
-
@script_lines = read_script(@path)
|
255
|
-
@output_linenos = default_output_linenos
|
179
|
+
|
180
|
+
def eturem_backtrace_locations
|
181
|
+
@eturem_backtrace_locations
|
256
182
|
end
|
257
|
-
|
258
|
-
def
|
259
|
-
|
260
|
-
@path = @backtrace_locations.first.path
|
261
|
-
@lineno = @backtrace_locations.first.lineno
|
262
|
-
@backtrace_locations.shift
|
183
|
+
|
184
|
+
def eturem_message
|
185
|
+
""
|
263
186
|
end
|
264
|
-
|
265
|
-
def
|
266
|
-
|
187
|
+
|
188
|
+
def eturem_script
|
189
|
+
Eturem::Base.script(@eturem_script_lines, @eturem_output_linenos, @eturem_lineno)
|
267
190
|
end
|
268
|
-
|
269
|
-
def
|
270
|
-
|
191
|
+
|
192
|
+
def eturem_full_message(highlight: true, order: :top)
|
193
|
+
highlight = false unless $stderr == STDERR && $stderr.tty?
|
194
|
+
|
195
|
+
str = @@eturem_output_backtrace ? eturem_backtrace_str(order) : ""
|
196
|
+
ext_message = eturem_message
|
197
|
+
if ext_message.empty?
|
198
|
+
str += eturem_original_error_message
|
199
|
+
else
|
200
|
+
str = "#{eturem_original_error_message}\n#{str}" if @@eturem_output_original
|
201
|
+
str += "#{ext_message}\n"
|
202
|
+
end
|
203
|
+
str += eturem_script if @@eturem_output_script
|
204
|
+
|
205
|
+
highlight ? str : Eturem::Base.unhighlight(str)
|
271
206
|
end
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
def eturem_backtrace_locations_shift
|
211
|
+
location = @eturem_backtrace_locations.shift
|
212
|
+
@eturem_label = location.label
|
213
|
+
@eturem_path = location.path
|
214
|
+
@eturem_lineno = location.lineno
|
215
|
+
end
|
216
|
+
|
217
|
+
def eturem_default_output_linenos
|
218
|
+
from = [1, @eturem_lineno - @@eturem_before_line_num].max
|
219
|
+
to = [@eturem_script_lines.size - 1, @eturem_lineno + @@eturem_after_line_num].min
|
276
220
|
(from..to).to_a
|
277
221
|
end
|
278
|
-
|
279
|
-
def
|
280
|
-
|
222
|
+
|
223
|
+
def eturem_traceback(order = :bottom)
|
224
|
+
order == :top ? "" : "\e[1mTraceback\e[0m (most recent call last):\n"
|
281
225
|
end
|
282
|
-
|
283
|
-
def
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
226
|
+
|
227
|
+
def eturem_backtrace_str_bottom
|
228
|
+
lines = []
|
229
|
+
backtrace = eturem_backtrace
|
230
|
+
size = backtrace.size
|
231
|
+
format = "%#{8 + size.to_s.length}d: %s\n"
|
232
|
+
backtrace.reverse.each_with_index do |bt, i|
|
233
|
+
lines.push(sprintf(format, size - i, bt))
|
290
234
|
end
|
235
|
+
|
236
|
+
if @eturem_message == "stack level too deep"
|
237
|
+
lines = lines[-4..-1] +
|
238
|
+
[" ... #{lines.size - 12} levels...\n"] +
|
239
|
+
lines[0..7]
|
240
|
+
end
|
241
|
+
lines.join
|
291
242
|
end
|
292
|
-
|
293
|
-
def
|
294
|
-
|
295
|
-
|
296
|
-
return nil unless script
|
297
|
-
script.encode!("utf-8")
|
298
|
-
if @@use_coderay
|
299
|
-
require "coderay"
|
300
|
-
script = CodeRay.scan(script, :ruby).terminal
|
301
|
-
end
|
302
|
-
@scripts[file] = [""] + script.lines(chomp: true)
|
243
|
+
|
244
|
+
def eturem_backtrace_str_top
|
245
|
+
lines = eturem_backtrace.map do |bt|
|
246
|
+
" from #{bt}\n"
|
303
247
|
end
|
304
|
-
|
248
|
+
if @eturem_message == "stack level too deep"
|
249
|
+
lines = lines[0..7] +
|
250
|
+
[" ... #{lines.size - 12} levels...\n"] +
|
251
|
+
lines[-4..-1]
|
252
|
+
end
|
253
|
+
lines.join
|
305
254
|
end
|
306
255
|
end
|
256
|
+
|
257
|
+
|
258
|
+
module ExceptionExt
|
259
|
+
include Base
|
260
|
+
end
|
261
|
+
|
262
|
+
|
263
|
+
module NameErrorExt
|
264
|
+
include ExceptionExt
|
265
|
+
|
266
|
+
def eturem_prepare()
|
267
|
+
@eturem_corrections = self.respond_to?(:corrections) ? self.corrections : []
|
268
|
+
@eturem_corrections += Object.constants.map(&:to_s).select do |const|
|
269
|
+
const.casecmp?(self.name)
|
270
|
+
end
|
271
|
+
@eturem_corrections.uniq!
|
272
|
+
def self.corrections; @eturem_corrections; end
|
273
|
+
super
|
274
|
+
uname = self.name.to_s.encode("utf-8")
|
275
|
+
if @eturem_script_lines[@eturem_lineno]
|
276
|
+
Eturem::Base.highlight(@eturem_script_lines[@eturem_lineno], uname, "\e[1;4;31m")
|
277
|
+
end
|
278
|
+
@eturem_corrections.each do |name|
|
279
|
+
index = @eturem_script_lines.index { |line| line.include?(name.to_s.encode("utf-8")) }
|
280
|
+
next unless index
|
281
|
+
Eturem::Base.highlight(@eturem_script_lines[index], name.to_s.encode("utf-8"), "\e[1;33m")
|
282
|
+
@eturem_output_linenos.push(index)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
module ArgumentErrorExt
|
289
|
+
include ExceptionExt
|
290
|
+
|
291
|
+
def eturem_prepare()
|
292
|
+
super
|
293
|
+
@eturem_method = @eturem_label
|
294
|
+
eturem_backtrace_locations_shift
|
295
|
+
@eturem_script_lines = Eturem::Base.read_script(@eturem_path)
|
296
|
+
@eturem_output_linenos = eturem_default_output_linenos
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
module SyntaxErrorExt
|
302
|
+
include ExceptionExt
|
307
303
|
|
308
|
-
|
304
|
+
def eturem_original_error_message()
|
305
|
+
ret = "#{@eturem_path}:#{@eturem_lineno}: #{@eturem_message}"
|
306
|
+
unless @eturem_path == Eturem.program_name
|
307
|
+
ret = "\e[1m#{ret} (\e[4m#{self.class}\e[0;1m)\e[0m"
|
308
|
+
end
|
309
|
+
ret + "\n"
|
310
|
+
end
|
311
|
+
end
|
309
312
|
end
|