foodcritic 7.0.1 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,7 +23,7 @@ module FoodCritic
23
23
 
24
24
  # Is this a valid Lucene query?
25
25
  def valid_query?(query)
26
- fail ArgumentError, 'Query cannot be nil or empty' if query.to_s.empty?
26
+ raise ArgumentError, "Query cannot be nil or empty" if query.to_s.empty?
27
27
 
28
28
  # Attempt to create a search query parser
29
29
  search = FoodCritic::Chef::Search.new
@@ -51,7 +51,7 @@ module FoodCritic
51
51
  else
52
52
  Linter::DEFAULT_CHEF_VERSION
53
53
  end
54
- metadata_path = [version, version.sub(/\.[a-z].*/, ''),
54
+ metadata_path = [version, version.sub(/\.[a-z].*/, ""),
55
55
  Linter::DEFAULT_CHEF_VERSION].map do |version|
56
56
  metadata_path(version)
57
57
  end.find { |m| File.exist?(m) }
@@ -60,13 +60,13 @@ module FoodCritic
60
60
  end
61
61
 
62
62
  def metadata_path(chef_version)
63
- File.join(File.dirname(__FILE__), '..', '..',
63
+ File.join(File.dirname(__FILE__), "..", "..",
64
64
  "chef_dsl_metadata/chef_#{chef_version}.json")
65
65
  end
66
66
 
67
67
  def resource_check?(key, resource_type, field)
68
68
  if resource_type.to_s.empty? || field.to_s.empty?
69
- fail ArgumentError, 'Arguments cannot be nil or empty.'
69
+ raise ArgumentError, "Arguments cannot be nil or empty."
70
70
  end
71
71
 
72
72
  load_metadata
@@ -85,23 +85,23 @@ module FoodCritic
85
85
  # lucene.treetop used to be provided by chef gem
86
86
  # We're keeping a local copy from chef 10.x
87
87
  def chef_search_grammars
88
- [File.expand_path('../../..', __FILE__) + "/misc/lucene.treetop"]
88
+ [File.expand_path("../../..", __FILE__) + "/misc/lucene.treetop"]
89
89
  end
90
90
 
91
91
  # Create the search parser from the first loadable grammar.
92
92
  def create_parser(grammar_paths)
93
93
  @search_parser ||=
94
94
  grammar_paths.inject(nil) do |parser, lucene_grammar|
95
- begin
96
- break parser unless parser.nil?
97
- # Don't instantiate custom nodes
98
- Treetop.load_from_string(
99
- IO.read(lucene_grammar).gsub(/<[^>]+>/, ''))
100
- LuceneParser.new
101
- rescue
102
- # Silently swallow and try the next grammar
95
+ begin
96
+ break parser unless parser.nil?
97
+ # Don't instantiate custom nodes
98
+ Treetop.load_from_string(
99
+ IO.read(lucene_grammar).gsub(/<[^>]+>/, ""))
100
+ LuceneParser.new
101
+ rescue
102
+ # Silently swallow and try the next grammar
103
+ end
103
104
  end
104
- end
105
105
  end
106
106
 
107
107
  # Has the search parser been loaded?
@@ -14,75 +14,75 @@ module FoodCritic
14
14
  cookbook_paths: [],
15
15
  role_paths: [],
16
16
  environment_paths: [],
17
- exclude_paths: []
17
+ exclude_paths: [],
18
18
  }
19
19
  @parser = OptionParser.new do |opts|
20
- opts.banner = 'foodcritic [cookbook_paths]'
21
- opts.on('-t', '--tags TAGS',
22
- 'Check against (or exclude ~) rules with the '\
23
- 'specified tags.') do |t|
20
+ opts.banner = "foodcritic [cookbook_paths]"
21
+ opts.on("-t", "--tags TAGS",
22
+ "Check against (or exclude ~) rules with the "\
23
+ "specified tags.") do |t|
24
24
  @options[:tags] << t
25
25
  end
26
- opts.on('-l', '--list',
27
- 'List all enabled rules and their descriptions.') do |t|
26
+ opts.on("-l", "--list",
27
+ "List all enabled rules and their descriptions.") do |t|
28
28
  @options[:list] = t
29
- end
30
- opts.on('-f', '--epic-fail TAGS',
29
+ end
30
+ opts.on("-f", "--epic-fail TAGS",
31
31
  "Fail the build based on tags. Use 'any' to fail "\
32
- 'on all warnings.') do |t|
32
+ "on all warnings.") do |t|
33
33
  @options[:fail_tags] << t
34
34
  end
35
- opts.on('-c', '--chef-version VERSION',
36
- 'Only check against rules valid for this version '\
37
- 'of Chef.') do |c|
35
+ opts.on("-c", "--chef-version VERSION",
36
+ "Only check against rules valid for this version "\
37
+ "of Chef.") do |c|
38
38
  @options[:chef_version] = c
39
39
  end
40
- opts.on('-B', '--cookbook-path PATH',
41
- 'Cookbook path(s) to check.') do |b|
40
+ opts.on("-B", "--cookbook-path PATH",
41
+ "Cookbook path(s) to check.") do |b|
42
42
  @options[:cookbook_paths] << b
43
43
  end
44
- opts.on('-C', '--[no-]context',
45
- 'Show lines matched against rather than the '\
46
- 'default summary.') do |c|
44
+ opts.on("-C", "--[no-]context",
45
+ "Show lines matched against rather than the "\
46
+ "default summary.") do |c|
47
47
  @options[:context] = c
48
48
  end
49
- opts.on('-E', '--environment-path PATH',
50
- 'Environment path(s) to check.') do |e|
49
+ opts.on("-E", "--environment-path PATH",
50
+ "Environment path(s) to check.") do |e|
51
51
  @options[:environment_paths] << e
52
52
  end
53
- opts.on('-I', '--include PATH',
54
- 'Additional rule file path(s) to load.') do |i|
53
+ opts.on("-I", "--include PATH",
54
+ "Additional rule file path(s) to load.") do |i|
55
55
  @options[:include_rules] << i
56
56
  end
57
- opts.on('-G', '--search-gems',
58
- 'Search rubygems for rule files with the path '\
59
- 'foodcritic/rules/**/*.rb') do |g|
57
+ opts.on("-G", "--search-gems",
58
+ "Search rubygems for rule files with the path "\
59
+ "foodcritic/rules/**/*.rb") do |g|
60
60
  @options[:search_gems] = true
61
61
  end
62
62
  opts.on("-P", "--progress",
63
63
  "Show progress of files being checked") do
64
64
  @options[:progress] = true
65
65
  end
66
- opts.on('-R', '--role-path PATH',
67
- 'Role path(s) to check.') do |r|
66
+ opts.on("-R", "--role-path PATH",
67
+ "Role path(s) to check.") do |r|
68
68
  @options[:role_paths] << r
69
69
  end
70
- opts.on('-S', '--search-grammar PATH',
71
- 'Specify grammar to use when validating search syntax.') do |s|
70
+ opts.on("-S", "--search-grammar PATH",
71
+ "Specify grammar to use when validating search syntax.") do |s|
72
72
  @options[:search_grammar] = s
73
73
  end
74
- opts.on('-V', '--version',
75
- 'Display the foodcritic version.') do |v|
74
+ opts.on("-V", "--version",
75
+ "Display the foodcritic version.") do |v|
76
76
  @options[:version] = true
77
77
  end
78
- opts.on('-X', '--exclude PATH',
79
- 'Exclude path(s) from being linted.') do |e|
78
+ opts.on("-X", "--exclude PATH",
79
+ "Exclude path(s) from being linted.") do |e|
80
80
  options[:exclude_paths] << e
81
81
  end
82
82
  end
83
83
  # -v is not implemented but OptionParser gives the Foodcritic's version
84
84
  # if that flag is passed
85
- if args.include? '-v'
85
+ if args.include? "-v"
86
86
  help
87
87
  else
88
88
  begin
@@ -97,7 +97,7 @@ module FoodCritic
97
97
  #
98
98
  # @return [Boolean] True if help should be shown.
99
99
  def show_help?
100
- @args.length == 1 && @args.first == '--help'
100
+ @args.length == 1 && @args.first == "--help"
101
101
  end
102
102
 
103
103
  # The help text.
@@ -1,4 +1,4 @@
1
- require 'cucumber/core/gherkin/tag_expression'
1
+ require "cucumber/core/gherkin/tag_expression"
2
2
 
3
3
  module FoodCritic
4
4
  # A warning of a possible issue
@@ -33,7 +33,7 @@ module FoodCritic
33
33
  end
34
34
 
35
35
  def to_s
36
- @rules.sort { |a,b| a.code <=> b.code }.
36
+ @rules.sort { |a, b| a.code <=> b.code }.
37
37
  map { |r| r.to_s }.join("\n")
38
38
  end
39
39
 
@@ -69,7 +69,7 @@ module FoodCritic
69
69
  w.match[:line].to_i]
70
70
  end.sort do |x, y|
71
71
  x.first == y.first ? x[1] <=> y[1] : x.first <=> y.first
72
- end.map { |w|"#{w.first}:#{w[1]}" }.uniq.join("\n")
72
+ end.map { |w| "#{w.first}:#{w[1]}" }.uniq.join("\n")
73
73
  end
74
74
  end
75
75
 
@@ -90,7 +90,7 @@ module FoodCritic
90
90
  # The tags associated with this rule. Rule is always tagged with the tag
91
91
  # `any` and the rule code.
92
92
  def tags
93
- ['any'] + @tags
93
+ ["any"] + @tags
94
94
  end
95
95
 
96
96
  # Checks the rule tags to see if they match a Gherkin (Cucumber) expression
@@ -1,4 +1,4 @@
1
- require 'pathname'
1
+ require "pathname"
2
2
 
3
3
  module FoodCritic
4
4
  # The DSL methods exposed for defining rules. A minimal example rule:
@@ -59,7 +59,6 @@ module FoodCritic
59
59
  # `recipe` rule blocks are also evaluated against providers.
60
60
  rule_block :recipe
61
61
 
62
-
63
62
  rule_block :cookbook
64
63
  rule_block :metadata
65
64
  rule_block :resource
@@ -1,6 +1,6 @@
1
- require 'optparse'
2
- require 'ripper'
3
- require 'set'
1
+ require "optparse"
2
+ require "ripper"
3
+ require "set"
4
4
 
5
5
  module FoodCritic
6
6
  # The main entry point for linting your Chef cookbooks.
@@ -9,7 +9,7 @@ module FoodCritic
9
9
 
10
10
  # The default version that will be used to determine relevant rules. This
11
11
  # can be over-ridden at the command line with the `--chef-version` option.
12
- DEFAULT_CHEF_VERSION = '12.11.18'
12
+ DEFAULT_CHEF_VERSION = "12.13.37"
13
13
  attr_reader :chef_version
14
14
 
15
15
  # Perform a lint check. This method is intended for use by the command-line
@@ -51,7 +51,6 @@ module FoodCritic
51
51
  RuleList.new(@rules)
52
52
  end
53
53
 
54
-
55
54
  # Review the cookbooks at the provided path, identifying potential
56
55
  # improvements.
57
56
  #
@@ -88,7 +87,7 @@ module FoodCritic
88
87
  cookbook_tags(p[:filename])
89
88
  end
90
89
 
91
- progress = '.'
90
+ progress = "."
92
91
 
93
92
  active_rules(relevant_tags).each do |rule|
94
93
  state = {
@@ -96,7 +95,7 @@ module FoodCritic
96
95
  file: p[:filename],
97
96
  ast: read_ast(p[:filename]),
98
97
  rule: rule,
99
- last_dir: last_dir
98
+ last_dir: last_dir,
100
99
  }
101
100
 
102
101
  matches = if p[:path_type] == :cookbook
@@ -107,7 +106,7 @@ module FoodCritic
107
106
 
108
107
  matches = remove_ignored(matches, state[:rule], state[:file])
109
108
 
110
- progress = 'x' if matches.any?
109
+ progress = "x" if matches.any?
111
110
 
112
111
  # Convert the matches into warnings
113
112
  matches.each do |match|
@@ -123,7 +122,7 @@ module FoodCritic
123
122
  last_dir = cookbook_dir(p[:filename])
124
123
  end
125
124
 
126
- puts '' if options[:progress]
125
+ puts "" if options[:progress]
127
126
 
128
127
  Review.new(paths, warnings)
129
128
  end
@@ -137,7 +136,7 @@ module FoodCritic
137
136
  end
138
137
 
139
138
  per_cookbook_rules(state[:last_dir], state[:file]) do
140
- if File.basename(state[:file]) == 'metadata.rb'
139
+ if File.basename(state[:file]) == "metadata.rb"
141
140
  cbk_matches += matches(
142
141
  state[:rule].metadata, state[:ast], state[:file])
143
142
  end
@@ -158,7 +157,7 @@ module FoodCritic
158
157
  end
159
158
 
160
159
  def load_rules!(options)
161
- rule_files = [File.join(File.dirname(__FILE__), 'rules.rb')]
160
+ rule_files = [File.join(File.dirname(__FILE__), "rules.rb")]
162
161
  rule_files << options[:include_rules]
163
162
  rule_files << rule_files_in_gems if options[:search_gems]
164
163
  @rules = RuleDsl.load(rule_files.flatten.compact, chef_version)
@@ -168,7 +167,7 @@ module FoodCritic
168
167
 
169
168
  def rule_files_in_gems
170
169
  Gem::Specification.latest_specs(true).map do |spec|
171
- spec.matches_for_glob('foodcritic/rules/**/*.rb')
170
+ spec.matches_for_glob("foodcritic/rules/**/*.rb")
172
171
  end.flatten
173
172
  end
174
173
 
@@ -176,14 +175,14 @@ module FoodCritic
176
175
  matches.reject do |m|
177
176
  matched_file = m[:filename] || file
178
177
  (line = m[:line]) && File.exist?(matched_file) &&
179
- !File.directory?(matched_file) &&
180
- ignore_line_match?(File.readlines(matched_file)[line - 1], rule)
178
+ !File.directory?(matched_file) &&
179
+ ignore_line_match?(File.readlines(matched_file)[line - 1], rule)
181
180
  end
182
181
  end
183
182
 
184
183
  def ignore_line_match?(line, rule)
185
184
  ignores = line.to_s[/\s+#\s*(.*)/, 1]
186
- if ignores && ignores.include?('~')
185
+ if ignores && ignores.include?("~")
187
186
  !rule.matches_tags?(ignores.split(/[ ,]/))
188
187
  else
189
188
  false
@@ -220,21 +219,21 @@ module FoodCritic
220
219
  def cookbook_dir(file)
221
220
  Pathname.new(File.join(File.dirname(file),
222
221
  case File.basename(file)
223
- when 'metadata.rb' then ''
224
- when /\.erb$/ then '../..'
225
- else '..'
222
+ when "metadata.rb" then ""
223
+ when /\.erb$/ then "../.."
224
+ else ".."
226
225
  end)).cleanpath
227
226
  end
228
227
 
229
228
  def dsl_method_for_file(file)
230
229
  dir_mapping = {
231
- 'attributes' => :attributes,
232
- 'libraries' => :library,
233
- 'providers' => :provider,
234
- 'resources' => :resource,
235
- 'templates' => :template
230
+ "attributes" => :attributes,
231
+ "libraries" => :library,
232
+ "providers" => :provider,
233
+ "resources" => :resource,
234
+ "templates" => :template,
236
235
  }
237
- if file.end_with? '.erb'
236
+ if file.end_with? ".erb"
238
237
  dir_mapping[File.basename(File.dirname(File.dirname(file)))]
239
238
  else
240
239
  dir_mapping[File.basename(File.dirname(file))]
@@ -250,16 +249,16 @@ module FoodCritic
250
249
 
251
250
  unless paths[:exclude].empty?
252
251
  exclusions = Dir.glob(paths[:exclude].map do |p|
253
- File.join(dir, p, '**/**')
252
+ File.join(dir, p, "**/**")
254
253
  end)
255
254
  end
256
255
 
257
256
  if File.directory?(dir)
258
257
  glob = if path_type == :cookbook
259
- '{metadata.rb,{attributes,definitions,libraries,'\
260
- 'providers,recipes,resources}/*.rb,templates/*/*.erb}'
258
+ "{metadata.rb,{attributes,definitions,libraries,"\
259
+ "providers,recipes,resources}/*.rb,templates/*/*.erb}"
261
260
  else
262
- '*.rb'
261
+ "*.rb"
263
262
  end
264
263
 
265
264
  (Dir.glob(File.join(dir, glob)) +
@@ -297,21 +296,21 @@ module FoodCritic
297
296
 
298
297
  def specified_paths!(options)
299
298
  paths = Hash[options.map do |key, value|
300
- [key, Array(value)] if key.to_s.end_with?('paths')
299
+ [key, Array(value)] if key.to_s.end_with?("paths")
301
300
  end.compact]
302
301
 
303
302
  unless paths.find { |k, v| k != :exclude_paths && !v.empty? }
304
- fail ArgumentError, 'A cookbook path or role path must be specified'
303
+ raise ArgumentError, "A cookbook path or role path must be specified"
305
304
  end
306
305
 
307
306
  Hash[paths.map do |key, value|
308
- [key.to_s.sub(/_paths$/, '').to_sym, value]
307
+ [key.to_s.sub(/_paths$/, "").to_sym, value]
309
308
  end]
310
309
  end
311
310
 
312
311
  def setup_defaults(options)
313
312
  { tags: [], fail_tags: [], include_rules: [], exclude_paths: [],
314
- cookbook_paths: [], role_paths: [] }.merge(options)
313
+ cookbook_paths: [], role_paths: [] }.merge(options)
315
314
  end
316
315
  end
317
316
  end
@@ -51,7 +51,7 @@ module FoodCritic
51
51
  action: notification_action(notify),
52
52
 
53
53
  # The notification timing: `:before`, `:immediate` or `:delayed`.
54
- timing: notification_timing(notify)
54
+ timing: notification_timing(notify),
55
55
  }
56
56
  )
57
57
  end.compact
@@ -80,11 +80,11 @@ module FoodCritic
80
80
  # Normally the `resource_name` will be a simple string. However in the
81
81
  # case where it has an embedded sub-expression then we will return the
82
82
  # AST to the caller to handle.
83
- if notify.xpath('descendant::string_embexpr').empty?
83
+ if notify.xpath("descendant::string_embexpr").empty?
84
84
  return nil if resource_name.empty?
85
85
  else
86
86
  resource_name =
87
- notify.xpath('args_add_block/args_add/string_literal')
87
+ notify.xpath("args_add_block/args_add/string_literal")
88
88
  end
89
89
  { resource_name: resource_name, resource_type: resource_type }
90
90
  end
@@ -93,7 +93,7 @@ module FoodCritic
93
93
  # notification.
94
94
  def old_style_notification(notify)
95
95
  resources = resource_hash_references(notify)
96
- resource_type = resources.xpath('symbol[1]/ident/@value').to_s.to_sym
96
+ resource_type = resources.xpath("symbol[1]/ident/@value").to_s.to_sym
97
97
  resource_name = resources.xpath('string_add[1][count(../
98
98
  descendant::string_add) = 1]/tstring_content/@value').to_s
99
99
  resource_name = resources if resource_name.empty?
@@ -136,7 +136,7 @@ module FoodCritic
136
136
  end
137
137
 
138
138
  def notification_type(notify)
139
- notify.xpath('ident/@value[1] | fcall/ident/@value[1]').to_s.to_sym
139
+ notify.xpath("ident/@value[1] | fcall/ident/@value[1]").to_s.to_sym
140
140
  end
141
141
 
142
142
  def resource_hash_references(ast)