foodcritic 16.1.1 → 16.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -88,6 +88,7 @@
88
88
  "locale",
89
89
  "log",
90
90
  "mac_os_x_userdefaults",
91
+ "mac_user",
91
92
  "macos_userdefaults",
92
93
  "macosx_service",
93
94
  "macports_package",
@@ -849,6 +850,7 @@
849
850
  ],
850
851
  "kernel_module": [
851
852
  "blacklist",
853
+ "disable",
852
854
  "install",
853
855
  "load",
854
856
  "nothing",
@@ -1257,6 +1259,7 @@
1257
1259
  ],
1258
1260
  "windows_ad_join": [
1259
1261
  "join",
1262
+ "leave",
1260
1263
  "nothing"
1261
1264
  ],
1262
1265
  "windows_autorun": [
@@ -4989,6 +4992,8 @@
4989
4992
  "itself",
4990
4993
  "kind_of?",
4991
4994
  "lazy",
4995
+ "list_options",
4996
+ "list_options=",
4992
4997
  "load_from",
4993
4998
  "logger",
4994
4999
  "lookup_provider_constant",
@@ -5016,6 +5021,8 @@
5016
5021
  "package_name=",
5017
5022
  "params",
5018
5023
  "params=",
5024
+ "password",
5025
+ "password=",
5019
5026
  "platform?",
5020
5027
  "platform_family?",
5021
5028
  "powershell_exec",
@@ -5107,6 +5114,8 @@
5107
5114
  "updated?",
5108
5115
  "updated_by_last_action",
5109
5116
  "updated_by_last_action?",
5117
+ "user",
5118
+ "user=",
5110
5119
  "valid_windows_architecture?",
5111
5120
  "validate",
5112
5121
  "validate_action",
@@ -11138,6 +11147,8 @@
11138
11147
  "object_id",
11139
11148
  "older_than_win_2012_or_8?",
11140
11149
  "only_if",
11150
+ "options",
11151
+ "options=",
11141
11152
  "params",
11142
11153
  "params=",
11143
11154
  "platform?",
@@ -26071,6 +26082,8 @@
26071
26082
  "value_to_text",
26072
26083
  "with_os_architecture",
26073
26084
  "with_run_context",
26085
+ "workgroup_name",
26086
+ "workgroup_name=",
26074
26087
  "wow64_architecture_override_required?",
26075
26088
  "wow64_directory",
26076
26089
  "yield_self"
@@ -29,7 +29,7 @@ module FoodCritic
29
29
  options = { type: :any, ignore_calls: false }.merge!(options)
30
30
  return [] unless ast.respond_to?(:xpath)
31
31
 
32
- unless [:any, :string, :symbol, :vivified].include?(options[:type])
32
+ unless %i{any string symbol vivified}.include?(options[:type])
33
33
  raise ArgumentError, "Node type not recognised"
34
34
  end
35
35
 
@@ -56,9 +56,7 @@ module FoodCritic
56
56
 
57
57
  # get list of items in the dir and intersect with metadata array.
58
58
  # until we get an interfact (we have a metadata) walk up the dir structure
59
- until (Dir.entries(file) & %w{metadata.rb metadata.json}).any?
60
- file = File.dirname(file)
61
- end
59
+ file = File.dirname(file) until (Dir.entries(file) & %w{metadata.rb metadata.json}).any?
62
60
 
63
61
  file
64
62
  end
@@ -69,9 +67,7 @@ module FoodCritic
69
67
  # @since 7.0.0
70
68
  # @return [String] the value of the metadata field
71
69
  def metadata_field(file, field)
72
- until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
73
- file = File.absolute_path(File.dirname(file.to_s))
74
- end
70
+ file = File.absolute_path(File.dirname(file.to_s)) until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
75
71
  file = File.dirname(file) unless File.extname(file).empty?
76
72
 
77
73
  md_path = File.join(file, "metadata.rb")
@@ -80,6 +76,7 @@ module FoodCritic
80
76
  command[ident/@value='#{field}']/
81
77
  descendant::tstring_content/@value").to_s
82
78
  raise "Cant read #{field} from #{md_path}" if value.to_s.empty?
79
+
83
80
  return value
84
81
  else
85
82
  raise "Cant find #{md_path}"
@@ -98,9 +95,7 @@ module FoodCritic
98
95
  begin
99
96
  metadata_field(file, "name")
100
97
  rescue RuntimeError
101
- until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
102
- file = File.absolute_path(File.dirname(file.to_s))
103
- end
98
+ file = File.absolute_path(File.dirname(file.to_s)) until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
104
99
  file = File.dirname(file) unless File.extname(file).empty?
105
100
  File.basename(file)
106
101
  end
@@ -156,6 +151,7 @@ module FoodCritic
156
151
  if field_name.nil? || field_name.to_s.empty?
157
152
  raise ArgumentError, "Field name cannot be nil or empty"
158
153
  end
154
+
159
155
  ast.xpath("(.//command[ident/@value='#{field_name}']|.//fcall[ident/@value='#{field_name}']/..)")
160
156
  end
161
157
 
@@ -163,13 +159,14 @@ module FoodCritic
163
159
  def field_value(ast, field_name)
164
160
  field(ast, field_name).xpath('.//args_add_block//tstring_content
165
161
  [count(ancestor::args_add) = 1][count(ancestor::string_add) = 1]
166
- /@value').map { |a| a.to_s }.last
162
+ /@value').map(&:to_s).last
167
163
  end
168
164
 
169
165
  # Create a match for a specified file. Use this if the presence of the file
170
166
  # triggers the warning rather than content.
171
167
  def file_match(file)
172
168
  raise ArgumentError, "Filename cannot be nil" if file.nil?
169
+
173
170
  { filename: file, matched: file, line: 1, column: 1 }
174
171
  end
175
172
 
@@ -189,10 +186,11 @@ module FoodCritic
189
186
  def find_resources(ast, options = {})
190
187
  options = { type: :any }.merge!(options)
191
188
  return [] unless ast.respond_to?(:xpath)
189
+
192
190
  scope_type = ""
193
191
  unless options[:type] == :any
194
- type_array = Array(options[:type]).map { |x| "@value='#{x}'" }
195
- scope_type = "[#{type_array.join(' or ')}]"
192
+ type_array = Array(options[:type]).map { |x| "@value='#{x}'" }
193
+ scope_type = "[#{type_array.join(" or ")}]"
196
194
  end
197
195
 
198
196
  # TODO: Include nested resources (provider actions)
@@ -241,6 +239,7 @@ module FoodCritic
241
239
  # Searches with a query formed from a subexpression will be ignored.
242
240
  def literal_searches(ast)
243
241
  return [] unless ast.respond_to?(:xpath)
242
+
244
243
  ast.xpath("//method_add_arg[fcall/ident/@value = 'search' and
245
244
  count(descendant::string_embexpr) = 0]/descendant::tstring_content")
246
245
  end
@@ -250,6 +249,7 @@ module FoodCritic
250
249
  raise_unless_xpath!(node)
251
250
  pos = node.xpath("descendant::pos").first
252
251
  return nil if pos.nil?
252
+
253
253
  { matched: node.respond_to?(:name) ? node.name : "",
254
254
  line: pos["line"].to_i, column: pos["column"].to_i }
255
255
  end
@@ -273,6 +273,7 @@ module FoodCritic
273
273
  # Retrieve a single-valued attribute from the specified resource.
274
274
  def resource_attribute(resource, name)
275
275
  raise ArgumentError, "Attribute name cannot be empty" if name.empty?
276
+
276
277
  resource_attributes(resource)[name.to_s]
277
278
  end
278
279
 
@@ -306,7 +307,8 @@ module FoodCritic
306
307
  if name.xpath("descendant::string_add").size == 1 &&
307
308
  name.xpath("descendant::string_literal").size == 1 &&
308
309
  name.xpath(
309
- "descendant::*[self::call or self::string_embexpr]").empty?
310
+ "descendant::*[self::call or self::string_embexpr]"
311
+ ).empty?
310
312
  name.xpath("descendant::tstring_content/@value").to_s
311
313
  else
312
314
  name
@@ -320,7 +322,7 @@ module FoodCritic
320
322
  # Resources in an AST, keyed by type.
321
323
  def resources_by_type(ast)
322
324
  raise_unless_xpath!(ast)
323
- result = Hash.new { |hash, key| hash[key] = Array.new }
325
+ result = Hash.new { |hash, key| hash[key] = [] }
324
326
  find_resources(ast).each do |resource|
325
327
  result[resource_type(resource)] << resource
326
328
  end
@@ -334,6 +336,7 @@ module FoodCritic
334
336
  if type.empty?
335
337
  raise ArgumentError, "Provided AST node is not a resource"
336
338
  end
339
+
337
340
  type
338
341
  end
339
342
 
@@ -350,6 +353,7 @@ module FoodCritic
350
353
  # Searches performed by the provided AST.
351
354
  def searches(ast)
352
355
  return [] unless ast.respond_to?(:xpath)
356
+
353
357
  ast.xpath("//fcall/ident[@value = 'search']")
354
358
  end
355
359
 
@@ -398,9 +402,10 @@ module FoodCritic
398
402
 
399
403
  def templates_included(all_templates, template_path, depth = 1)
400
404
  raise RecursedTooFarError.new(template_path) if depth > 10
405
+
401
406
  partials = read_ast(template_path).xpath('//*[self::command or
402
407
  child::fcall][descendant::ident/@value="render"]//args_add/
403
- string_literal//tstring_content/@value').map { |p| p.to_s }
408
+ string_literal//tstring_content/@value').map(&:to_s)
404
409
  Array(template_path) + partials.map do |included_partial|
405
410
  partial_path = Array(all_templates).find do |path|
406
411
  (Pathname.new(template_path).dirname + included_partial).to_s == path
@@ -416,10 +421,10 @@ module FoodCritic
416
421
  def template_paths(recipe_path)
417
422
  Dir.glob(Pathname.new(recipe_path).dirname.dirname + "templates" +
418
423
  "**/*", File::FNM_DOTMATCH).select do |path|
419
- File.file?(path)
420
- end.reject do |path|
421
- File.basename(path) == ".DS_Store" || File.extname(path) == ".swp"
422
- end
424
+ File.file?(path)
425
+ end.reject do |path|
426
+ File.basename(path) == ".DS_Store" || File.extname(path) == ".swp"
427
+ end
423
428
  end
424
429
 
425
430
  # Give a filename path it returns the hash of the JSON contents
@@ -447,11 +452,11 @@ module FoodCritic
447
452
  atts = {}
448
453
  resource.xpath("do_block/descendant::method_add_block[
449
454
  count(ancestor::do_block) = 1][brace_block | do_block]").each do |batt|
450
- att_name = batt.xpath("string(method_add_arg/fcall/ident/@value)")
451
- if att_name && !att_name.empty? && batt.children.length > 1
452
- atts[att_name] = batt.children[1]
455
+ att_name = batt.xpath("string(method_add_arg/fcall/ident/@value)")
456
+ if att_name && !att_name.empty? && batt.children.length > 1
457
+ atts[att_name] = batt.children[1]
458
+ end
453
459
  end
454
- end
455
460
  atts
456
461
  end
457
462
 
@@ -531,14 +536,15 @@ module FoodCritic
531
536
  atts = {}
532
537
  resource.xpath('do_block/descendant::*[self::command or
533
538
  self::method_add_arg][count(ancestor::do_block) >= 1]').each do |att|
534
- blocks = att.xpath("ancestor::method_add_block/method_add_arg/fcall")
535
- next if blocks.any? { |a| block_depth(a) > block_depth(resource) }
536
- att_name = att.xpath('string(ident/@value |
537
- fcall/ident[@value="variables"]/@value)')
538
- unless att_name.empty?
539
- atts[att_name] = extract_attribute_value(att, options)
539
+ blocks = att.xpath("ancestor::method_add_block/method_add_arg/fcall")
540
+ next if blocks.any? { |a| block_depth(a) > block_depth(resource) }
541
+
542
+ att_name = att.xpath('string(ident/@value |
543
+ fcall/ident[@value="variables"]/@value)')
544
+ unless att_name.empty?
545
+ atts[att_name] = extract_attribute_value(att, options)
546
+ end
540
547
  end
541
- end
542
548
  atts
543
549
  end
544
550
 
@@ -579,6 +585,7 @@ module FoodCritic
579
585
  class AttFilter
580
586
  def is_att_type(value)
581
587
  return [] unless value.respond_to?(:select)
588
+
582
589
  value.select do |n|
583
590
  %w{
584
591
  automatic_attrs
@@ -605,7 +612,7 @@ module FoodCritic
605
612
 
606
613
  def standard_attribute_access(ast, options)
607
614
  if options[:type] == :any
608
- [:string, :symbol].map do |type|
615
+ %i{string symbol}.map do |type|
609
616
  standard_attribute_access(ast, options.merge(type: type))
610
617
  end.inject(:+)
611
618
  else
@@ -650,13 +657,13 @@ module FoodCritic
650
657
  call.xpath("aref/args_add_block").size == 0 &&
651
658
  (call.xpath("descendant::ident").size > 1 &&
652
659
  !node_method?(call.xpath("ident/@value").to_s.to_sym,
653
- options[:cookbook_dir]))
660
+ options[:cookbook_dir]))
654
661
  end.sort
655
662
  end
656
663
 
657
664
  def word_list_values(ast, xpath = nil)
658
665
  # Find the node for the field argument variable. (e.g. given `foo d`, find `d`)
659
- var_ref = ast.xpath("#{xpath ? xpath + '/' : ''}descendant::var_ref/ident")
666
+ var_ref = ast.xpath("#{xpath ? xpath + "/" : ""}descendant::var_ref/ident")
660
667
  if var_ref.empty?
661
668
  # The field is either a static value, or took no arguments, or something
662
669
  # more complex than we care to evaluate.
@@ -665,7 +672,7 @@ module FoodCritic
665
672
  # Look back out the tree for a method_add_block which contains a block
666
673
  # variable matching the field argument variable, and then drill down to
667
674
  # all the literal content nodes.
668
- ast.xpath(%Q{ancestor::method_add_block[//block_var//ident/@value='#{var_ref.first['value']}']/call//tstring_content})
675
+ ast.xpath(%Q{ancestor::method_add_block[//block_var//ident/@value='#{var_ref.first["value"]}']/call//tstring_content})
669
676
  end
670
677
  end
671
678
  end
@@ -56,12 +56,12 @@ module FoodCritic
56
56
  metadata_path(ver)
57
57
  end.find { |m| File.exist?(m) }
58
58
  @dsl_metadata ||= FFI_Yajl::Parser.parse(IO.read(metadata_path),
59
- symbolize_keys: true)
59
+ symbolize_keys: true)
60
60
  end
61
61
 
62
62
  def metadata_path(chef_version)
63
63
  File.join(File.dirname(__FILE__), "..", "..",
64
- "chef_dsl_metadata/chef_#{chef_version}.json")
64
+ "chef_dsl_metadata/chef_#{chef_version}.json")
65
65
  end
66
66
 
67
67
  def resource_check?(key, resource_type, field)
@@ -94,9 +94,11 @@ module FoodCritic
94
94
  grammar_paths.inject(nil) do |parser, lucene_grammar|
95
95
  begin
96
96
  break parser unless parser.nil?
97
+
97
98
  # Don't instantiate custom nodes
98
99
  Treetop.load_from_string(
99
- IO.read(lucene_grammar).gsub(/<[^>]+>/, ""))
100
+ IO.read(lucene_grammar).gsub(/<[^>]+>/, "")
101
+ )
100
102
  LuceneParser.new
101
103
  rescue
102
104
  # Silently swallow and try the next grammar
@@ -29,74 +29,74 @@ module FoodCritic
29
29
  @parser = OptionParser.new do |opts|
30
30
  opts.banner = "foodcritic [cookbook_paths]"
31
31
  opts.on("-t", "--tags TAGS",
32
- "Check against (or exclude ~) rules with the "\
33
- "specified tags.") do |t|
34
- @options[:tags] << t
35
- end
32
+ "Check against (or exclude ~) rules with the "\
33
+ "specified tags.") do |t|
34
+ @options[:tags] << t
35
+ end
36
36
  opts.on("-l", "--list",
37
- "List all enabled rules and their descriptions.") do |t|
38
- @options[:list] = t
39
- end
37
+ "List all enabled rules and their descriptions.") do |t|
38
+ @options[:list] = t
39
+ end
40
40
  opts.on("-f", "--epic-fail TAGS",
41
- "Fail the build based on tags. Default of 'any' to fail "\
42
- "on all warnings.") do |t|
43
- @options[:fail_tags] << t
44
- end
41
+ "Fail the build based on tags. Default of 'any' to fail "\
42
+ "on all warnings.") do |t|
43
+ @options[:fail_tags] << t
44
+ end
45
45
  opts.on("-c", "--chef-version VERSION",
46
- "Only check against rules valid for this version "\
47
- "of Chef.") do |c|
48
- @options[:chef_version] = c
49
- end
46
+ "Only check against rules valid for this version "\
47
+ "of Chef.") do |c|
48
+ @options[:chef_version] = c
49
+ end
50
50
  opts.on("-r", "--rule-file PATH",
51
- "Specify file with rules to be used or ignored ") do |c|
52
- @options[:rule_file] = c
53
- end
51
+ "Specify file with rules to be used or ignored ") do |c|
52
+ @options[:rule_file] = c
53
+ end
54
54
  opts.on("-s", "--ast-cache-size NUM", Integer,
55
- "Change the size of the AST cache.") do |s|
56
- @options[:ast_cache_size] = s
57
- end
55
+ "Change the size of the AST cache.") do |s|
56
+ @options[:ast_cache_size] = s
57
+ end
58
58
  opts.on("-B", "--cookbook-path PATH",
59
- "Cookbook path(s) to check.") do |b|
60
- @options[:cookbook_paths] << b
61
- end
59
+ "Cookbook path(s) to check.") do |b|
60
+ @options[:cookbook_paths] << b
61
+ end
62
62
  opts.on("-C", "--[no-]context",
63
- "Show lines matched against rather than the "\
64
- "default summary.") do |c|
65
- @options[:context] = c
66
- end
63
+ "Show lines matched against rather than the "\
64
+ "default summary.") do |c|
65
+ @options[:context] = c
66
+ end
67
67
  opts.on("-E", "--environment-path PATH",
68
- "Environment path(s) to check.") do |e|
69
- @options[:environment_paths] << e
70
- end
68
+ "Environment path(s) to check.") do |e|
69
+ @options[:environment_paths] << e
70
+ end
71
71
  opts.on("-I", "--include PATH",
72
- "Additional rule file path(s) to load.") do |i|
73
- @options[:include_rules] << i
74
- end
72
+ "Additional rule file path(s) to load.") do |i|
73
+ @options[:include_rules] << i
74
+ end
75
75
  opts.on("-G", "--search-gems",
76
- "Search rubygems for rule files with the path "\
77
- "foodcritic/rules/**/*.rb") do |g|
78
- @options[:search_gems] = true
79
- end
76
+ "Search rubygems for rule files with the path "\
77
+ "foodcritic/rules/**/*.rb") do |g|
78
+ @options[:search_gems] = true
79
+ end
80
80
  opts.on("-P", "--[no-]progress",
81
- "Show progress of files being checked. default: true") do |q|
82
- @options[:progress] = q
83
- end
81
+ "Show progress of files being checked. default: true") do |q|
82
+ @options[:progress] = q
83
+ end
84
84
  opts.on("-R", "--role-path PATH",
85
- "Role path(s) to check.") do |r|
86
- @options[:role_paths] << r
87
- end
85
+ "Role path(s) to check.") do |r|
86
+ @options[:role_paths] << r
87
+ end
88
88
  opts.on("-S", "--search-grammar PATH",
89
- "Specify grammar to use when validating search syntax.") do |s|
90
- @options[:search_grammar] = s
91
- end
89
+ "Specify grammar to use when validating search syntax.") do |s|
90
+ @options[:search_grammar] = s
91
+ end
92
92
  opts.on("-V", "--version",
93
- "Display the foodcritic version.") do |v|
94
- @options[:version] = true
95
- end
93
+ "Display the foodcritic version.") do |v|
94
+ @options[:version] = true
95
+ end
96
96
  opts.on("-X", "--exclude PATH",
97
- "Exclude path(s) from being linted. PATH is relative to the cookbook, not an absolute PATH. Default test/**/*,spec/**/*,features/**/*") do |e|
98
- options[:exclude_paths] << e
99
- end
97
+ "Exclude path(s) from being linted. PATH is relative to the cookbook, not an absolute PATH. Default test/**/*,spec/**/*,features/**/*") do |e|
98
+ options[:exclude_paths] << e
99
+ end
100
100
  end
101
101
  # -v is not implemented but OptionParser gives the Foodcritic's version
102
102
  # if that flag is passed
@@ -162,6 +162,7 @@ module FoodCritic
162
162
  def valid_grammar?
163
163
  return true unless options.key?(:search_grammar)
164
164
  return false unless File.exist?(options[:search_grammar])
165
+
165
166
  search = FoodCritic::Chef::Search.new
166
167
  search.create_parser([options[:search_grammar]])
167
168
  search.parser?