rails-route-checker 0.2.3 → 0.2.4

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
- SHA1:
3
- metadata.gz: 19d68dcbdd849a080cf1e5d99f1ae4a5835ad770
4
- data.tar.gz: eb811f79a36bdf90e44cc440549dd279cc1d8a73
2
+ SHA256:
3
+ metadata.gz: 3604e0534bad28fed12e85404774e01507b811767f3b08606963d8db34eeffd1
4
+ data.tar.gz: 33ac9a2201800a8034242cbee920b693b8dd4772a7b44d4e5834df06f7977e5a
5
5
  SHA512:
6
- metadata.gz: 545ed87d3c89646a04cf3a7e7aee7b90ee48a16d33d7d8fce0699ec0c0ea01a211b2bd659dd5a85740a2c5ebeadd92cb017cfca426384fd09844700b4149d94c
7
- data.tar.gz: 75ea1b5e8b936cb03925fb4c79369e86b9be5643401adda5bc0878689c8f3f6a16494fd74dec7f63307e582b86bd31c083805ed575466b87fa5ba33e56e8b058
6
+ metadata.gz: b82d44db72af06feda748069d51b060e403559e73ddbe0d8589ff551b086e7477868c9205ee232ae8fe2e81499083aedef70e0c0d572be07a6ee6ca75f0eb094
7
+ data.tar.gz: baca9417795fb9ad33b776a9e011951f5c78ba5296b6fe189d0a31b94c8787fdeff529c8a899a513f4132899d1b460179d7c58c48d6a6ebec8c8591a34ad5912
@@ -10,12 +10,7 @@ module RailsRouteChecker
10
10
  action = r.requirements[:action]
11
11
 
12
12
  next if options[:ignored_controllers].include?(controller)
13
-
14
- if controller_information.key?(controller)
15
- info = controller_information[controller]
16
- next if info[:actions].include?(action)
17
- next if info[:lookup_context] && info[:lookup_context].template_exists?("#{controller}/#{action}")
18
- end
13
+ next if controller_has_action?(controller, action)
19
14
 
20
15
  {
21
16
  controller: controller,
@@ -42,6 +37,16 @@ module RailsRouteChecker
42
37
  end
43
38
  end
44
39
 
40
+ def controller_has_action?(controller, action)
41
+ return false unless controller_information.key?(controller)
42
+
43
+ info = controller_information[controller]
44
+ return true if info[:actions].include?(action)
45
+ return true if info[:lookup_context] && info[:lookup_context].template_exists?("#{controller}/#{action}")
46
+
47
+ false
48
+ end
49
+
45
50
  def generate_undef_view_path_calls
46
51
  generate_undef_view_path_calls_erb + generate_undef_view_path_calls_haml
47
52
  end
@@ -59,6 +64,7 @@ module RailsRouteChecker
59
64
  filter = lambda do |path_or_url|
60
65
  return false if match_in_whitelist?(filename, path_or_url)
61
66
  return false if match_defined_in_view?(controller, path_or_url)
67
+
62
68
  true
63
69
  end
64
70
 
@@ -85,6 +91,7 @@ module RailsRouteChecker
85
91
  filter = lambda do |path_or_url|
86
92
  return false if match_in_whitelist?(filename, path_or_url)
87
93
  return false if match_defined_in_view?(controller, path_or_url)
94
+
88
95
  true
89
96
  end
90
97
 
@@ -105,6 +112,7 @@ module RailsRouteChecker
105
112
  filter = lambda do |path_or_url|
106
113
  return false if match_in_whitelist?(filename, path_or_url)
107
114
  return false if match_defined_in_ruby?(controller, path_or_url)
115
+
108
116
  return true
109
117
  end
110
118
 
@@ -115,18 +123,21 @@ module RailsRouteChecker
115
123
  def match_in_whitelist?(filename, path_or_url)
116
124
  possible_route_name = path_or_url.sub(/_(?:url|path)$/, '')
117
125
  return true if options[:ignored_paths].include?(possible_route_name)
126
+
118
127
  (options[:ignored_path_whitelist][filename] || []).include?(path_or_url)
119
128
  end
120
129
 
121
130
  def match_defined_in_view?(controller, path_or_url)
122
131
  possible_route_name = path_or_url.sub(/_(?:url|path)$/, '')
123
132
  return true if loaded_app.all_route_names.include?(possible_route_name)
133
+
124
134
  controller && controller[:helpers].include?(path_or_url)
125
135
  end
126
136
 
127
137
  def match_defined_in_ruby?(controller, path_or_url)
128
138
  possible_route_name = path_or_url.sub(/_(?:url|path)$/, '')
129
139
  return true if loaded_app.all_route_names.include?(possible_route_name)
140
+
130
141
  controller && controller[:instance_methods].include?(path_or_url)
131
142
  end
132
143
 
@@ -137,6 +148,7 @@ module RailsRouteChecker
137
148
  while possible_controller_path.any?
138
149
  controller_name = possible_controller_path.join('/')
139
150
  return controller_information[controller_name] if controller_exists?(controller_name)
151
+
140
152
  possible_controller_path = possible_controller_path[0..-2]
141
153
  end
142
154
  controller_information['application']
@@ -145,12 +157,14 @@ module RailsRouteChecker
145
157
  def controller_from_ruby_file(filename)
146
158
  controller_name = (filename.match(%r{app/controllers/(.*)_controller.rb}) || [])[1]
147
159
  return controller_information[controller_name] if controller_exists?(controller_name)
160
+
148
161
  controller_information['application']
149
162
  end
150
163
 
151
164
  def controller_exists?(controller_name)
152
165
  return false unless controller_name
153
- File.exists?("app/controllers/#{controller_name}_controller.rb")
166
+
167
+ File.exist?("app/controllers/#{controller_name}_controller.rb")
154
168
  end
155
169
  end
156
170
  end
@@ -40,18 +40,13 @@ module RailsRouteChecker
40
40
  @controller_information ||= ActionController::Base.descendants.map do |controller|
41
41
  next if controller.controller_path.start_with?('rails/')
42
42
 
43
- instance_methods = (controller.instance_methods.map(&:to_s) + controller.private_instance_methods.map(&:to_s))
44
- lookup_context = ActionView::LookupContext.new(
45
- controller._view_paths, {}, controller._prefixes
46
- ) if controller.instance_methods.include?(:default_render)
47
-
48
43
  [
49
44
  controller.controller_path,
50
45
  {
51
46
  helpers: controller.helpers.methods.map(&:to_s),
52
47
  actions: controller.action_methods.to_a,
53
- instance_methods: instance_methods.compact.uniq,
54
- lookup_context: lookup_context
48
+ instance_methods: instance_methods(controller),
49
+ lookup_context: lookup_context(controller)
55
50
  }
56
51
  ]
57
52
  end.compact.to_h
@@ -61,6 +56,16 @@ module RailsRouteChecker
61
56
 
62
57
  attr_reader :app
63
58
 
59
+ def lookup_context(controller)
60
+ return nil unless controller.instance_methods.include?(:default_render)
61
+
62
+ ActionView::LookupContext.new(controller._view_paths, {}, controller._prefixes)
63
+ end
64
+
65
+ def instance_methods(controller)
66
+ (controller.instance_methods.map(&:to_s) + controller.private_instance_methods.map(&:to_s)).compact.uniq
67
+ end
68
+
64
69
  def suppress_output
65
70
  begin
66
71
  original_stderr = $stderr.clone
@@ -106,6 +111,7 @@ module RailsRouteChecker
106
111
  action = route.requirements[:action]
107
112
  return true unless controller && action
108
113
  return true if controller.start_with?('rails/')
114
+
109
115
  false
110
116
  end
111
117
  end
@@ -5,23 +5,7 @@ module RailsRouteChecker
5
5
  def run(filename, **opts)
6
6
  file_source = opts[:source] || File.read(filename)
7
7
 
8
- next_ruby_source_line_num = 1
9
- ruby_source = ''
10
- source_map = {}
11
-
12
- file_source.split("\n").each_with_index do |line, line_num|
13
- ruby_lines = process_line(line)
14
- next unless ruby_lines.any?
15
-
16
- ruby_source += ruby_lines.join("\n") + "\n"
17
- ruby_lines.length.times do |i|
18
- source_map[next_ruby_source_line_num + i] = line_num + 1
19
- end
20
- next_ruby_source_line_num += ruby_lines.length
21
- end
22
-
23
- opts[:source] = ruby_source
24
- opts[:source_map] = source_map
8
+ opts.merge!(process_file(file_source))
25
9
 
26
10
  RailsRouteChecker::Parsers::RubyParser.run(filename, **opts)
27
11
  end
@@ -46,6 +30,28 @@ module RailsRouteChecker
46
30
  end
47
31
  ruby_lines
48
32
  end
33
+
34
+ def process_file(source)
35
+ next_ruby_source_line_num = 1
36
+ ruby_source = ''
37
+ source_map = {}
38
+
39
+ source.split("\n").each_with_index do |line, line_num|
40
+ ruby_lines = process_line(line)
41
+ next unless ruby_lines.any?
42
+
43
+ ruby_source += ruby_lines.join("\n") + "\n"
44
+ ruby_lines.length.times do |i|
45
+ source_map[next_ruby_source_line_num + i] = line_num + 1
46
+ end
47
+ next_ruby_source_line_num += ruby_lines.length
48
+ end
49
+
50
+ {
51
+ source: ruby_source,
52
+ source_map: source_map
53
+ }
54
+ end
49
55
  end
50
56
  end
51
57
  end
@@ -9,8 +9,9 @@ module RailsRouteChecker
9
9
  @source_lines = @source.split(/\r\n|\r|\n/)
10
10
 
11
11
  version = Gem::Version.new(Haml::VERSION).approximate_recommendation
12
+ options = Haml::Options.new
12
13
  original_tree = case version
13
- when '~> 4.0', '~> 4.1' then Haml::Parser.new(@source, Haml::Options.new).parse
14
+ when '~> 4.0', '~> 4.1' then Haml::Parser.new(@source, options).parse
14
15
  when '~> 5.0' then Haml::Parser.new(options).call(@source)
15
16
  else raise "Cannot handle Haml version: #{version}"
16
17
  end
@@ -21,9 +22,7 @@ module RailsRouteChecker
21
22
  private
22
23
 
23
24
  def process_tree(original_tree)
24
- if Gem::Requirement.new('~> 4.0.0').satisfied_by?(Gem.loaded_specs['haml'].version)
25
- original_tree.children.pop
26
- end
25
+ original_tree.children.pop if Gem::Requirement.new('~> 4.0.0').satisfied_by?(Gem.loaded_specs['haml'].version)
27
26
 
28
27
  convert_tree(original_tree)
29
28
  end
@@ -53,6 +53,7 @@ module RailsRouteChecker
53
53
  yield
54
54
 
55
55
  return unless start_block
56
+
56
57
  @indent_level -= 1
57
58
  add_line('end', node)
58
59
  end
@@ -18,7 +18,7 @@ module RailsRouteChecker
18
18
  end
19
19
 
20
20
  def attributes_source
21
- @attr_source ||=
21
+ @attr_source ||= # rubocop:disable Naming/MemoizedInstanceVariableName
22
22
  begin
23
23
  _explicit_tag, static_attrs, rest =
24
24
  source_code.scan(/\A\s*(%[-:\w]+)?([-:\w\.\#]*)(.*)/m)[0]
@@ -21,6 +21,7 @@ module RailsRouteChecker
21
21
 
22
22
  def haml_available?
23
23
  return @haml_available if defined?(@haml_available)
24
+
24
25
  @haml_available = gem_installed?('haml')
25
26
  end
26
27
 
@@ -46,6 +47,7 @@ module RailsRouteChecker
46
47
  def if_unloaded(parser)
47
48
  @loaded_parsers ||= {}
48
49
  return false if @loaded_parsers[parser]
50
+
49
51
  yield
50
52
  @loaded_parsers[parser] = true
51
53
  end
@@ -6,15 +6,16 @@ module RailsRouteChecker
6
6
  class << self
7
7
  def run(filename, **opts)
8
8
  file_source = opts[:source] || File.read(filename)
9
+ process_file(filename, file_source, opts)
10
+ end
9
11
 
10
- items = []
12
+ private
11
13
 
12
- deep_iterator(Ripper.sexp(file_source)) do |item, extra_data|
13
- scope = extra_data[:scope]
14
- next unless %i[vcall fcall].include?(scope[-2])
15
- next unless scope[-1] == :@ident
16
- next unless item.end_with?('_path', '_url')
14
+ def process_file(filename, source, opts)
15
+ items = []
17
16
 
17
+ deep_iterator(Ripper.sexp(source)) do |item, extra_data|
18
+ next unless item_is_url_call?(item, extra_data)
18
19
  next if opts[:filter].respond_to?(:call) && !opts[:filter].call(item)
19
20
 
20
21
  line = extra_data[:position][0]
@@ -26,30 +27,43 @@ module RailsRouteChecker
26
27
  items
27
28
  end
28
29
 
29
- private
30
+ def item_is_url_call?(item, extra_data)
31
+ scope = extra_data[:scope]
32
+ return false unless %i[vcall fcall].include?(scope[-2])
33
+ return false unless scope[-1] == :@ident
34
+ return false unless item.end_with?('_path', '_url')
35
+
36
+ true
37
+ end
30
38
 
31
39
  def deep_iterator(list, current_scope = [], current_line_num = [], &block)
32
- if list.is_a?(Array)
33
- if list[0].is_a?(Symbol)
34
- current_scope << list[0]
35
-
36
- if list[-1].is_a?(Array) && list[-1].length == 2 && list[-1].all? { |item| item.is_a?(Integer) }
37
- current_line_num = list[-1]
38
- list = list[0..-2]
39
- end
40
-
41
- list[1..-1].each do |item|
42
- deep_iterator(item, current_scope, current_line_num, &block)
43
- end
44
- current_scope.pop
45
- else
46
- list.each do |item|
47
- deep_iterator(item, current_scope, current_line_num, &block)
48
- end
40
+ return deep_iterate_array(list, current_scope, current_line_num, &block) if list.is_a?(Array)
41
+
42
+ yield(list, { scope: current_scope, position: current_line_num }) unless list.nil?
43
+ end
44
+
45
+ def deep_iterate_array(list, current_scope, current_line_num, &block)
46
+ unless list[0].is_a?(Symbol)
47
+ list.each do |item|
48
+ deep_iterator(item, current_scope, current_line_num, &block)
49
49
  end
50
- elsif !list.nil?
51
- yield(list, { scope: current_scope, position: current_line_num })
50
+ return
51
+ end
52
+
53
+ current_scope << list[0]
54
+
55
+ last_list_item = list[-1]
56
+ if last_list_item.is_a?(Array) &&
57
+ last_list_item.length == 2 &&
58
+ last_list_item.all? { |item| item.is_a?(Integer) }
59
+ current_line_num = last_list_item
60
+ list = list[0..-2]
61
+ end
62
+
63
+ list[1..-1].each do |item|
64
+ deep_iterator(item, current_scope, current_line_num, &block)
52
65
  end
66
+ current_scope.pop
53
67
  end
54
68
  end
55
69
  end
@@ -1,3 +1,3 @@
1
1
  module RailsRouteChecker
2
- VERSION = '0.2.3'.freeze
2
+ VERSION = '0.2.4'.freeze
3
3
  end
@@ -1,5 +1,4 @@
1
-
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'rails-route-checker/version'
5
4
 
@@ -24,5 +23,5 @@ Gem::Specification.new do |spec|
24
23
 
25
24
  spec.add_development_dependency 'bundler', '~> 1.15'
26
25
  spec.add_development_dependency 'rake', '~> 10.0'
27
- spec.add_development_dependency 'rubocop', '~> 0.51'
26
+ spec.add_development_dependency 'rubocop', '~> 0.60'
28
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-route-checker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Allie
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-15 00:00:00.000000000 Z
11
+ date: 2018-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.51'
47
+ version: '0.60'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.51'
54
+ version: '0.60'
55
55
  description: A linting tool that helps you find any routes defined in your routes.rb
56
56
  file that don't have a corresponding controller action, and find any _path or _url
57
57
  calls that don't have a corresponding route in the routes.rb file.
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
103
  version: '0'
104
104
  requirements: []
105
105
  rubyforge_project:
106
- rubygems_version: 2.6.8
106
+ rubygems_version: 2.7.7
107
107
  signing_key:
108
108
  specification_version: 4
109
109
  summary: A linting tool for your Rails routes