foodcritic 7.0.1 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,16 @@
1
1
  begin
2
- require 'simplecov'
2
+ require "simplecov"
3
3
  SimpleCov.start do
4
- add_filter '/features/'
4
+ add_filter "/features/"
5
5
  end
6
6
  rescue LoadError
7
- warn 'warning: simplecov gem not found; skipping coverage'
7
+ warn "warning: simplecov gem not found; skipping coverage"
8
8
  end
9
9
 
10
- require 'aruba/cucumber'
11
- require 'foodcritic'
10
+ require "aruba/cucumber"
11
+ require "foodcritic"
12
12
 
13
- require 'minitest/spec'
13
+ require "minitest/spec"
14
14
 
15
15
  MiniTest::Spec.new(nil)
16
16
 
data/foodcritic.gemspec CHANGED
@@ -1,27 +1,27 @@
1
- lib = File.expand_path('../lib/', __FILE__)
1
+ lib = File.expand_path("../lib/", __FILE__)
2
2
  $:.unshift lib unless $:.include?(lib)
3
- require 'foodcritic/version'
3
+ require "foodcritic/version"
4
4
  Gem::Specification.new do |s|
5
- s.name = 'foodcritic'
5
+ s.name = "foodcritic"
6
6
  s.version = FoodCritic::VERSION
7
- s.description = 'Lint tool for Chef cookbooks.'
7
+ s.description = "Lint tool for Chef cookbooks."
8
8
  s.summary = "foodcritic-#{s.version}"
9
- s.authors = ['Andrew Crump']
10
- s.homepage = 'http://foodcritic.io'
11
- s.license = 'MIT'
12
- s.executables << 'foodcritic'
13
- s.required_ruby_version = '>= 2.1.0'
14
- s.add_dependency('cucumber-core', '>= 1.3')
15
- s.add_dependency('nokogiri', '>= 1.5', '< 2.0')
16
- s.add_dependency('rake')
17
- s.add_dependency('treetop', '~> 1.4')
18
- s.add_dependency('yajl-ruby', '~> 1.1')
19
- s.add_dependency('erubis')
20
- s.add_dependency('rufus-lru', '~> 1.0')
21
- s.files = Dir['chef_dsl_metadata/*.json'] +
22
- Dir['lib/**/*.rb'] +
23
- Dir['misc/**/*']
24
- s.files += Dir['Rakefile'] + Dir['Gemfile'] + Dir["*.gemspec"]
25
- s.files += Dir['spec/**/*'] + Dir['features/**/*']
26
- s.files += Dir['*.md'] + Dir['LICENSE'] + Dir['man/*']
9
+ s.authors = ["Andrew Crump"]
10
+ s.homepage = "http://foodcritic.io"
11
+ s.license = "MIT"
12
+ s.executables << "foodcritic"
13
+ s.required_ruby_version = ">= 2.1.0"
14
+ s.add_dependency("cucumber-core", ">= 1.3")
15
+ s.add_dependency("nokogiri", ">= 1.5", "< 2.0")
16
+ s.add_dependency("rake")
17
+ s.add_dependency("treetop", "~> 1.4")
18
+ s.add_dependency("yajl-ruby", "~> 1.1")
19
+ s.add_dependency("erubis")
20
+ s.add_dependency("rufus-lru", "~> 1.0")
21
+ s.files = Dir["chef_dsl_metadata/*.json"] +
22
+ Dir["lib/**/*.rb"] +
23
+ Dir["misc/**/*"]
24
+ s.files += Dir["Rakefile"] + Dir["Gemfile"] + Dir["*.gemspec"]
25
+ s.files += Dir["spec/**/*"] + Dir["features/**/*"]
26
+ s.files += Dir["*.md"] + Dir["LICENSE"] + Dir["man/*"]
27
27
  end
data/lib/foodcritic.rb CHANGED
@@ -1,21 +1,21 @@
1
- require 'pathname'
2
- require 'cucumber/core'
3
- require 'treetop'
4
- require 'ripper'
5
- require 'yajl'
6
- require 'erubis'
1
+ require "pathname"
2
+ require "cucumber/core"
3
+ require "treetop"
4
+ require "ripper"
5
+ require "yajl"
6
+ require "erubis"
7
7
 
8
- require_relative 'foodcritic/chef'
9
- require_relative 'foodcritic/command_line'
10
- require_relative 'foodcritic/domain'
11
- require_relative 'foodcritic/error_checker'
12
- require_relative 'foodcritic/notifications'
13
- require_relative 'foodcritic/ast'
14
- require_relative 'foodcritic/xml'
15
- require_relative 'foodcritic/api'
16
- require_relative 'foodcritic/dsl'
17
- require_relative 'foodcritic/linter'
18
- require_relative 'foodcritic/output'
19
- require_relative 'foodcritic/rake_task'
20
- require_relative 'foodcritic/template'
21
- require_relative 'foodcritic/version'
8
+ require_relative "foodcritic/chef"
9
+ require_relative "foodcritic/command_line"
10
+ require_relative "foodcritic/domain"
11
+ require_relative "foodcritic/error_checker"
12
+ require_relative "foodcritic/notifications"
13
+ require_relative "foodcritic/ast"
14
+ require_relative "foodcritic/xml"
15
+ require_relative "foodcritic/api"
16
+ require_relative "foodcritic/dsl"
17
+ require_relative "foodcritic/linter"
18
+ require_relative "foodcritic/output"
19
+ require_relative "foodcritic/rake_task"
20
+ require_relative "foodcritic/template"
21
+ require_relative "foodcritic/version"
@@ -1,5 +1,5 @@
1
- require 'nokogiri'
2
- require 'rufus-lru'
1
+ require "nokogiri"
2
+ require "rufus-lru"
3
3
 
4
4
  module FoodCritic
5
5
  # Helper methods that form part of the Rules DSL.
@@ -18,17 +18,17 @@ module FoodCritic
18
18
  return [] unless ast.respond_to?(:xpath)
19
19
 
20
20
  unless [:any, :string, :symbol, :vivified].include?(options[:type])
21
- fail ArgumentError, 'Node type not recognised'
21
+ raise ArgumentError, "Node type not recognised"
22
22
  end
23
23
 
24
24
  case options[:type]
25
25
  when :any then
26
- vivified_attribute_access(ast, options) +
27
- standard_attribute_access(ast, options)
26
+ vivified_attribute_access(ast, options) +
27
+ standard_attribute_access(ast, options)
28
28
  when :vivified then
29
- vivified_attribute_access(ast, options)
29
+ vivified_attribute_access(ast, options)
30
30
  else
31
- standard_attribute_access(ast, options)
31
+ standard_attribute_access(ast, options)
32
32
  end
33
33
  end
34
34
 
@@ -45,10 +45,10 @@ module FoodCritic
45
45
  or count(descendant::tstring_content[@value='solo']) > 0
46
46
  )
47
47
  ]}).empty?) ||
48
- ast.xpath('//if_mod[return][aref/descendant::ident/@value="solo"]/aref/
49
- const_path_ref/descendant::const').map do |c|
50
- c['value']
51
- end == %w(Chef Config)
48
+ ast.xpath('//if_mod[return][aref/descendant::ident/@value="solo"]/aref/
49
+ const_path_ref/descendant::const').map do |c|
50
+ c["value"]
51
+ end == %w{Chef Config}
52
52
  end
53
53
 
54
54
  # Is the
@@ -61,9 +61,9 @@ module FoodCritic
61
61
  #
62
62
  # TODO: This will not work if the cookbook that contains the library
63
63
  # is not under the same `cookbook_path` as the cookbook being checked.
64
- cbk_tree_path = Pathname.new(File.join(recipe_path, '../../..'))
64
+ cbk_tree_path = Pathname.new(File.join(recipe_path, "../../.."))
65
65
  search_libs = Dir[File.join(cbk_tree_path.realpath,
66
- '*/libraries/search.rb')]
66
+ "*/libraries/search.rb")]
67
67
 
68
68
  # True if any of the candidate library files match the signature:
69
69
  #
@@ -77,12 +77,12 @@ module FoodCritic
77
77
 
78
78
  # Support function to retrieve a metadata field
79
79
  def metadata_field(file, field)
80
- until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty? do
80
+ until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
81
81
  file = File.absolute_path(File.dirname(file.to_s))
82
82
  end
83
83
  file = File.dirname(file) unless File.extname(file).empty?
84
84
 
85
- md_path = File.join(file, 'metadata.rb')
85
+ md_path = File.join(file, "metadata.rb")
86
86
  if File.exist?(md_path)
87
87
  value = read_ast(md_path).xpath("//stmts_add/
88
88
  command[ident/@value='#{field}']/
@@ -96,14 +96,14 @@ module FoodCritic
96
96
 
97
97
  # The name of the cookbook containing the specified file.
98
98
  def cookbook_name(file)
99
- fail ArgumentError, 'File cannot be nil or empty' if file.to_s.empty?
99
+ raise ArgumentError, "File cannot be nil or empty" if file.to_s.empty?
100
100
 
101
101
  # Name is a special case as we want to fallback to the cookbook directory
102
102
  # name if metadata_field fails
103
103
  begin
104
- metadata_field(file, 'name')
104
+ metadata_field(file, "name")
105
105
  rescue RuntimeError
106
- until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty? do
106
+ until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
107
107
  file = File.absolute_path(File.dirname(file.to_s))
108
108
  end
109
109
  file = File.dirname(file) unless File.extname(file).empty?
@@ -113,16 +113,16 @@ module FoodCritic
113
113
 
114
114
  # The maintainer of the cookbook containing the specified file.
115
115
  def cookbook_maintainer(file)
116
- fail ArgumentError, 'File cannot be nil or empty' if file.to_s.empty?
116
+ raise ArgumentError, "File cannot be nil or empty" if file.to_s.empty?
117
117
 
118
- metadata_field(file, 'maintainer')
118
+ metadata_field(file, "maintainer")
119
119
  end
120
120
 
121
121
  # The maintainer email of the cookbook containing the specified file.
122
122
  def cookbook_maintainer_email(file)
123
- fail ArgumentError, 'File cannot be nil or empty' if file.to_s.empty?
123
+ raise ArgumentError, "File cannot be nil or empty" if file.to_s.empty?
124
124
 
125
- metadata_field(file, 'maintainer_email')
125
+ metadata_field(file, "maintainer_email")
126
126
  end
127
127
 
128
128
  # The dependencies declared in cookbook metadata.
@@ -142,13 +142,13 @@ module FoodCritic
142
142
  # end
143
143
  deps = deps.to_a +
144
144
  word_list_values(ast, "//command[ident/@value='depends']")
145
- deps.uniq.map { |dep| dep['value'].strip }
145
+ deps.uniq.map { |dep| dep["value"].strip }
146
146
  end
147
147
 
148
148
  # The key / value pair in an environment or role ruby file
149
149
  def field(ast, field_name)
150
150
  if field_name.nil? || field_name.to_s.empty?
151
- fail ArgumentError, 'Field name cannot be nil or empty'
151
+ raise ArgumentError, "Field name cannot be nil or empty"
152
152
  end
153
153
  ast.xpath("//command[ident/@value='#{field_name}']")
154
154
  end
@@ -163,7 +163,7 @@ module FoodCritic
163
163
  # Create a match for a specified file. Use this if the presence of the file
164
164
  # triggers the warning rather than content.
165
165
  def file_match(file)
166
- fail ArgumentError, 'Filename cannot be nil' if file.nil?
166
+ raise ArgumentError, "Filename cannot be nil" if file.nil?
167
167
  { filename: file, matched: file, line: 1, column: 1 }
168
168
  end
169
169
 
@@ -182,7 +182,7 @@ module FoodCritic
182
182
  def find_resources(ast, options = {})
183
183
  options = { type: :any }.merge!(options)
184
184
  return [] unless ast.respond_to?(:xpath)
185
- scope_type = ''
185
+ scope_type = ""
186
186
  scope_type = "[@value='#{options[:type]}']" unless options[:type] == :any
187
187
 
188
188
  # TODO: Include nested resources (provider actions)
@@ -205,12 +205,12 @@ module FoodCritic
205
205
  def included_recipes(ast, options = { with_partial_names: true })
206
206
  raise_unless_xpath!(ast)
207
207
 
208
- filter = ['[count(descendant::args_add) = 1]']
208
+ filter = ["[count(descendant::args_add) = 1]"]
209
209
 
210
210
  # If `:with_partial_names` is false then we won't include the string
211
211
  # literal portions of any string that has an embedded expression.
212
212
  unless options[:with_partial_names]
213
- filter << '[count(descendant::string_embexpr) = 0]'
213
+ filter << "[count(descendant::string_embexpr) = 0]"
214
214
  end
215
215
 
216
216
  string_desc = '[descendant::args_add/string_literal]/
@@ -221,10 +221,10 @@ module FoodCritic
221
221
  following-sibling::arg_paren",
222
222
  ].map do |recipe_include|
223
223
  recipe_include + filter.join + string_desc
224
- end.join(' | '))
224
+ end.join(" | "))
225
225
 
226
226
  # Hash keyed by recipe name with matched nodes.
227
- included.inject(Hash.new([])) { |h, i| h[i['value']] += [i]; h }
227
+ included.inject(Hash.new([])) { |h, i| h[i["value"]] += [i]; h }
228
228
  end
229
229
 
230
230
  # Searches performed by the specified recipe that are literal strings.
@@ -238,10 +238,10 @@ module FoodCritic
238
238
  # Create a match from the specified node.
239
239
  def match(node)
240
240
  raise_unless_xpath!(node)
241
- pos = node.xpath('descendant::pos').first
241
+ pos = node.xpath("descendant::pos").first
242
242
  return nil if pos.nil?
243
- { matched: node.respond_to?(:name) ? node.name : '',
244
- line: pos['line'].to_i, column: pos['column'].to_i }
243
+ { matched: node.respond_to?(:name) ? node.name : "",
244
+ line: pos["line"].to_i, column: pos["column"].to_i }
245
245
  end
246
246
 
247
247
  # Read the AST for the given Ruby source file
@@ -256,7 +256,7 @@ module FoodCritic
256
256
 
257
257
  # Retrieve a single-valued attribute from the specified resource.
258
258
  def resource_attribute(resource, name)
259
- fail ArgumentError, 'Attribute name cannot be empty' if name.empty?
259
+ raise ArgumentError, "Attribute name cannot be empty" if name.empty?
260
260
  resource_attributes(resource)[name.to_s]
261
261
  end
262
262
 
@@ -286,18 +286,18 @@ module FoodCritic
286
286
  raise_unless_xpath!(resource)
287
287
  options = { return_expressions: false }.merge(options)
288
288
  if options[:return_expressions]
289
- name = resource.xpath('command/args_add_block')
290
- if name.xpath('descendant::string_add').size == 1 &&
291
- name.xpath('descendant::string_literal').size == 1 &&
292
- name.xpath(
293
- 'descendant::*[self::call or self::string_embexpr]').empty?
294
- name.xpath('descendant::tstring_content/@value').to_s
289
+ name = resource.xpath("command/args_add_block")
290
+ if name.xpath("descendant::string_add").size == 1 &&
291
+ name.xpath("descendant::string_literal").size == 1 &&
292
+ name.xpath(
293
+ "descendant::*[self::call or self::string_embexpr]").empty?
294
+ name.xpath("descendant::tstring_content/@value").to_s
295
295
  else
296
296
  name
297
297
  end
298
298
  else
299
299
  # Preserve existing behaviour
300
- resource.xpath('string(command//tstring_content/@value)')
300
+ resource.xpath("string(command//tstring_content/@value)")
301
301
  end
302
302
  end
303
303
 
@@ -314,9 +314,9 @@ module FoodCritic
314
314
  # Return the type, e.g. 'package' for a given resource
315
315
  def resource_type(resource)
316
316
  raise_unless_xpath!(resource)
317
- type = resource.xpath('string(command/ident/@value)')
317
+ type = resource.xpath("string(command/ident/@value)")
318
318
  if type.empty?
319
- fail ArgumentError, 'Provided AST node is not a resource'
319
+ raise ArgumentError, "Provided AST node is not a resource"
320
320
  end
321
321
  type
322
322
  end
@@ -339,8 +339,8 @@ module FoodCritic
339
339
 
340
340
  # The list of standard cookbook sub-directories.
341
341
  def standard_cookbook_subdirs
342
- %w(attributes definitions files libraries providers recipes resources
343
- templates)
342
+ %w{attributes definitions files libraries providers recipes resources
343
+ templates}
344
344
  end
345
345
 
346
346
  # Platforms declared as supported in cookbook metadata
@@ -355,14 +355,14 @@ module FoodCritic
355
355
  platforms.map do |platform|
356
356
  versions = platform.xpath('ancestor::args_add[position() > 1]/
357
357
  string_literal/descendant::tstring_content/@value').map { |v| v.to_s }
358
- { platform: platform['value'], versions: versions }
358
+ { platform: platform["value"], versions: versions }
359
359
  end.sort { |a, b| a[:platform] <=> b[:platform] }
360
360
  end
361
361
 
362
362
  # Template filename
363
363
  def template_file(resource)
364
- if resource['source']
365
- resource['source']
364
+ if resource["source"]
365
+ resource["source"]
366
366
  elsif resource[:name]
367
367
  if resource[:name].respond_to?(:xpath)
368
368
  resource[:name]
@@ -373,7 +373,7 @@ module FoodCritic
373
373
  end
374
374
 
375
375
  def templates_included(all_templates, template_path, depth = 1)
376
- fail RecursedTooFarError.new(template_path) if depth > 10
376
+ raise RecursedTooFarError.new(template_path) if depth > 10
377
377
  partials = read_ast(template_path).xpath('//*[self::command or
378
378
  child::fcall][descendant::ident/@value="render"]//args_add/
379
379
  string_literal//tstring_content/@value').map { |p| p.to_s }
@@ -390,11 +390,11 @@ module FoodCritic
390
390
 
391
391
  # Templates in the current cookbook
392
392
  def template_paths(recipe_path)
393
- Dir.glob(Pathname.new(recipe_path).dirname.dirname + 'templates' +
394
- '**/*', File::FNM_DOTMATCH).select do |path|
393
+ Dir.glob(Pathname.new(recipe_path).dirname.dirname + "templates" +
394
+ "**/*", File::FNM_DOTMATCH).select do |path|
395
395
  File.file?(path)
396
396
  end.reject do |path|
397
- File.basename(path) == '.DS_Store' || File.extname(path) == '.swp'
397
+ File.basename(path) == ".DS_Store" || File.extname(path) == ".swp"
398
398
  end
399
399
  end
400
400
 
@@ -406,7 +406,7 @@ module FoodCritic
406
406
  atts = {}
407
407
  resource.xpath("do_block/descendant::method_add_block[
408
408
  count(ancestor::do_block) = 1][brace_block | do_block]").each do |batt|
409
- att_name = batt.xpath('string(method_add_arg/fcall/ident/@value)')
409
+ att_name = batt.xpath("string(method_add_arg/fcall/ident/@value)")
410
410
  if att_name && !att_name.empty? && batt.children.length > 1
411
411
  atts[att_name] = batt.children[1]
412
412
  end
@@ -415,7 +415,7 @@ module FoodCritic
415
415
  end
416
416
 
417
417
  def block_depth(resource)
418
- resource.path.split('/').group_by { |e|e }['method_add_block'].size
418
+ resource.path.split("/").group_by { |e| e }["method_add_block"].size
419
419
  end
420
420
 
421
421
  # Recurse the nested arrays provided by Ripper to create a tree we can more
@@ -437,7 +437,7 @@ module FoodCritic
437
437
  xml_array_node(doc, xml_node, child)
438
438
  end
439
439
  else
440
- xml_node['value'] = child.to_s unless child.nil?
440
+ xml_node["value"] = child.to_s unless child.nil?
441
441
  end
442
442
  end
443
443
  end
@@ -446,27 +446,27 @@ module FoodCritic
446
446
  end
447
447
 
448
448
  def extract_attribute_value(att, options = {})
449
- if !att.xpath('args_add_block[count(descendant::args_add)>1]').empty?
450
- att.xpath('args_add_block').first
449
+ if !att.xpath("args_add_block[count(descendant::args_add)>1]").empty?
450
+ att.xpath("args_add_block").first
451
451
  elsif !att.xpath('args_add_block/args_add/
452
452
  var_ref/kw[@value="true" or @value="false"]').empty?
453
453
  att.xpath('string(args_add_block/args_add/
454
- var_ref/kw/@value)') == 'true'
455
- elsif !att.xpath('descendant::assoc_new').empty?
456
- att.xpath('descendant::assoc_new')
457
- elsif !att.xpath('descendant::int').empty?
458
- att.xpath('descendant::int/@value').to_s
459
- elsif att.xpath('descendant::symbol').empty?
454
+ var_ref/kw/@value)') == "true"
455
+ elsif !att.xpath("descendant::assoc_new").empty?
456
+ att.xpath("descendant::assoc_new")
457
+ elsif !att.xpath("descendant::int").empty?
458
+ att.xpath("descendant::int/@value").to_s
459
+ elsif att.xpath("descendant::symbol").empty?
460
460
  if options[:return_expressions] &&
461
- (att.xpath('descendant::string_add').size != 1 ||
462
- att.xpath('descendant::*[self::call or
463
- self::string_embexpr]').any?)
461
+ (att.xpath("descendant::string_add").size != 1 ||
462
+ att.xpath('descendant::*[self::call or
463
+ self::string_embexpr]').any?)
464
464
  att
465
465
  else
466
- att.xpath('string(descendant::tstring_content/@value)')
466
+ att.xpath("string(descendant::tstring_content/@value)")
467
467
  end
468
468
  else
469
- att.xpath('string(descendant::symbol/ident/@value)').to_sym
469
+ att.xpath("string(descendant::symbol/ident/@value)").to_sym
470
470
  end
471
471
  end
472
472
 
@@ -485,7 +485,7 @@ module FoodCritic
485
485
  atts = {}
486
486
  resource.xpath('do_block/descendant::*[self::command or
487
487
  self::method_add_arg][count(ancestor::do_block) >= 1]').each do |att|
488
- blocks = att.xpath('ancestor::method_add_block/method_add_arg/fcall')
488
+ blocks = att.xpath("ancestor::method_add_block/method_add_arg/fcall")
489
489
  next if blocks.any? { |a| block_depth(a) > block_depth(resource) }
490
490
  att_name = att.xpath('string(ident/@value |
491
491
  fcall/ident[@value="variables"]/@value)')
@@ -500,8 +500,8 @@ module FoodCritic
500
500
  return false if cookbook_dir.nil? || !Dir.exist?(cookbook_dir)
501
501
 
502
502
  # TODO: Modify this to work with multiple cookbook paths
503
- cbk_tree_path = Pathname.new(File.join(cookbook_dir, '..'))
504
- libs = Dir[File.join(cbk_tree_path.realpath, '*/libraries/*.rb')]
503
+ cbk_tree_path = Pathname.new(File.join(cookbook_dir, ".."))
504
+ libs = Dir[File.join(cbk_tree_path.realpath, "*/libraries/*.rb")]
505
505
 
506
506
  libs.any? do |lib|
507
507
  !read_ast(lib).xpath(%Q{//class[count(descendant::const[@value='Chef'])
@@ -512,15 +512,15 @@ module FoodCritic
512
512
 
513
513
  def raise_unless_xpath!(ast)
514
514
  unless ast.respond_to?(:xpath)
515
- fail ArgumentError, 'AST must support #xpath'
515
+ raise ArgumentError, 'AST must support #xpath'
516
516
  end
517
517
  end
518
518
 
519
519
  def uncached_read_ast(file)
520
- source = if file.to_s.split(File::SEPARATOR).include?('templates')
520
+ source = if file.to_s.split(File::SEPARATOR).include?("templates")
521
521
  template_expressions_only(file)
522
522
  else
523
- File.read(file).encode('utf-8', 'binary', :undef => :replace)
523
+ File.read(file).encode("utf-8", "binary", :undef => :replace)
524
524
  end
525
525
  build_xml(Ripper::SexpBuilder.new(source).parse)
526
526
  end
@@ -530,22 +530,25 @@ module FoodCritic
530
530
  def is_att_type(value)
531
531
  return [] unless value.respond_to?(:select)
532
532
  value.select do |n|
533
- %w(
533
+ %w{
534
534
  automatic_attrs
535
535
  default
536
536
  default!
537
537
  default_unless
538
538
  force_default
539
+ force_default!
539
540
  force_override
541
+ force_override!
540
542
  node
541
543
  normal
544
+ normal!
542
545
  normal_unless
543
546
  override
544
547
  override!
545
548
  override_unless
546
549
  set
547
550
  set_unless
548
- ).include?(n.to_s)
551
+ }.include?(n.to_s)
549
552
  end
550
553
  end
551
554
  end
@@ -557,20 +560,20 @@ module FoodCritic
557
560
  end.inject(:+)
558
561
  else
559
562
  type = if options[:type] == :string
560
- 'tstring_content'
563
+ "tstring_content"
561
564
  else
562
- '*[self::symbol or self::dyna_symbol]'
565
+ "*[self::symbol or self::dyna_symbol]"
563
566
  end
564
- expr = '//*[self::aref_field or self::aref][count(method_add_arg) = 0]'
567
+ expr = "//*[self::aref_field or self::aref][count(method_add_arg) = 0]"
565
568
  expr += '[count(is_att_type(descendant::var_ref/ident/@value)) =
566
569
  count(descendant::var_ref/ident/@value)]'
567
- expr += '[is_att_type(descendant::ident'
568
- expr += '[not(ancestor::aref/call)]' if options[:ignore_calls]
569
- expr += '/@value)]'
570
+ expr += "[is_att_type(descendant::ident"
571
+ expr += "[not(ancestor::aref/call)]" if options[:ignore_calls]
572
+ expr += "/@value)]"
570
573
  expr += ignore_attributes_xpath(options[:ignore])
571
574
  expr += "/descendant::#{type}"
572
575
  if options[:type] == :string
573
- expr += '[count(ancestor::dyna_symbol) = 0]'
576
+ expr += "[count(ancestor::dyna_symbol) = 0]"
574
577
  end
575
578
  ast.xpath(expr, AttFilter.new).sort
576
579
  end
@@ -578,11 +581,11 @@ module FoodCritic
578
581
 
579
582
  def template_expressions_only(file)
580
583
  exprs = Template::ExpressionExtractor.new.extract(
581
- File.read(file).encode('utf-8', 'binary', :undef => :replace)
584
+ File.read(file).encode("utf-8", "binary", :undef => :replace)
582
585
  )
583
- lines = Array.new(exprs.map { |e| e[:line] }.max || 0, '')
586
+ lines = Array.new(exprs.map { |e| e[:line] }.max || 0, "")
584
587
  exprs.each do |e|
585
- lines[e[:line] - 1] += ';' unless lines[e[:line] - 1].empty?
588
+ lines[e[:line] - 1] += ";" unless lines[e[:line] - 1].empty?
586
589
  lines[e[:line] - 1] += e[:code]
587
590
  end
588
591
  lines.join("\n")
@@ -594,9 +597,9 @@ module FoodCritic
594
597
  #{ignore_attributes_xpath(options[:ignore])}
595
598
  [@value='.'][count(following-sibling::arg_paren) = 0]}, AttFilter.new)
596
599
  calls.select do |call|
597
- call.xpath('aref/args_add_block').size == 0 &&
598
- (call.xpath('descendant::ident').size > 1 &&
599
- !node_method?(call.xpath('ident/@value').to_s.to_sym,
600
+ call.xpath("aref/args_add_block").size == 0 &&
601
+ (call.xpath("descendant::ident").size > 1 &&
602
+ !node_method?(call.xpath("ident/@value").to_s.to_sym,
600
603
  options[:cookbook_dir]))
601
604
  end.sort
602
605
  end
@@ -606,9 +609,9 @@ module FoodCritic
606
609
  if var_ref.empty?
607
610
  []
608
611
  else
609
- ast.xpath(%Q(descendant::block_var/params/
612
+ ast.xpath(%Q{descendant::block_var/params/
610
613
  ident#{var_ref.first['value']}/ancestor::method_add_block/call/
611
- descendant::tstring_content))
614
+ descendant::tstring_content})
612
615
  end
613
616
  end
614
617
  end