foodcritic 1.6.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -109,7 +109,6 @@
109
109
  "private_methods",
110
110
  "protected_methods",
111
111
  "psych_to_yaml",
112
- "psych_y",
113
112
  "public_method",
114
113
  "public_methods",
115
114
  "public_send",
@@ -157,6 +156,156 @@
157
156
  "value_for_platform_family",
158
157
  "with_indexer_metadata"
159
158
  ],
159
+ "node_methods": [
160
+ "!",
161
+ "!=",
162
+ "!~",
163
+ "<=>",
164
+ "==",
165
+ "===",
166
+ "=~",
167
+ "[]",
168
+ "[]=",
169
+ "__id__",
170
+ "__send__",
171
+ "add_to_index",
172
+ "apply_expansion_attributes",
173
+ "attribute",
174
+ "attribute=",
175
+ "attribute?",
176
+ "automatic_attrs",
177
+ "automatic_attrs=",
178
+ "cdb_destroy",
179
+ "cdb_save",
180
+ "chef_environment",
181
+ "chef_server_rest",
182
+ "class",
183
+ "class_from_file",
184
+ "clone",
185
+ "construct_attributes",
186
+ "consume_attributes",
187
+ "consume_external_attrs",
188
+ "consume_run_list",
189
+ "convert_to_class_name",
190
+ "convert_to_snake_case",
191
+ "cookbook_collection",
192
+ "cookbook_collection=",
193
+ "couchdb",
194
+ "couchdb=",
195
+ "couchdb_id",
196
+ "couchdb_id=",
197
+ "couchdb_rev",
198
+ "couchdb_rev=",
199
+ "create",
200
+ "default",
201
+ "default_attrs",
202
+ "default_attrs=",
203
+ "default_unless",
204
+ "define_singleton_method",
205
+ "delete_from_index",
206
+ "destroy",
207
+ "display",
208
+ "display_hash",
209
+ "dup",
210
+ "each",
211
+ "each_attribute",
212
+ "each_key",
213
+ "each_value",
214
+ "enum_for",
215
+ "eql?",
216
+ "equal?",
217
+ "expand!",
218
+ "extend",
219
+ "filename_to_qualified_string",
220
+ "find_file",
221
+ "freeze",
222
+ "from_file",
223
+ "frozen?",
224
+ "gem",
225
+ "has_key?",
226
+ "hash",
227
+ "include_attribute",
228
+ "index_id",
229
+ "index_id=",
230
+ "index_object_type",
231
+ "initialize_clone",
232
+ "initialize_dup",
233
+ "inspect",
234
+ "instance_eval",
235
+ "instance_exec",
236
+ "instance_of?",
237
+ "instance_variable_defined?",
238
+ "instance_variable_get",
239
+ "instance_variable_set",
240
+ "instance_variables",
241
+ "is_a?",
242
+ "key?",
243
+ "keys",
244
+ "kind_of?",
245
+ "load_attribute_by_short_filename",
246
+ "load_attributes",
247
+ "method",
248
+ "method_missing",
249
+ "methods",
250
+ "name",
251
+ "nil?",
252
+ "node",
253
+ "normal",
254
+ "normal_attrs",
255
+ "normal_attrs=",
256
+ "normal_unless",
257
+ "object_id",
258
+ "override",
259
+ "override_attrs",
260
+ "override_attrs=",
261
+ "override_unless",
262
+ "private_methods",
263
+ "protected_methods",
264
+ "psych_to_yaml",
265
+ "public_method",
266
+ "public_methods",
267
+ "public_send",
268
+ "recipe?",
269
+ "recipe_list",
270
+ "recipe_list=",
271
+ "reset_defaults_and_overrides",
272
+ "respond_to?",
273
+ "respond_to_missing?",
274
+ "role?",
275
+ "run_list",
276
+ "run_list=",
277
+ "run_list?",
278
+ "run_state",
279
+ "run_state=",
280
+ "save",
281
+ "send",
282
+ "set",
283
+ "set_if_args",
284
+ "set_or_return",
285
+ "set_unless",
286
+ "singleton_class",
287
+ "singleton_methods",
288
+ "snake_case_basename",
289
+ "store",
290
+ "systemu",
291
+ "tags",
292
+ "taint",
293
+ "tainted?",
294
+ "tap",
295
+ "to_enum",
296
+ "to_hash",
297
+ "to_json",
298
+ "to_s",
299
+ "to_yaml",
300
+ "to_yaml_properties",
301
+ "trust",
302
+ "untaint",
303
+ "untrust",
304
+ "untrusted?",
305
+ "update_from!",
306
+ "validate",
307
+ "with_indexer_metadata"
308
+ ],
160
309
  "actions": {
161
310
  "apt_package": [
162
311
  "install",
@@ -562,7 +711,6 @@
562
711
  "provider",
563
712
  "provider=",
564
713
  "psych_to_yaml",
565
- "psych_y",
566
714
  "public_method",
567
715
  "public_methods",
568
716
  "public_send",
@@ -711,7 +859,6 @@
711
859
  "provider",
712
860
  "provider=",
713
861
  "psych_to_yaml",
714
- "psych_y",
715
862
  "public_method",
716
863
  "public_methods",
717
864
  "public_send",
@@ -851,7 +998,6 @@
851
998
  "provider",
852
999
  "provider=",
853
1000
  "psych_to_yaml",
854
- "psych_y",
855
1001
  "public_method",
856
1002
  "public_methods",
857
1003
  "public_send",
@@ -990,7 +1136,6 @@
990
1136
  "provider",
991
1137
  "provider=",
992
1138
  "psych_to_yaml",
993
- "psych_y",
994
1139
  "public_method",
995
1140
  "public_methods",
996
1141
  "public_send",
@@ -1137,7 +1282,6 @@
1137
1282
  "provider",
1138
1283
  "provider=",
1139
1284
  "psych_to_yaml",
1140
- "psych_y",
1141
1285
  "public_method",
1142
1286
  "public_methods",
1143
1287
  "public_send",
@@ -1284,7 +1428,6 @@
1284
1428
  "provider",
1285
1429
  "provider=",
1286
1430
  "psych_to_yaml",
1287
- "psych_y",
1288
1431
  "public_method",
1289
1432
  "public_methods",
1290
1433
  "public_send",
@@ -1433,7 +1576,6 @@
1433
1576
  "provider",
1434
1577
  "provider=",
1435
1578
  "psych_to_yaml",
1436
- "psych_y",
1437
1579
  "public_method",
1438
1580
  "public_methods",
1439
1581
  "public_send",
@@ -1591,7 +1733,6 @@
1591
1733
  "provider",
1592
1734
  "provider=",
1593
1735
  "psych_to_yaml",
1594
- "psych_y",
1595
1736
  "public_method",
1596
1737
  "public_methods",
1597
1738
  "public_send",
@@ -1767,7 +1908,6 @@
1767
1908
  "provider",
1768
1909
  "provider=",
1769
1910
  "psych_to_yaml",
1770
- "psych_y",
1771
1911
  "public_method",
1772
1912
  "public_methods",
1773
1913
  "public_send",
@@ -1943,7 +2083,6 @@
1943
2083
  "provider",
1944
2084
  "provider=",
1945
2085
  "psych_to_yaml",
1946
- "psych_y",
1947
2086
  "public_method",
1948
2087
  "public_methods",
1949
2088
  "public_send",
@@ -2105,7 +2244,6 @@
2105
2244
  "provider",
2106
2245
  "provider=",
2107
2246
  "psych_to_yaml",
2108
- "psych_y",
2109
2247
  "public_method",
2110
2248
  "public_methods",
2111
2249
  "public_send",
@@ -2245,7 +2383,6 @@
2245
2383
  "provider",
2246
2384
  "provider=",
2247
2385
  "psych_to_yaml",
2248
- "psych_y",
2249
2386
  "public_method",
2250
2387
  "public_methods",
2251
2388
  "public_send",
@@ -2388,7 +2525,6 @@
2388
2525
  "provider",
2389
2526
  "provider=",
2390
2527
  "psych_to_yaml",
2391
- "psych_y",
2392
2528
  "public_method",
2393
2529
  "public_methods",
2394
2530
  "public_send",
@@ -2530,7 +2666,6 @@
2530
2666
  "provider",
2531
2667
  "provider=",
2532
2668
  "psych_to_yaml",
2533
- "psych_y",
2534
2669
  "public_method",
2535
2670
  "public_methods",
2536
2671
  "public_send",
@@ -2672,7 +2807,6 @@
2672
2807
  "provider",
2673
2808
  "provider=",
2674
2809
  "psych_to_yaml",
2675
- "psych_y",
2676
2810
  "public_method",
2677
2811
  "public_methods",
2678
2812
  "public_send",
@@ -2815,7 +2949,6 @@
2815
2949
  "provider",
2816
2950
  "provider=",
2817
2951
  "psych_to_yaml",
2818
- "psych_y",
2819
2952
  "public_method",
2820
2953
  "public_methods",
2821
2954
  "public_send",
@@ -2962,7 +3095,6 @@
2962
3095
  "provider",
2963
3096
  "provider=",
2964
3097
  "psych_to_yaml",
2965
- "psych_y",
2966
3098
  "public_method",
2967
3099
  "public_methods",
2968
3100
  "public_send",
@@ -3101,7 +3233,6 @@
3101
3233
  "provider",
3102
3234
  "provider=",
3103
3235
  "psych_to_yaml",
3104
- "psych_y",
3105
3236
  "public_method",
3106
3237
  "public_methods",
3107
3238
  "public_send",
@@ -3243,7 +3374,6 @@
3243
3374
  "provider",
3244
3375
  "provider=",
3245
3376
  "psych_to_yaml",
3246
- "psych_y",
3247
3377
  "public_method",
3248
3378
  "public_methods",
3249
3379
  "public_send",
@@ -3388,7 +3518,6 @@
3388
3518
  "provider",
3389
3519
  "provider=",
3390
3520
  "psych_to_yaml",
3391
- "psych_y",
3392
3521
  "public_method",
3393
3522
  "public_methods",
3394
3523
  "public_send",
@@ -3539,7 +3668,6 @@
3539
3668
  "provider",
3540
3669
  "provider=",
3541
3670
  "psych_to_yaml",
3542
- "psych_y",
3543
3671
  "public_method",
3544
3672
  "public_methods",
3545
3673
  "public_send",
@@ -3679,7 +3807,6 @@
3679
3807
  "provider",
3680
3808
  "provider=",
3681
3809
  "psych_to_yaml",
3682
- "psych_y",
3683
3810
  "public_method",
3684
3811
  "public_methods",
3685
3812
  "public_send",
@@ -3827,7 +3954,6 @@
3827
3954
  "provider",
3828
3955
  "provider=",
3829
3956
  "psych_to_yaml",
3830
- "psych_y",
3831
3957
  "public_method",
3832
3958
  "public_methods",
3833
3959
  "public_send",
@@ -3968,7 +4094,6 @@
3968
4094
  "provider",
3969
4095
  "provider=",
3970
4096
  "psych_to_yaml",
3971
- "psych_y",
3972
4097
  "public_method",
3973
4098
  "public_methods",
3974
4099
  "public_send",
@@ -4108,7 +4233,6 @@
4108
4233
  "provider",
4109
4234
  "provider=",
4110
4235
  "psych_to_yaml",
4111
- "psych_y",
4112
4236
  "public_method",
4113
4237
  "public_methods",
4114
4238
  "public_send",
@@ -4246,7 +4370,6 @@
4246
4370
  "provider",
4247
4371
  "provider=",
4248
4372
  "psych_to_yaml",
4249
- "psych_y",
4250
4373
  "public_method",
4251
4374
  "public_methods",
4252
4375
  "public_send",
@@ -4391,7 +4514,6 @@
4391
4514
  "provider",
4392
4515
  "provider=",
4393
4516
  "psych_to_yaml",
4394
- "psych_y",
4395
4517
  "public_method",
4396
4518
  "public_methods",
4397
4519
  "public_send",
@@ -4537,7 +4659,6 @@
4537
4659
  "provider",
4538
4660
  "provider=",
4539
4661
  "psych_to_yaml",
4540
- "psych_y",
4541
4662
  "public_method",
4542
4663
  "public_methods",
4543
4664
  "public_send",
@@ -4674,7 +4795,6 @@
4674
4795
  "provider",
4675
4796
  "provider=",
4676
4797
  "psych_to_yaml",
4677
- "psych_y",
4678
4798
  "public_method",
4679
4799
  "public_methods",
4680
4800
  "public_send",
@@ -4812,7 +4932,6 @@
4812
4932
  "provider",
4813
4933
  "provider=",
4814
4934
  "psych_to_yaml",
4815
- "psych_y",
4816
4935
  "public_method",
4817
4936
  "public_methods",
4818
4937
  "public_send",
@@ -4953,7 +5072,6 @@
4953
5072
  "provider",
4954
5073
  "provider=",
4955
5074
  "psych_to_yaml",
4956
- "psych_y",
4957
5075
  "public_method",
4958
5076
  "public_methods",
4959
5077
  "public_send",
@@ -5102,7 +5220,6 @@
5102
5220
  "provider",
5103
5221
  "provider=",
5104
5222
  "psych_to_yaml",
5105
- "psych_y",
5106
5223
  "public_method",
5107
5224
  "public_methods",
5108
5225
  "public_send",
@@ -5244,7 +5361,6 @@
5244
5361
  "provider",
5245
5362
  "provider=",
5246
5363
  "psych_to_yaml",
5247
- "psych_y",
5248
5364
  "public_method",
5249
5365
  "public_methods",
5250
5366
  "public_send",
@@ -5393,7 +5509,6 @@
5393
5509
  "provider",
5394
5510
  "provider=",
5395
5511
  "psych_to_yaml",
5396
- "psych_y",
5397
5512
  "public_method",
5398
5513
  "public_methods",
5399
5514
  "public_send",
@@ -5543,7 +5658,6 @@
5543
5658
  "provider",
5544
5659
  "provider=",
5545
5660
  "psych_to_yaml",
5546
- "psych_y",
5547
5661
  "public_method",
5548
5662
  "public_methods",
5549
5663
  "public_send",
@@ -5691,7 +5805,6 @@
5691
5805
  "provider",
5692
5806
  "provider=",
5693
5807
  "psych_to_yaml",
5694
- "psych_y",
5695
5808
  "public_method",
5696
5809
  "public_methods",
5697
5810
  "public_send",
@@ -5838,7 +5951,6 @@
5838
5951
  "provider",
5839
5952
  "provider=",
5840
5953
  "psych_to_yaml",
5841
- "psych_y",
5842
5954
  "public_method",
5843
5955
  "public_methods",
5844
5956
  "public_send",
@@ -5978,7 +6090,6 @@
5978
6090
  "provider",
5979
6091
  "provider=",
5980
6092
  "psych_to_yaml",
5981
- "psych_y",
5982
6093
  "public_method",
5983
6094
  "public_methods",
5984
6095
  "public_send",
@@ -6127,7 +6238,6 @@
6127
6238
  "provider",
6128
6239
  "provider=",
6129
6240
  "psych_to_yaml",
6130
- "psych_y",
6131
6241
  "public_method",
6132
6242
  "public_methods",
6133
6243
  "public_send",
@@ -6268,7 +6378,6 @@
6268
6378
  "provider",
6269
6379
  "provider=",
6270
6380
  "psych_to_yaml",
6271
- "psych_y",
6272
6381
  "public_method",
6273
6382
  "public_methods",
6274
6383
  "public_send",
@@ -6408,7 +6517,6 @@
6408
6517
  "provider",
6409
6518
  "provider=",
6410
6519
  "psych_to_yaml",
6411
- "psych_y",
6412
6520
  "public_method",
6413
6521
  "public_methods",
6414
6522
  "public_send",
@@ -6563,7 +6671,6 @@
6563
6671
  "provider",
6564
6672
  "provider=",
6565
6673
  "psych_to_yaml",
6566
- "psych_y",
6567
6674
  "public_method",
6568
6675
  "public_methods",
6569
6676
  "public_send",
@@ -6707,7 +6814,6 @@
6707
6814
  "provider",
6708
6815
  "provider=",
6709
6816
  "psych_to_yaml",
6710
- "psych_y",
6711
6817
  "public_method",
6712
6818
  "public_methods",
6713
6819
  "public_send",
@@ -6852,7 +6958,6 @@
6852
6958
  "provider",
6853
6959
  "provider=",
6854
6960
  "psych_to_yaml",
6855
- "psych_y",
6856
6961
  "public_method",
6857
6962
  "public_methods",
6858
6963
  "public_send",
@@ -6995,7 +7100,6 @@
6995
7100
  "provider",
6996
7101
  "provider=",
6997
7102
  "psych_to_yaml",
6998
- "psych_y",
6999
7103
  "public_method",
7000
7104
  "public_methods",
7001
7105
  "public_send",
@@ -7149,7 +7253,6 @@
7149
7253
  "provider",
7150
7254
  "provider=",
7151
7255
  "psych_to_yaml",
7152
- "psych_y",
7153
7256
  "public_method",
7154
7257
  "public_methods",
7155
7258
  "public_send",
@@ -7306,7 +7409,6 @@
7306
7409
  "provider",
7307
7410
  "provider=",
7308
7411
  "psych_to_yaml",
7309
- "psych_y",
7310
7412
  "public_method",
7311
7413
  "public_methods",
7312
7414
  "public_send",
@@ -7471,7 +7573,6 @@
7471
7573
  "provider",
7472
7574
  "provider=",
7473
7575
  "psych_to_yaml",
7474
- "psych_y",
7475
7576
  "public_method",
7476
7577
  "public_methods",
7477
7578
  "public_send",
@@ -7616,7 +7717,6 @@
7616
7717
  "provider",
7617
7718
  "provider=",
7618
7719
  "psych_to_yaml",
7619
- "psych_y",
7620
7720
  "public_method",
7621
7721
  "public_methods",
7622
7722
  "public_send",
@@ -37,8 +37,8 @@ module FoodCritic
37
37
 
38
38
  # TODO: This expression is too loose, but also will fail to match other
39
39
  # types of conditionals.
40
- ! ast.xpath(%q{//if/*[self::aref or self::call][count(descendant::const[@value = 'Chef' or
41
- @value = 'Config']) = 2
40
+ ! ast.xpath(%q{//*[self::if or self::unless]/*[self::aref or self::call]
41
+ [count(descendant::const[@value = 'Chef' or @value = 'Config']) = 2
42
42
  and
43
43
  ( count(descendant::ident[@value='solo']) > 0
44
44
  or count(descendant::tstring_content[@value='solo']) > 0
@@ -369,6 +369,8 @@ module FoodCritic
369
369
  var_ref/kw/@value)') == 'true'
370
370
  elsif ! att.xpath('descendant::assoc_new').empty?
371
371
  att.xpath('descendant::assoc_new')
372
+ elsif ! att.xpath('descendant::int').empty?
373
+ att.xpath('descendant::int/@value').to_s
372
374
  elsif att.xpath('descendant::symbol').empty?
373
375
  if options[:return_expressions] and
374
376
  (att.xpath('descendant::string_add').size != 1 or
@@ -388,18 +390,18 @@ module FoodCritic
388
390
 
389
391
  def normal_attributes(resource, options = {})
390
392
  atts = {}
391
- # The ancestor check here ensures that nested blocks are not returned.
392
- # For example a method call within a `ruby_block` would otherwise be
393
- # returned as an attribute.
394
- #
395
- # TODO: This may need to be revisted in light of recent changes to the
396
- # application cookbook which is popularising nested blocks.
397
393
  resource.xpath('do_block/descendant::*[self::command or
398
- self::method_add_arg][count(ancestor::do_block) = 1]').each do |att|
394
+ self::method_add_arg][count(ancestor::do_block) >= 1]').each do |att|
395
+ next unless %w{block not_if only_if restart_command before_migrate
396
+ before_symlink before_restart after_restart}.all? do |block_att|
397
+ att.xpath("count(ancestor::method_add_block/method_add_arg/
398
+ fcall[ident/@value='#{block_att}']) = 0")
399
+ end
399
400
 
400
- unless att.xpath('string(ident/@value | fcall/ident/@value)').empty?
401
- atts[att.xpath('string(ident/@value | fcall/ident/@value)')] =
402
- extract_attribute_value(att, options)
401
+ att_name = att.xpath('string(ident/@value |
402
+ fcall/ident[@value="variables"]/@value)')
403
+ unless att_name.empty?
404
+ atts[att_name] = extract_attribute_value(att, options)
403
405
  end
404
406
  end
405
407
  atts
@@ -441,6 +443,7 @@ module FoodCritic
441
443
  else
442
444
  type = options[:type] == :string ? 'tstring_content' : options[:type]
443
445
  expr = '//*[self::aref_field or self::aref]'
446
+ expr += '[count(descendant::aref/var_ref) = 0]'
444
447
  expr += '[is_att_type(descendant::ident'
445
448
  expr += '[not(ancestor::aref/call)]' if options[:ignore_calls]
446
449
  expr += "/@value)]/descendant::#{type}"
@@ -8,6 +8,11 @@ module FoodCritic
8
8
  @dsl_metadata[:dsl_methods].map(&:to_sym)
9
9
  end
10
10
 
11
+ def chef_node_methods
12
+ load_metadata
13
+ @dsl_metadata[:node_methods].map(&:to_sym)
14
+ end
15
+
11
16
  # Is the specified action valid for the type of resource?
12
17
  def resource_action?(resource_type, action)
13
18
  resource_check?(:actions, resource_type, action)
@@ -53,8 +53,9 @@ module FoodCritic
53
53
 
54
54
  # A rule to be matched against.
55
55
  class Rule
56
- attr_accessor :code, :name, :applies_to, :cookbook, :recipe, :provider,
57
- :resource, :metadata, :library, :template
56
+ attr_accessor :code, :name, :applies_to, :cookbook, :attributes, :recipe,
57
+ :provider, :resource, :metadata, :library, :template
58
+
58
59
  attr_writer :tags
59
60
 
60
61
  def initialize(code, name)
@@ -59,6 +59,7 @@ module FoodCritic
59
59
  rule_block :cookbook
60
60
  rule_block :metadata
61
61
  rule_block :resource
62
+ rule_block :attributes
62
63
  rule_block :provider
63
64
  rule_block :library
64
65
  rule_block :template
@@ -43,7 +43,7 @@ module FoodCritic
43
43
  # * `:fail_tags` - The tags to fail the build on
44
44
  # * `:exclude_paths` - Paths to exclude from linting
45
45
  #
46
- def check(cookbook_paths, options)
46
+ def check(cookbook_paths, options = {})
47
47
 
48
48
  cookbook_paths = sanity_check_cookbook_paths(cookbook_paths)
49
49
  options = setup_defaults(options)
@@ -122,6 +122,7 @@ module FoodCritic
122
122
 
123
123
  def dsl_method_for_file(file)
124
124
  dir_mapping = {
125
+ 'attributes' => :attributes,
125
126
  'libraries' => :library,
126
127
  'providers' => :provider,
127
128
  'resources' => :resource,
@@ -64,7 +64,8 @@ module FoodCritic
64
64
 
65
65
  # Given `notifies :restart, "service[foo]"` the target is the
66
66
  # `"service[foo]"` string portion.
67
- target_path = 'args_add_block/args_add/descendant::tstring_content/@value'
67
+ target_path = 'args_add_block/args_add/descendant::
68
+ tstring_content[count(ancestor::dyna_symbol) = 0]/@value'
68
69
  target = notify.xpath("arg_paren/#{target_path} | #{target_path}").to_s
69
70
 
70
71
  # Test the target string against the standard syntax for a new-style
@@ -123,7 +124,8 @@ module FoodCritic
123
124
  end
124
125
 
125
126
  def notification_action(notify)
126
- notify.xpath('descendant::symbol[1]/ident/@value').to_s.to_sym
127
+ notify.xpath('descendant::symbol[1]/ident/@value |
128
+ descendant::dyna_symbol[1]/xstring_add/tstring_content/@value').first.to_s.to_sym
127
129
  end
128
130
 
129
131
  def notification_nodes(ast, &block)
@@ -17,15 +17,19 @@ module FoodCritic
17
17
 
18
18
  def options
19
19
  {:fail_tags => ['correctness'], # differs to default cmd-line behaviour
20
- :exclude_paths => ['test/**/*']}.merge(@options)
20
+ :exclude_paths => ['test/**/*', 'spec/**/*', 'features/**/*']
21
+ }.merge(@options)
21
22
  end
22
23
 
23
24
  def define
24
25
  desc "Lint Chef cookbooks"
25
26
  task(name) do
26
27
  result = FoodCritic::Linter.new.check(files, options)
27
- puts result
28
- fail if result.failed?
28
+ if result.warnings.any?
29
+ puts result
30
+ end
31
+
32
+ fail result.to_s if result.failed?
29
33
  end
30
34
  end
31
35
 
@@ -9,14 +9,6 @@
9
9
  # query only, as any nodes returned from a `recipe` block will be converted
10
10
  # into warnings.
11
11
 
12
- rule "FC001",
13
- "Use strings in preference to symbols to access node attributes" do
14
- tags %w{style attributes}
15
- recipe do |ast|
16
- attribute_access(ast, :type => :symbol)
17
- end
18
- end
19
-
20
12
  rule "FC002", "Avoid string interpolation where not required" do
21
13
  tags %w{style strings}
22
14
  recipe do |ast|
@@ -436,7 +428,8 @@ rule "FC033", "Missing template" do
436
428
  tags %w{correctness}
437
429
  recipe do |ast,filename|
438
430
  find_resources(ast, :type => :template).reject do |resource|
439
- resource_attributes(resource)['local']
431
+ resource_attributes(resource)['local'] ||
432
+ resource_attributes(resource)['cookbook']
440
433
  end.map do |resource|
441
434
  file = template_file(resource_attributes(resource,
442
435
  :return_expressions => true))
@@ -488,3 +481,101 @@ rule "FC037", "Invalid notification action" do
488
481
  end
489
482
  end
490
483
  end
484
+
485
+ rule "FC038", "Invalid resource action" do
486
+ tags %w{correctness}
487
+ recipe do |ast|
488
+ find_resources(ast).select do |resource|
489
+ actions = resource_attributes(resource)['action']
490
+ if actions.respond_to?(:xpath)
491
+ actions = actions.xpath('descendant::array/descendant::symbol/ident/@value')
492
+ else
493
+ actions = Array(actions)
494
+ end
495
+ actions.reject{|a| a.to_s.empty?}.any? do |action|
496
+ ! resource_action?(resource_type(resource), action)
497
+ end
498
+ end
499
+ end
500
+ end
501
+
502
+ rule "FC039", "Node method cannot be accessed with key" do
503
+ tags %w{correctness}
504
+ recipe do |ast|
505
+ [{:type => :string, :path => '@value'},
506
+ {:type => :symbol, :path => 'ident/@value'}].map do |access_type|
507
+ attribute_access(ast, :type => access_type[:type]).select do |att|
508
+ att_name = att.xpath(access_type[:path]).to_s.to_sym
509
+ att_name != :tags && chef_node_methods.include?(att_name)
510
+ end.select do |att|
511
+ ! att.xpath('ancestor::args_add_block[position() = 1]
512
+ [preceding-sibling::vcall | preceding-sibling::var_ref]').empty?
513
+ end.select do |att|
514
+ att_type = att.xpath('ancestor::args_add_block[position() = 1]
515
+ /../var_ref/ident/@value').to_s
516
+ ast.xpath("//assign/var_field/ident[@value='#{att_type}']").empty?
517
+ end
518
+ end.flatten
519
+ end
520
+ end
521
+
522
+ rule "FC040", "Execute resource used to run git commands" do
523
+ tags %w{style recipe etsy}
524
+ recipe do |ast|
525
+ find_resources(ast, :type => 'execute').select do |cmd|
526
+ cmd_str = (resource_attribute(cmd, 'command') || resource_name(cmd)).to_s
527
+ cmd_str.include?('git ')
528
+ end
529
+ end
530
+ end
531
+
532
+ rule "FC041", "Execute resource used to run curl or wget commands" do
533
+ tags %w{style recipe etsy}
534
+ recipe do |ast|
535
+ find_resources(ast, :type => 'execute').select do |cmd|
536
+ cmd_str = (resource_attribute(cmd, 'command') || resource_name(cmd)).to_s
537
+ (cmd_str.include?('curl ') || cmd_str.include?('wget '))
538
+ end
539
+ end
540
+ end
541
+
542
+ rule "FC042", "Prefer include_recipe to require_recipe" do
543
+ tags %w{deprecated}
544
+ recipe do |ast|
545
+ ast.xpath('//command[ident/@value="require_recipe"]')
546
+ end
547
+ end
548
+
549
+ rule "FC043", "Prefer new notification syntax" do
550
+ tags %w{style notifications deprecated}
551
+ recipe do |ast|
552
+ find_resources(ast).select do |resource|
553
+ notifications(resource).any?{|notify| notify[:style] == :old}
554
+ end
555
+ end
556
+ end
557
+
558
+ rule "FC044", "Avoid bare attribute keys" do
559
+ tags %w{style}
560
+ attributes do |ast|
561
+ declared = ast.xpath('//descendant::var_field/ident/@value').map{|v| v.to_s}
562
+ ast.xpath('//assign/*[self::vcall or self::var_ref]
563
+ [count(child::kw) = 0]/ident').select do |v|
564
+ (v['value'] != 'secure_password') && ! declared.include?(v['value'])
565
+ end
566
+ end
567
+ end
568
+
569
+ rule "FC045", "Consider setting cookbook name in metadata" do
570
+ tags %w{annoyances metadata}
571
+ metadata do |ast, filename|
572
+ unless ast.xpath('descendant::stmts_add/command/ident/@value="name"')
573
+ [file_match(filename)]
574
+ end
575
+ end
576
+ cookbook do |filename|
577
+ if ! File.exists?(File.join(filename, 'metadata.rb'))
578
+ [file_match(File.join(filename, 'metadata.rb'))]
579
+ end
580
+ end
581
+ end
@@ -1,4 +1,4 @@
1
1
  module FoodCritic
2
2
  # The current version of foodcritic
3
- VERSION = '1.6.1'
3
+ VERSION = '1.7.0'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foodcritic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-30 00:00:00.000000000 Z
12
+ date: 2012-12-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gherkin
@@ -48,17 +48,17 @@ dependencies:
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - '='
51
+ - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 1.5.0
53
+ version: 1.5.4
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - '='
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 1.5.0
61
+ version: 1.5.4
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: pry
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -164,8 +164,7 @@ files:
164
164
  - lib/foodcritic/xml.rb
165
165
  - lib/foodcritic.rb
166
166
  - chef_dsl_metadata.json
167
- - !binary |-
168
- YmluL2Zvb2Rjcml0aWM=
167
+ - bin/foodcritic
169
168
  homepage: http://acrmp.github.com/foodcritic
170
169
  licenses:
171
170
  - MIT
@@ -187,12 +186,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
186
  version: '0'
188
187
  segments:
189
188
  - 0
190
- hash: -2527542643292755100
189
+ hash: -3551223216716308083
191
190
  requirements: []
192
191
  rubyforge_project:
193
- rubygems_version: 1.8.19
192
+ rubygems_version: 1.8.24
194
193
  signing_key:
195
194
  specification_version: 3
196
- summary: foodcritic-1.6.1
195
+ summary: foodcritic-1.7.0
197
196
  test_files: []
198
197
  has_rdoc: