i_did_mean 1.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 +7 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +56 -0
- data/.ruby-version +1 -0
- data/.travis.yml +12 -0
- data/Appraisals +26 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +49 -0
- data/gemfiles/rails_5.0.gemfile +10 -0
- data/gemfiles/rails_5.0.gemfile.lock +142 -0
- data/gemfiles/rails_5.1.gemfile +10 -0
- data/gemfiles/rails_5.1.gemfile.lock +142 -0
- data/gemfiles/rails_5.2.gemfile +10 -0
- data/gemfiles/rails_5.2.gemfile.lock +158 -0
- data/gemfiles/rails_6.0.gemfile +10 -0
- data/gemfiles/rails_6.0.gemfile.lock +166 -0
- data/gemfiles/rails_edge.gemfile +10 -0
- data/gemfiles/rails_edge.gemfile.lock +182 -0
- data/i_did_mean.gemspec +32 -0
- data/lib/i_did_mean.rb +23 -0
- data/lib/i_did_mean/error.rb +6 -0
- data/lib/i_did_mean/formatter.rb +9 -0
- data/lib/i_did_mean/processor.rb +106 -0
- data/lib/i_did_mean/rails/middleware.rb +36 -0
- data/lib/i_did_mean/railtie.rb +12 -0
- data/lib/i_did_mean/version.rb +5 -0
- metadata +196 -0
data/i_did_mean.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "i_did_mean/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "i_did_mean"
|
9
|
+
spec.version = IDidMean::VERSION
|
10
|
+
spec.authors = ["Hrvoje Simic"]
|
11
|
+
spec.email = ["shime@twobucks.co"]
|
12
|
+
spec.summary = %(Did you mean? Yes I did! Autofix your typos!)
|
13
|
+
spec.description = %(Autofix your typos, by leveraging DidYouMean suggestions.)
|
14
|
+
spec.homepage = "https://github.com/shime/i_did_mean"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "appraisal"
|
24
|
+
spec.add_development_dependency "bundler"
|
25
|
+
spec.add_development_dependency "minitest"
|
26
|
+
spec.add_development_dependency "minitest-focus"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
spec.add_development_dependency "rack-test"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
spec.add_development_dependency "rubocop"
|
31
|
+
spec.add_development_dependency "rubocop-minitest"
|
32
|
+
end
|
data/lib/i_did_mean.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
|
5
|
+
module IDidMean
|
6
|
+
def self.call(error)
|
7
|
+
processor = Processor.new(error)
|
8
|
+
processor.call
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
at_exit do
|
13
|
+
IDidMean.call($ERROR_INFO) if $ERROR_INFO
|
14
|
+
end
|
15
|
+
|
16
|
+
require "i_did_mean/error"
|
17
|
+
require "i_did_mean/processor"
|
18
|
+
require "i_did_mean/formatter"
|
19
|
+
|
20
|
+
if defined?(::Rails)
|
21
|
+
require "i_did_mean/rails/middleware"
|
22
|
+
require "i_did_mean/railtie"
|
23
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IDidMean
|
4
|
+
class Processor
|
5
|
+
def initialize(error)
|
6
|
+
@error = error
|
7
|
+
|
8
|
+
return if backtrace.empty?
|
9
|
+
|
10
|
+
@file, @number = backtrace.first.split(":").first(2)
|
11
|
+
|
12
|
+
save_original_formatter
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
if should_process?
|
17
|
+
replace_line(number)
|
18
|
+
replace_formatter
|
19
|
+
else
|
20
|
+
restore_original_formatter
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def should_process?
|
25
|
+
# Only process this error if:
|
26
|
+
# * error is present (**surprise, surprise**)
|
27
|
+
# * error was corrected (did_you_mean has done its magic)
|
28
|
+
error&.respond_to?(:corrections) &&
|
29
|
+
# * there is only one correction, so we can be certain to replace
|
30
|
+
error.corrections.length == 1 &&
|
31
|
+
# * this is not some internal backtrace (considering Rails here)
|
32
|
+
backtrace.first
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :error
|
38
|
+
attr_reader :file
|
39
|
+
attr_reader :number
|
40
|
+
attr_reader :original_formatter
|
41
|
+
|
42
|
+
# Extracts method name from error message.
|
43
|
+
# Example:
|
44
|
+
#
|
45
|
+
# For this error message:
|
46
|
+
#
|
47
|
+
# NameError: undefined local variable or method `foo' for #<Object:0x00007fab0c28a0f0>
|
48
|
+
#
|
49
|
+
# It should return "foo".
|
50
|
+
#
|
51
|
+
def original_method_name
|
52
|
+
case error
|
53
|
+
when NameError
|
54
|
+
error.name
|
55
|
+
when KeyError
|
56
|
+
error.key
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def corrected_method_name
|
61
|
+
error.corrections
|
62
|
+
.first
|
63
|
+
.to_s
|
64
|
+
.gsub(/\A:/, "")
|
65
|
+
.gsub(/"/, "")
|
66
|
+
end
|
67
|
+
|
68
|
+
def file_path
|
69
|
+
@file_path ||= File.expand_path(file)
|
70
|
+
end
|
71
|
+
|
72
|
+
def lines
|
73
|
+
@lines ||= IO.readlines(file_path)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Used for cleaning backtrace.
|
77
|
+
# We're only interested in application backtrace.
|
78
|
+
# This is Rails related.
|
79
|
+
def backtrace
|
80
|
+
backtrace = error.backtrace
|
81
|
+
backtrace = ::Rails.backtrace_cleaner.clean(backtrace) if defined?(::Rails)
|
82
|
+
backtrace
|
83
|
+
end
|
84
|
+
|
85
|
+
def replace_line(number)
|
86
|
+
lines[number.to_i - 1][original_method_name.to_s] = corrected_method_name
|
87
|
+
IO.write(file_path, lines.join)
|
88
|
+
end
|
89
|
+
|
90
|
+
def replace_formatter
|
91
|
+
DidYouMean.formatter = Formatter.new
|
92
|
+
end
|
93
|
+
|
94
|
+
def restore_original_formatter
|
95
|
+
DidYouMean.formatter = original_formatter
|
96
|
+
end
|
97
|
+
|
98
|
+
def save_original_formatter
|
99
|
+
self.original_formatter = DidYouMean.formatter
|
100
|
+
end
|
101
|
+
|
102
|
+
def original_formatter=(formatter)
|
103
|
+
@original_formatter ||= formatter
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IDidMean
|
4
|
+
module Rails
|
5
|
+
class Middleware
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
begin
|
12
|
+
response = @app.call(env)
|
13
|
+
rescue StandardError => e
|
14
|
+
processor = IDidMean::Processor.new(e)
|
15
|
+
|
16
|
+
raise unless processor.should_process?
|
17
|
+
|
18
|
+
response = handle_exception(processor, env)
|
19
|
+
end
|
20
|
+
|
21
|
+
response
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def handle_exception(processor, env)
|
27
|
+
processor.call
|
28
|
+
|
29
|
+
ActiveSupport::DescendantsTracker.clear
|
30
|
+
ActiveSupport::Dependencies.clear
|
31
|
+
|
32
|
+
@app.call(env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IDidMean
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
initializer("i_did_mean.middleware") do |app|
|
6
|
+
app.config.middleware.insert_after(
|
7
|
+
ActionDispatch::DebugExceptions,
|
8
|
+
IDidMean::Rails::Middleware
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: i_did_mean
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hrvoje Simic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: appraisal
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-focus
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rack-test
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-minitest
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Autofix your typos, by leveraging DidYouMean suggestions.
|
140
|
+
email:
|
141
|
+
- shime@twobucks.co
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".rubocop.yml"
|
148
|
+
- ".ruby-version"
|
149
|
+
- ".travis.yml"
|
150
|
+
- Appraisals
|
151
|
+
- Gemfile
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- gemfiles/rails_5.0.gemfile
|
156
|
+
- gemfiles/rails_5.0.gemfile.lock
|
157
|
+
- gemfiles/rails_5.1.gemfile
|
158
|
+
- gemfiles/rails_5.1.gemfile.lock
|
159
|
+
- gemfiles/rails_5.2.gemfile
|
160
|
+
- gemfiles/rails_5.2.gemfile.lock
|
161
|
+
- gemfiles/rails_6.0.gemfile
|
162
|
+
- gemfiles/rails_6.0.gemfile.lock
|
163
|
+
- gemfiles/rails_edge.gemfile
|
164
|
+
- gemfiles/rails_edge.gemfile.lock
|
165
|
+
- i_did_mean.gemspec
|
166
|
+
- lib/i_did_mean.rb
|
167
|
+
- lib/i_did_mean/error.rb
|
168
|
+
- lib/i_did_mean/formatter.rb
|
169
|
+
- lib/i_did_mean/processor.rb
|
170
|
+
- lib/i_did_mean/rails/middleware.rb
|
171
|
+
- lib/i_did_mean/railtie.rb
|
172
|
+
- lib/i_did_mean/version.rb
|
173
|
+
homepage: https://github.com/shime/i_did_mean
|
174
|
+
licenses:
|
175
|
+
- MIT
|
176
|
+
metadata: {}
|
177
|
+
post_install_message:
|
178
|
+
rdoc_options: []
|
179
|
+
require_paths:
|
180
|
+
- lib
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
191
|
+
requirements: []
|
192
|
+
rubygems_version: 3.0.3
|
193
|
+
signing_key:
|
194
|
+
specification_version: 4
|
195
|
+
summary: Did you mean? Yes I did! Autofix your typos!
|
196
|
+
test_files: []
|