foodcritic 2.2.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +15 -0
  2. data/CHANGELOG.md +83 -0
  3. data/chef_dsl_metadata/chef_0.10.0.json +2 -3
  4. data/chef_dsl_metadata/chef_0.10.10.json +2 -3
  5. data/chef_dsl_metadata/chef_0.10.2.json +2 -3
  6. data/chef_dsl_metadata/chef_0.10.4.json +2 -3
  7. data/chef_dsl_metadata/chef_0.10.6.json +2 -3
  8. data/chef_dsl_metadata/chef_0.10.8.json +2 -3
  9. data/chef_dsl_metadata/chef_0.8.14.json +2 -3
  10. data/chef_dsl_metadata/chef_0.8.16.json +2 -3
  11. data/chef_dsl_metadata/chef_0.9.0.json +2 -3
  12. data/chef_dsl_metadata/chef_0.9.10.json +2 -3
  13. data/chef_dsl_metadata/chef_0.9.12.json +2 -3
  14. data/chef_dsl_metadata/chef_0.9.14.json +2 -3
  15. data/chef_dsl_metadata/chef_0.9.16.json +2 -3
  16. data/chef_dsl_metadata/chef_0.9.18.json +2 -3
  17. data/chef_dsl_metadata/chef_0.9.2.json +2 -3
  18. data/chef_dsl_metadata/chef_0.9.4.json +2 -3
  19. data/chef_dsl_metadata/chef_0.9.6.json +2 -3
  20. data/chef_dsl_metadata/chef_0.9.8.json +2 -3
  21. data/chef_dsl_metadata/chef_10.12.0.json +2 -3
  22. data/chef_dsl_metadata/chef_10.14.0.json +2 -3
  23. data/chef_dsl_metadata/chef_10.14.2.json +2 -3
  24. data/chef_dsl_metadata/chef_10.14.4.json +2 -3
  25. data/chef_dsl_metadata/chef_10.16.0.json +2 -3
  26. data/chef_dsl_metadata/chef_10.16.2.json +2 -3
  27. data/chef_dsl_metadata/chef_10.16.4.json +2 -3
  28. data/chef_dsl_metadata/chef_10.16.6.json +2 -3
  29. data/chef_dsl_metadata/chef_10.18.0.json +2 -3
  30. data/chef_dsl_metadata/chef_10.18.2.json +2 -3
  31. data/chef_dsl_metadata/chef_10.20.0.json +2 -3
  32. data/chef_dsl_metadata/chef_10.22.0.json +2 -3
  33. data/chef_dsl_metadata/chef_10.24.0.json +2 -3
  34. data/chef_dsl_metadata/chef_10.24.4.json +2 -3
  35. data/chef_dsl_metadata/chef_10.26.0.json +2 -3
  36. data/chef_dsl_metadata/chef_11.0.0.json +2 -3
  37. data/chef_dsl_metadata/chef_11.2.0.json +2 -3
  38. data/chef_dsl_metadata/chef_11.4.0.json +2 -3
  39. data/chef_dsl_metadata/chef_11.4.2.json +2 -3
  40. data/chef_dsl_metadata/chef_11.4.4.json +2 -3
  41. data/chef_dsl_metadata/chef_11.6.0.json +9734 -0
  42. data/features/007_check_for_undeclared_recipe_dependencies.feature +18 -34
  43. data/features/017_check_for_no_lwrp_notifications.feature +25 -0
  44. data/features/019_check_for_consistent_node_access.feature +1 -0
  45. data/features/033_check_for_missing_template.feature +20 -64
  46. data/features/034_check_for_unused_template_variables.feature +44 -0
  47. data/features/047_check_for_attribute_assignment_without_precedence.feature +47 -0
  48. data/features/048_check_for_shellout.feature +34 -0
  49. data/features/049_check_for_role_name_mismatch_with_file_name.feature +31 -0
  50. data/features/050_check_for_invalid_name.feature +33 -0
  51. data/features/051_check_for_template_partial_loops.feature +21 -0
  52. data/features/command_line_help.feature +15 -0
  53. data/features/ignore_via_line_comments.feature +18 -0
  54. data/features/individual_file.feature +17 -1
  55. data/features/multiple_paths.feature +26 -2
  56. data/features/step_definitions/cookbook_steps.rb +328 -9
  57. data/features/support/command_helpers.rb +71 -10
  58. data/features/support/cookbook_helpers.rb +88 -6
  59. data/lib/foodcritic/api.rb +89 -20
  60. data/lib/foodcritic/command_line.rb +64 -18
  61. data/lib/foodcritic/domain.rb +26 -7
  62. data/lib/foodcritic/dsl.rb +3 -0
  63. data/lib/foodcritic/linter.rb +93 -61
  64. data/lib/foodcritic/rake_task.rb +3 -2
  65. data/lib/foodcritic/rules.rb +105 -14
  66. data/lib/foodcritic/template.rb +34 -1
  67. data/lib/foodcritic/version.rb +1 -1
  68. data/man/foodcritic.1 +13 -1
  69. data/man/foodcritic.1.ronn +9 -0
  70. data/spec/foodcritic/api_spec.rb +210 -1
  71. data/spec/foodcritic/command_line_spec.rb +13 -0
  72. data/spec/foodcritic/domain_spec.rb +40 -5
  73. data/spec/foodcritic/linter_spec.rb +19 -22
  74. data/spec/foodcritic/template_spec.rb +8 -4
  75. data/spec/regression/expected-output.txt +139 -60
  76. metadata +31 -26
@@ -49,3 +49,21 @@ Feature: Ignoring rules on per line basis
49
49
  | # ~FC002,~FC007 | FC002 |
50
50
  | # ~FC002,~FC039 | |
51
51
  | # ~FC002 | FC039 |
52
+
53
+ Scenario Outline: Ignoring role rules
54
+ Given a ruby role that triggers FC049 with comment <comment>
55
+ When I check the role directory
56
+ Then the role name does not match file name warning 049 should <shown>
57
+ Examples:
58
+ | comment | shown |
59
+ | | be shown |
60
+ | #~FC049 | not be shown |
61
+
62
+ Scenario Outline: Ignoring environment rules
63
+ Given a ruby environment that triggers FC050 with comment <comment>
64
+ When I check the environment directory
65
+ Then the invalid environment name warning 050 should <shown>
66
+ Examples:
67
+ | comment | shown |
68
+ | | be shown |
69
+ | #~FC050 | not be shown |
@@ -4,9 +4,25 @@ Feature: Individual file
4
4
  As a developer
5
5
  I want to lint individual files in a cookbook
6
6
 
7
- Scenario: Linting an individual file shows warnings only from that file
7
+ Scenario: Linting an individual recipe shows warnings only from that file
8
8
  Given a cookbook with a single recipe that reads node attributes via symbols,strings
9
9
  And a cookbook that declares normal attributes via symbols
10
10
  When I check the recipe
11
11
  Then the attribute consistency warning 019 should be displayed for the recipe
12
12
  And the attribute consistency warning 019 should not be displayed for the attributes
13
+
14
+ Scenario: Linting an individual role
15
+ Given a roles directory
16
+ And it contains a role file webserver.rb that defines the role name "apache"
17
+ And it contains a role file database.rb that defines the role name "postgresql"
18
+ When I check the webserver role only
19
+ Then the role name does not match file name warning 049 should be shown against the webserver role
20
+ And the role name does not match file name warning 049 should not be shown against the database role
21
+
22
+ Scenario: Linting an individual environment
23
+ Given an environments directory
24
+ And it contains an environment file production_eu.rb that defines the environment name "production (eu-west-1)"
25
+ And it contains an environment file production_us.rb that defines the environment name "production (us-east-1)"
26
+ When I check the eu environment file only
27
+ Then the invalid environment name warning 050 should be shown against the eu environment
28
+ And the invalid environment name warning 050 should not be shown against the us environment
@@ -4,8 +4,32 @@ Feature: Multiple paths
4
4
  As a developer
5
5
  I want to lint multiple paths at once
6
6
 
7
- Scenario: Linting multiple individual cookbooks
7
+ Scenario Outline: Linting multiple individual cookbooks
8
8
  Given a cookbook with a single recipe that reads node attributes via symbols,strings
9
9
  And another cookbook with a single recipe that reads node attributes via strings
10
- When I check both cookbooks
10
+ When I check both cookbooks with the command-line <command_line>
11
11
  Then the attribute consistency warning 019 should be shown
12
+ Examples:
13
+ | command_line |
14
+ | example another_example |
15
+ | -B example -B another_example |
16
+ | --cookbook-path example --cookbook-path another_example |
17
+ | -B example another_example |
18
+ | --cookbook-path example another_example |
19
+ | -B example --cookbook-path another_example |
20
+
21
+ Scenario: Linting multiple role directories
22
+ Given two roles directories
23
+ And each role directory has a role with a name that does not match the containing file name
24
+ When I check both roles directories
25
+ Then the role name does not match file name warning 049 should be shown against the files in both directories
26
+
27
+ Scenario: Linting a cookbook, role and environment together
28
+ Given a cookbook with a single recipe that reads node attributes via symbols,strings
29
+ And another cookbook with a single recipe that reads node attributes via strings
30
+ And a directory that contains a role file webserver.rb in ruby that defines role name apache
31
+ And a directory that contains an environment file production.rb in ruby that defines environment name production (us-east)
32
+ When I check the cookbooks, role and environment together
33
+ Then the attribute consistency warning 019 should be shown
34
+ And the role name does not match file name warning 049 should be shown
35
+ And the invalid environment name warning 050 should be shown
@@ -34,8 +34,20 @@ Given 'a cookbook attributes file with a do block that takes arguments' do
34
34
  }
35
35
  end
36
36
 
37
- Given /^a cookbook attributes file with assignment (.*)$/ do |assignment|
38
- write_attributes assignment
37
+ Given /^a cookbook (attributes|recipe) file with assignment (.*)$/ do |type, assignment|
38
+ if type == 'attributes'
39
+ write_attributes assignment
40
+ else
41
+ write_recipe assignment
42
+ end
43
+ end
44
+
45
+ Given "a cookbook recipe that contains a group resource that uses the 'system' attribute" do
46
+ write_recipe %q{
47
+ group "senge" do
48
+ system true
49
+ end
50
+ }
39
51
  end
40
52
 
41
53
  Given /^a cookbook recipe that declares (too many )?execute resources varying only in the command in branching conditionals$/ do |too_many|
@@ -69,6 +81,18 @@ Given /^a cookbook recipe that declares a ([^ ]+) resource with the ([^ ]+) attr
69
81
  }
70
82
  end
71
83
 
84
+ Given /^a cookbook recipe that executes '([^']+)' with an execute resource$/ do |command|
85
+ write_recipe %Q{
86
+ execute "#{command}" do
87
+ action :run
88
+ end
89
+ }
90
+ end
91
+
92
+ Given /^a cookbook recipe that spawns a sub-process with (.*)$/ do |command|
93
+ write_recipe command
94
+ end
95
+
72
96
  Given 'a cookbook recipe with a deploy resource that contains a template resource' do
73
97
  write_recipe %q{
74
98
  deploy '/foo/bar' do
@@ -429,8 +453,9 @@ Given /^a cookbook recipe that includes a recipe name from an( embedded)? expres
429
453
  }
430
454
  end
431
455
 
432
- Given /^a cookbook recipe that includes a(n un| )?declared recipe dependency( unscoped)?$/ do |undeclared,unscoped|
433
- recipe_with_dependency(:is_declared => undeclared.strip.empty?, :is_scoped => unscoped.nil?)
456
+ Given /^a cookbook recipe that includes a(n un| )?declared recipe dependency(?: {0,1})(unscoped)?( with parentheses)?$/ do |undeclared,unscoped, parens|
457
+ recipe_with_dependency(:is_declared => undeclared.strip.empty?,
458
+ :is_scoped => unscoped.nil?, :parentheses => parens)
434
459
  end
435
460
 
436
461
  Given 'a cookbook recipe that includes both declared and undeclared recipe dependencies' do
@@ -465,6 +490,17 @@ Given /a cookbook recipe that (install|upgrade)s (a gem|multiple gems)(.*)$/ do
465
490
  end
466
491
  end
467
492
 
493
+ Given 'a cookbook recipe that refers to a hidden template' do
494
+ write_recipe %q{
495
+ template '/etc/.s3cfg' do
496
+ source '.s3cfg.erb'
497
+ end
498
+ }
499
+ write_file "cookbooks/example/templates/default/.s3cfg.erb", %q{
500
+ config=true
501
+ }
502
+ end
503
+
468
504
  Given /^a cookbook recipe that refers to a (missing |local )?template( in a subdirectory)?$/ do |missing_or_local, sub_dir|
469
505
  sub_dir = sub_dir ? 'sub_dir/' : ''
470
506
  write_recipe %Q{
@@ -755,6 +791,16 @@ Given /^a cookbook that passes variables (.*) to a template with extension (.*)$
755
791
  }
756
792
  end
757
793
 
794
+ Given /^a cookbook that passes variables (.*) to an inferred template$/ do |vars|
795
+ write_recipe %Q{
796
+ template "/tmp/config.conf" do
797
+ variables(
798
+ :#{vars.split(',').map{|v| "#{v} => node[:#{v}]"}.join(",\n:")}
799
+ )
800
+ end
801
+ }
802
+ end
803
+
758
804
  Given /^a cookbook that contains a (short|long) ruby block$/ do |length|
759
805
  recipe_with_ruby_block(length.to_sym)
760
806
  end
@@ -805,10 +851,46 @@ Given /^a cookbook that contains a LWRP that (?:does not trigger notifications|d
805
851
  })
806
852
  end
807
853
 
854
+ Given /^a cookbook that contains a LWRP that uses converge_by - (brace|do) block (with|without) parentheses$/ do |block_type, with_parens|
855
+ write_resource("site", %q{
856
+ actions :create
857
+ attribute :name, :kind_of => String, :name_attribute => true
858
+ })
859
+ if block_type == 'brace'
860
+ write_provider("site", %q{
861
+ action :create do
862
+ converge_by("Creating site #{new_resource.name}"){ Site.new(new_resource.name).create }
863
+ end
864
+ })
865
+ else
866
+ if with_parens == 'with'
867
+ write_provider("site", %q{
868
+ action :create do
869
+ converge_by("Creating site #{new_resource.name}") do
870
+ Site.new(new_resource.name).create
871
+ end
872
+ end
873
+ })
874
+ else
875
+ write_provider("site", %q{
876
+ action :create do
877
+ converge_by "Creating site #{new_resource.name}" do
878
+ Site.new(new_resource.name).create
879
+ end
880
+ end
881
+ })
882
+ end
883
+ end
884
+ end
885
+
808
886
  Given /^a cookbook that contains a LWRP that uses the deprecated notification syntax(.*)$/ do |qualifier|
809
887
  cookbook_with_lwrp({:notifies => qualifier.include?('class variable') ? :class_variable : :deprecated_syntax})
810
888
  end
811
889
 
890
+ Given 'a cookbook that contains a LWRP that uses use_inline_resources' do
891
+ cookbook_with_lwrp({:use_inline_resources => true})
892
+ end
893
+
812
894
  Given 'a cookbook that contains a LWRP with multiple notifications' do
813
895
  write_resource("site", %q{
814
896
  actions :create, :delete
@@ -1176,6 +1258,22 @@ Given /^a cookbook with metadata that (specifies|does not specify) the cookbook
1176
1258
  }
1177
1259
  end
1178
1260
 
1261
+ Given /^a directory that contains a role file ([^ ]+) in (json|ruby) that defines role name (.*)$/ do |file_name, format, role_name|
1262
+ role(:role_name => %Q{"#{role_name}"}, :file_name => file_name, :format => format.to_sym)
1263
+ end
1264
+
1265
+ Given 'a directory that contains a ruby role that declares the role name more than once' do
1266
+ role(:role_name => ['"webserver"', '"apache"'], :file_name => 'webserver.rb')
1267
+ end
1268
+
1269
+ Given 'a directory that contains a ruby role with an expression as its name' do
1270
+ role(:role_name => '"#{foo}#{bar}"', :file_name => 'webserver.rb')
1271
+ end
1272
+
1273
+ Given /^a directory that contains an environment file (.*) in ruby that defines environment name (.*)$/ do |file_name, env_name|
1274
+ environment(:environment_name => %Q{"#{env_name}"}, :file_name => 'production.rb')
1275
+ end
1276
+
1179
1277
  Given /^a ([a-z_]+) resource declared with the mode ([^\s]+)(?: with comment (.*)?)?$/ do |resource,mode,comment|
1180
1278
  recipe_resource_with_mode(resource, mode, comment)
1181
1279
  end
@@ -1192,6 +1290,17 @@ Given /^a file with multiple errors on one line(?: with comment (.*))?$/ do |com
1192
1290
  write_file "cookbooks/example/recipes/default.rb", %Q{node['run_state']['nginx_force_recompile'] = "\#{foo}"#{comment}}
1193
1291
  end
1194
1292
 
1293
+ Given(/^a LWRP with an action :create that notifies with (converge_by|updated_by_last_action) and another :delete that does not notify$/) do |notify_type|
1294
+ cookbook_with_lwrp_actions([
1295
+ {:name => :create, :notify_type => notify_type.to_sym},
1296
+ {:name => :delete, :notify_type => :none}
1297
+ ])
1298
+ end
1299
+
1300
+ Given /^(?:a roles|an environments) directory$/ do
1301
+
1302
+ end
1303
+
1195
1304
  Given /^a Rakefile that defines (no lint task|a lint task with no block|a lint task with an empty block|a lint task with a block setting options to)(.*)?$/ do |task,options|
1196
1305
  rakefile(
1197
1306
  case task
@@ -1326,6 +1435,28 @@ Given /^a rule that (declares|does not declare) a version constraint(?: of ([^ ]
1326
1435
  end
1327
1436
  end
1328
1437
 
1438
+ Given /^a template that includes a partial( that includes the original template again)?$/ do |loops|
1439
+ write_recipe %q{
1440
+ template "/tmp/a" do
1441
+ source "a.erb"
1442
+ variables({
1443
+ :config_var => "foo"
1444
+ })
1445
+ end
1446
+ }
1447
+ write_file 'cookbooks/example/templates/default/a.erb', '<%= render "b.erb" %>'
1448
+ content = if loops
1449
+ '<%= render "a.erb" %>'
1450
+ else
1451
+ '<%= @config_var %>'
1452
+ end
1453
+ write_file 'cookbooks/example/templates/default/b.erb', content
1454
+ end
1455
+
1456
+ Given 'access to the man page documentation' do
1457
+
1458
+ end
1459
+
1329
1460
  Given /^another cookbook that has (an older )?chef-solo-search installed$/ do |older|
1330
1461
  if older.nil?
1331
1462
  write_library 'search', %q{
@@ -1374,6 +1505,16 @@ Given 'the gems have been vendored' do
1374
1505
  vendor_gems
1375
1506
  end
1376
1507
 
1508
+ Given 'the last role name declared does not match the containing filename' do
1509
+
1510
+ end
1511
+
1512
+ Given /^the inferred template contains the expression (.*)$/ do |expr|
1513
+ write_file "cookbooks/example/templates/default/config.conf.erb", %Q{
1514
+ <%= #{expr} %>
1515
+ }
1516
+ end
1517
+
1377
1518
  Given /^the template (.+)?contains the expression (.*)$/ do |ext,expr|
1378
1519
  file = if ext
1379
1520
  "templates/default/config#{ext.strip}"
@@ -1385,6 +1526,40 @@ Given /^the template (.+)?contains the expression (.*)$/ do |ext,expr|
1385
1526
  }
1386
1527
  end
1387
1528
 
1529
+ Given /^the template (.+)?contains partial includes of type (.*) with the expression (.*)$/ do |ext,type,expr|
1530
+ file = if ext
1531
+ "config#{ext.strip}"
1532
+ else
1533
+ 'config.conf.erb'
1534
+ end
1535
+ if type == 'nested' and expr.split(',').length > 1
1536
+ expressions = expr.split(',')
1537
+ includes = (1..expressions.length).map{|i| "included_template_#{i}.erb"}
1538
+ (Array(file) + includes).zip(includes).map do |parent, child|
1539
+ content = if child
1540
+ "<%= render '#{child}' %>"
1541
+ else
1542
+ expressions.map{|e| "<%= #{e} %>"}.join("\n")
1543
+ end
1544
+ [parent, content]
1545
+ end.each do |template_name, content|
1546
+ write_file "cookbooks/example/templates/default/#{template_name}", content
1547
+ end
1548
+ else
1549
+ if type == 'no parentheses'
1550
+ include_string = "<%= render 'included_template.erb' %>"
1551
+ else
1552
+ include_string = "<%= render('included_template.erb') %>"
1553
+ end
1554
+ write_file "cookbooks/example/templates/default/#{file}", %Q{
1555
+ #{include_string}
1556
+ }
1557
+ write_file "cookbooks/example/templates/default/included_template.erb", %Q{
1558
+ <%= #{expr} %>
1559
+ }
1560
+ end
1561
+ end
1562
+
1388
1563
  Given 'unit tests under a top-level test directory' do
1389
1564
  minitest_spec_attributes
1390
1565
  end
@@ -1427,6 +1602,41 @@ Given /^a recipe that uses include_recipe$/ do
1427
1602
  }
1428
1603
  end
1429
1604
 
1605
+ Given /^a ruby environment file that defines an environment with name (.*)$/ do |env_name|
1606
+ environment(:environment_name => %Q{"#{env_name}"}, :file_name => 'production.rb')
1607
+ end
1608
+
1609
+ Given /^a ruby environment that triggers FC050 with comment (.*)$/ do |comment|
1610
+ write_file 'environments/production.rb', %Q{
1611
+ name "Production (eu-west-1)" #{comment}
1612
+ run_list "recipe[apache2]"
1613
+ }.strip
1614
+ end
1615
+
1616
+ Given /^a ruby role file that defines a role with name (.*)$/ do |role_name|
1617
+ role(:role_name => [%Q{"#{role_name}"}], :file_name => 'webserver.rb')
1618
+ end
1619
+
1620
+ Given /^a ruby role that triggers FC049 with comment (.*)$/ do |comment|
1621
+ write_file 'roles/webserver.rb', %Q{
1622
+ name "apache" #{comment}
1623
+ run_list "recipe[apache2]"
1624
+ }.strip
1625
+ end
1626
+
1627
+ Given 'each role directory has a role with a name that does not match the containing file name' do
1628
+ role(:dir => 'roles1', :role_name => '"apache"', :file_name => 'webserver.rb')
1629
+ role(:dir => 'roles2', :role_name => '"postgresql"', :file_name => 'database.rb')
1630
+ end
1631
+
1632
+ Given /^it contains an environment file (.*\.rb) that defines the environment name (.*)$/ do |file_name, env_name|
1633
+ environment(:environment_name => env_name, :file_name => file_name)
1634
+ end
1635
+
1636
+ Given /^it contains a role file ([a-z]+\.rb) that defines the role name (.*)$/ do |file_name, role_name|
1637
+ role(:role_name => role_name, :file_name => file_name)
1638
+ end
1639
+
1430
1640
  Given /^the cookbook metadata declares support for (.*)$/ do |supported_platforms|
1431
1641
  write_metadata(supported_platforms.split(',').map do |platform|
1432
1642
  "supports '#{platform}'"
@@ -1452,6 +1662,10 @@ Given 'two of the recipes read node attributes via symbols' do
1452
1662
  end
1453
1663
  end
1454
1664
 
1665
+ Given 'two roles directories' do
1666
+
1667
+ end
1668
+
1455
1669
  When /^I check the cookbook specifying ([^ ]+) as the Chef version$/ do |version|
1456
1670
  options = ['-c', version, 'cookbooks/example']
1457
1671
  in_current_dir do
@@ -1471,18 +1685,70 @@ Given /^the cookbook directory has a \.foodcritic file specifying tags (.*)$/ do
1471
1685
  run_lint(["cookbooks/example"])
1472
1686
  end
1473
1687
 
1474
- When 'I check both cookbooks' do
1688
+ When 'I check both cookbooks specified as arguments' do
1475
1689
  run_lint(["cookbooks/another_example", "cookbooks/example"])
1476
1690
  end
1477
1691
 
1692
+ When /^I check both cookbooks with the command-line (.*)$/ do |command_line|
1693
+ cmds = command_line.split(' ').map do |c|
1694
+ if c.end_with?('example')
1695
+ "cookbooks/#{c}"
1696
+ else
1697
+ c
1698
+ end
1699
+ end
1700
+ run_lint(cmds)
1701
+ end
1702
+
1703
+ When 'I check the cookbooks, role and environment together' do
1704
+ run_lint([
1705
+ '-B', 'cookbooks/another_example', '-B', 'cookbooks/example',
1706
+ '-E', 'environments',
1707
+ '-R', 'roles'
1708
+ ])
1709
+ end
1710
+
1478
1711
  When 'I check the cookbook without specifying a Chef version' do
1479
1712
  run_lint(['-I', 'rules/test.rb', 'cookbooks/example'])
1480
1713
  end
1481
1714
 
1715
+ When 'I check the environment directory' do
1716
+ run_lint ['-E', 'environments']
1717
+ end
1718
+
1719
+ When 'I check both roles directories' do
1720
+ run_lint ['-R', 'roles1', '-R', 'roles2']
1721
+ end
1722
+
1723
+ When 'I check the eu environment file only' do
1724
+ run_lint ['-E', 'environments/production_eu.rb']
1725
+ end
1726
+
1482
1727
  When 'I check the recipe' do
1483
1728
  run_lint(["cookbooks/example/recipes/default.rb"])
1484
1729
  end
1485
1730
 
1731
+ When 'I compare the man page options against the usage options' do
1732
+
1733
+ end
1734
+
1735
+ When 'I check the role directory' do
1736
+ run_lint ['-R', 'roles']
1737
+ end
1738
+
1739
+ When /^I check the role directory as a (default|cookbook|role) path$/ do |path_type|
1740
+ options = case path_type
1741
+ when 'default' then ['roles']
1742
+ when 'cookbook' then ['-B', 'roles']
1743
+ when 'role' then ['-R', 'roles']
1744
+ end
1745
+ run_lint(options)
1746
+ end
1747
+
1748
+ When 'I check the webserver role only' do
1749
+ run_lint ['-R', 'roles/webserver.rb']
1750
+ end
1751
+
1486
1752
  When 'I list the available build tasks' do
1487
1753
  list_available_build_tasks
1488
1754
  end
@@ -1518,6 +1784,14 @@ When 'I run it on the command line specifying a cookbook that does not exist' do
1518
1784
  run_lint(['no-such-cookbook'])
1519
1785
  end
1520
1786
 
1787
+ When /^I run it on the command line specifying a( role|n environment) directory that does not exist$/ do |type|
1788
+ if type.include?('role')
1789
+ run_lint(['-R', 'no-such-role-dir'])
1790
+ else
1791
+ run_lint(['-E', 'no-such-environment-dir'])
1792
+ end
1793
+ end
1794
+
1521
1795
  When 'I run it on the command line with no arguments' do
1522
1796
  run_lint([])
1523
1797
  end
@@ -1541,6 +1815,10 @@ Then 'a warning for the custom rule should be displayed' do
1541
1815
  expect_output('BAR001: Use symbols in preference to strings to access node attributes: cookbooks/example/recipes/default.rb:1')
1542
1816
  end
1543
1817
 
1818
+ Then 'all options should be documented in the man page' do
1819
+ man_page_options.should == usage_options_for_diff
1820
+ end
1821
+
1544
1822
  Then /^an? '([^']+)' error should be displayed$/ do |expected_error|
1545
1823
  last_error.should include expected_error
1546
1824
  end
@@ -1559,6 +1837,40 @@ Then /^the bare attribute keys warning 044 should not be displayed against the (
1559
1837
  expect_warning 'FC044', {:expect_warning => false, :line => 2, :file_type => :attributes}
1560
1838
  end
1561
1839
 
1840
+ Then /^the LWRP does not notify when updated warning 017 should( not)? be shown against the :([^ ]+) action$/ do |not_shown, action|
1841
+ line = action == 'create' ? 1 : 8
1842
+ expect_warning('FC017', :file_type => :provider, :expect_warning => ! not_shown, :line => line)
1843
+ end
1844
+
1845
+ Then /^the invalid (role|environment) name warning 050 should( not)? be shown$/ do |type, not_shown|
1846
+ file = type == 'role' ? 'roles/webserver.rb' : 'environments/production.rb'
1847
+ expect_warning 'FC050', {:expect_warning => ! not_shown, :file => file}
1848
+ end
1849
+
1850
+ Then /^the invalid environment name warning 050 should( not)? be shown against the (eu|us) environment$/ do |not_shown, env|
1851
+ expect_warning 'FC050', {:expect_warning => ! not_shown,
1852
+ :file => "environments/production_#{env}.rb", :line => 1}
1853
+ end
1854
+
1855
+ Then 'the prefer mixlib shellout warning 048 should not be displayed against the group resource' do
1856
+ expect_warning 'FC048', {:expect_warning => false, :line => 2}
1857
+ end
1858
+
1859
+ Then /^the role name does not match file name warning 049 should( not)? be shown( against the second name)?$/ do |not_shown, second|
1860
+ expect_warning 'FC049', {:expect_warning => ! not_shown,
1861
+ :file => 'roles/webserver.rb', :line => second ? 2 : 1}
1862
+ end
1863
+
1864
+ Then 'the role name does not match file name warning 049 should be shown against the files in both directories' do
1865
+ expect_warning 'FC049', {:file => "roles1/webserver.rb", :line => 1}
1866
+ expect_warning 'FC049', {:file => "roles2/database.rb", :line => 1}
1867
+ end
1868
+
1869
+ Then /^the role name does not match file name warning 049 should( not)? be shown against the (webserver|database) role$/ do |not_shown, role|
1870
+ expect_warning 'FC049', {:expect_warning => ! not_shown,
1871
+ :file => "roles/#{role}.rb", :line => 1}
1872
+ end
1873
+
1562
1874
  Then 'the long ruby block warning 014 should be displayed against the long block only' do
1563
1875
  expect_warning 'FC014', {:expect_warning => false, :line => 1}
1564
1876
  expect_warning 'FC014', {:expect_warning => true, :line => 11}
@@ -1730,17 +2042,24 @@ Then /^the simple usage text should be displayed along with a (non-)?zero exit c
1730
2042
  usage_displayed(non_zero.nil?)
1731
2043
  end
1732
2044
 
2045
+ Then /^the template partials loop indefinitely warning 051 should (not )?be displayed against the templates$/ do |not_shown|
2046
+ expect_warning('FC051', :file => 'templates/default/a.erb', :line => 1,
2047
+ :expect_warning => ! not_shown)
2048
+ expect_warning('FC051', :file => 'templates/default/b.erb', :line => 1,
2049
+ :expect_warning => ! not_shown)
2050
+ end
2051
+
1733
2052
  Then 'the undeclared dependency warning 007 should be displayed only for the undeclared dependencies' do
1734
2053
  expect_warning("FC007", :file => 'recipes/default.rb', :line => 1, :expect_warning => false)
1735
2054
  expect_warning("FC007", :file => 'recipes/default.rb', :line => 2, :expect_warning => false)
1736
2055
  expect_warning("FC007", :file => 'recipes/default.rb', :line => 6, :expect_warning => true)
1737
2056
  end
1738
2057
 
1739
- Then /^the unused template variables warning 034 should (not )?be displayed against the template(.*)?$/ do |not_shown, ext|
1740
- file = if ext
1741
- "templates/default/config#{ext.strip}"
1742
- else
2058
+ Then /^the unused template variables warning 034 should (not )?be displayed against the (?:inferred )?template(.*)?$/ do |not_shown, ext|
2059
+ file = if ext.empty?
1743
2060
  'templates/default/config.conf.erb'
2061
+ else
2062
+ "templates/default/config#{ext.strip}"
1744
2063
  end
1745
2064
  expect_warning('FC034', :file => file, :line => 1,
1746
2065
  :expect_warning => ! not_shown)