foodcritic 3.0.3 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/CHANGELOG.md +65 -0
- data/README.md +1 -1
- data/chef_dsl_metadata/chef_11.10.0.json +10272 -0
- data/chef_dsl_metadata/chef_11.10.2.json +10272 -0
- data/chef_dsl_metadata/chef_11.10.4.json +10272 -0
- data/chef_dsl_metadata/chef_11.6.2.json +9566 -0
- data/chef_dsl_metadata/chef_11.8.0.json +10074 -0
- data/chef_dsl_metadata/chef_11.8.2.json +10074 -0
- data/features/001_check_node_access.feature +60 -0
- data/features/003_check_for_chef_server.feature +5 -0
- data/features/006_check_file_mode.feature +1 -0
- data/features/022_check_for_dodgy_conditions_within_loop.feature +10 -0
- data/features/040_check_raw_git_usage.feature +6 -0
- data/features/047_check_for_attribute_assignment_without_precedence.feature +2 -0
- data/features/build_framework_support.feature +10 -0
- data/features/exclude_paths_to_lint.feature +19 -0
- data/features/show_lines_matched.feature +4 -4
- data/features/sort_warnings.feature +1 -1
- data/features/step_definitions/cookbook_steps.rb +117 -24
- data/features/support/command_helpers.rb +45 -12
- data/features/support/env.rb +5 -0
- data/lib/foodcritic/api.rb +122 -99
- data/lib/foodcritic/ast.rb +6 -7
- data/lib/foodcritic/chef.rb +24 -23
- data/lib/foodcritic/command_line.rb +49 -41
- data/lib/foodcritic/domain.rb +12 -10
- data/lib/foodcritic/dsl.rb +4 -7
- data/lib/foodcritic/error_checker.rb +0 -3
- data/lib/foodcritic/linter.rb +45 -43
- data/lib/foodcritic/notifications.rb +32 -32
- data/lib/foodcritic/output.rb +3 -6
- data/lib/foodcritic/rake_task.rb +9 -10
- data/lib/foodcritic/rules.rb +278 -240
- data/lib/foodcritic/template.rb +6 -13
- data/lib/foodcritic/version.rb +1 -1
- data/lib/foodcritic/xml.rb +1 -3
- data/man/foodcritic.1 +6 -2
- data/man/foodcritic.1.ronn +4 -1
- data/spec/foodcritic/linter_spec.rb +2 -2
- data/spec/regression/expected-output.txt +296 -1
- metadata +160 -138
@@ -0,0 +1,60 @@
|
|
1
|
+
Feature: Check Node Access
|
2
|
+
|
3
|
+
In order to be consistent in the way I access node attributes and to avoid confusing people new to Ruby
|
4
|
+
As a developer
|
5
|
+
I want to identify if the cookbooks access node attributes with symbols rather than strings
|
6
|
+
|
7
|
+
Scenario: Cookbook recipe accesses attributes via symbols
|
8
|
+
Given a cookbook with a single recipe that reads node attributes via symbols
|
9
|
+
When I check the cookbook
|
10
|
+
Then the node access warning 001 should be displayed
|
11
|
+
|
12
|
+
Scenario: Cookbook recipe accesses multiple attributes via symbols
|
13
|
+
Given a cookbook with a single recipe that accesses multiple node attributes via symbols
|
14
|
+
When I check the cookbook
|
15
|
+
Then the node access warning 001 should be displayed for each match
|
16
|
+
|
17
|
+
Scenario: Assignment of node attributes accessed via symbols
|
18
|
+
Given a cookbook with a single recipe that assigns node attributes accessed via symbols to a local variable
|
19
|
+
When I check the cookbook
|
20
|
+
Then the node access warning 001 should be displayed
|
21
|
+
|
22
|
+
Scenario: Cookbook recipe accesses nested attributes via symbols
|
23
|
+
Given a cookbook with a single recipe that accesses nested node attributes via symbols
|
24
|
+
When I check the cookbook
|
25
|
+
Then the node access warning 001 should be displayed twice for the same line
|
26
|
+
|
27
|
+
Scenario: Cookbook recipe accesses attributes via strings
|
28
|
+
Given a cookbook with a single recipe that reads node attributes via strings
|
29
|
+
When I check the cookbook
|
30
|
+
Then the node access warning 001 should not be displayed
|
31
|
+
|
32
|
+
Scenario: Cookbook recipe access attributes via strings and searches
|
33
|
+
Given a cookbook with a single recipe that searches based on a node attribute accessed via strings
|
34
|
+
When I check the cookbook
|
35
|
+
Then the node access warning 001 should not be displayed
|
36
|
+
|
37
|
+
Scenario: Cookbook recipe access attributes via symbols for template
|
38
|
+
Given a cookbook with a single recipe that passes node attributes accessed via symbols to a template
|
39
|
+
When I check the cookbook
|
40
|
+
Then the node access warning 001 should be displayed against the variables
|
41
|
+
|
42
|
+
Scenario: Cookbook recipe sets default attributes via symbols
|
43
|
+
Given a cookbook that declares default attributes via symbols
|
44
|
+
When I check the cookbook
|
45
|
+
Then the node access warning 001 should be displayed against the attributes file
|
46
|
+
|
47
|
+
Scenario: Cookbook recipe overrides attributes via symbols
|
48
|
+
Given a cookbook that declares override attributes via symbols
|
49
|
+
When I check the cookbook
|
50
|
+
Then the node access warning 001 should be displayed against the attributes file
|
51
|
+
|
52
|
+
Scenario: Cookbook recipe sets attributes via symbols
|
53
|
+
Given a cookbook that declares set attributes via symbols
|
54
|
+
When I check the cookbook
|
55
|
+
Then the node access warning 001 should be displayed against the attributes file
|
56
|
+
|
57
|
+
Scenario: Cookbook recipe sets normal attributes via symbols
|
58
|
+
Given a cookbook that declares normal attributes via symbols
|
59
|
+
When I check the cookbook
|
60
|
+
Then the node access warning 001 should be displayed against the attributes file
|
@@ -46,6 +46,11 @@ Feature: Check for Chef Server
|
|
46
46
|
When I check the cookbook
|
47
47
|
Then the check for server warning 003 should not be displayed against the condition
|
48
48
|
|
49
|
+
Scenario: Search checking for server (ternary)
|
50
|
+
Given a cookbook with a single recipe that searches but checks first (ternary) to see if this is server
|
51
|
+
When I check the cookbook
|
52
|
+
Then the check for server warning 003 should not be displayed against the condition
|
53
|
+
|
49
54
|
Scenario Outline: Search checking for server (return)
|
50
55
|
Given a cookbook with a single recipe that searches but returns first (<format>) if search is not supported
|
51
56
|
When I check the cookbook
|
@@ -31,3 +31,13 @@ Feature: Check for dodgy resource conditions within a loop
|
|
31
31
|
Given a resource declared with a guard within a loop with multiple block arguments
|
32
32
|
When I check the cookbook
|
33
33
|
Then the dodgy resource condition warning 022 should not be shown
|
34
|
+
|
35
|
+
Scenario: Resource guard contains a block
|
36
|
+
Given a resource that declares a guard containing a block
|
37
|
+
When I check the cookbook
|
38
|
+
Then the dodgy resource condition warning 022 should not be shown
|
39
|
+
|
40
|
+
Scenario: Loop in a definition
|
41
|
+
Given a resource declared within a definition
|
42
|
+
When I check the cookbook
|
43
|
+
Then the dodgy resource condition warning 022 should not be shown
|
@@ -31,7 +31,13 @@ Feature: Check for direct usage of git
|
|
31
31
|
| git fetch origin | should |
|
32
32
|
| git checkout master | should |
|
33
33
|
| git reset --hard | should |
|
34
|
+
| git status && git pull | should |
|
34
35
|
| git show | should not |
|
35
36
|
| echo 'bob' && git show | should not |
|
36
37
|
| gitk | should not |
|
37
38
|
| curl http://github.com/ | should not |
|
39
|
+
|
40
|
+
Scenario: Multiple execute resources
|
41
|
+
Given a cookbook recipe with multiple execute resources where the last uses git
|
42
|
+
When I check the cookbook
|
43
|
+
Then the execute resource used to run git commands warning 040 should be displayed against the last resource
|
@@ -21,8 +21,10 @@ Feature: Check for attribute assignment without specified precedence
|
|
21
21
|
| node.normal['foo'] = 'bar' | should not |
|
22
22
|
| node.default['foo'] = 'bar' | should not |
|
23
23
|
| node.force_default['foo'] = 'bar' | should not |
|
24
|
+
| node.default!['foo'] = 'bar' | should not |
|
24
25
|
| node.set['foo'] = 'bar' | should not |
|
25
26
|
| node.override['foo'] = 'bar' | should not |
|
27
|
+
| node.override!['foo'] = 'bar' | should not |
|
26
28
|
| node.force_override['foo'] = 'bar' | should not |
|
27
29
|
| node.automatic_attrs['foo'] = 'bar' | should not |
|
28
30
|
| node['foos'] << 'bar' | should |
|
@@ -67,6 +67,16 @@ I want to be able to invoke the lint tool from my build
|
|
67
67
|
| style | {:fail_tags => ['correctness,style']} | fail | FC002 |
|
68
68
|
| style,correctness | {:fail_tags => [], :tags => ['correctness']} | succeed | FC006 |
|
69
69
|
|
70
|
+
@context
|
71
|
+
Scenario: Specify that contexts should be shown
|
72
|
+
Given a cookbook with a single recipe that reads node attributes via symbols,strings
|
73
|
+
And the cookbook has a Gemfile that includes rake and foodcritic
|
74
|
+
And a Rakefile that defines a lint task with a block setting options to {:context => true}
|
75
|
+
When I run the build
|
76
|
+
Then the recipe filename should be displayed
|
77
|
+
And the attribute consistency warning 019 should be displayed below
|
78
|
+
And the line number and line of code that triggered the warning should be displayed
|
79
|
+
|
70
80
|
Scenario Outline: Specify paths to lint
|
71
81
|
Given a cookbook that has <problems> problems
|
72
82
|
And the cookbook has a Gemfile that includes rake and foodcritic
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: Exclude paths from being linted
|
2
|
+
|
3
|
+
In order to avoid linting some paths that are not really from the cookbook
|
4
|
+
As a developer
|
5
|
+
I want to be able to exclude some files or directories from the passed paths
|
6
|
+
|
7
|
+
Scenario: Don't exclude a non cookbook directory
|
8
|
+
Given a cookbook that has style problems
|
9
|
+
And unit tests under a top-level test directory
|
10
|
+
When I check the cookbook without excluding the test directory
|
11
|
+
Then warnings will be displayed against the tests
|
12
|
+
And the style warning 002 should be displayed
|
13
|
+
|
14
|
+
Scenario: Exclude a non cookbook directory
|
15
|
+
Given a cookbook that has style problems
|
16
|
+
And unit tests under a top-level test directory
|
17
|
+
When I check the cookbook excluding the test directory
|
18
|
+
Then no warnings will be displayed against the tests
|
19
|
+
And the style warning 002 should be displayed
|
@@ -6,15 +6,15 @@ Feature: Show Lines Matched
|
|
6
6
|
I want to be able to see the lines the warning matches against, with context
|
7
7
|
|
8
8
|
Scenario: Recipe with a single warning
|
9
|
-
Given a cookbook with a single recipe that reads node attributes via symbols
|
9
|
+
Given a cookbook with a single recipe that reads node attributes via symbols
|
10
10
|
When I check the cookbook, specifying that context should be shown
|
11
11
|
Then the recipe filename should be displayed
|
12
|
-
And the
|
12
|
+
And the node access warning 001 should be displayed below
|
13
13
|
And the line number and line of code that triggered the warning should be displayed
|
14
14
|
|
15
15
|
Scenario: Recipe with a multiple warnings of the same type
|
16
|
-
Given a cookbook with a single recipe that
|
16
|
+
Given a cookbook with a single recipe that accesses multiple node attributes via symbols
|
17
17
|
When I check the cookbook, specifying that context should be shown
|
18
18
|
Then the recipe filename should be displayed
|
19
|
-
And the
|
19
|
+
And the node access warning 001 should be displayed below
|
20
20
|
And the line number and line of code that triggered the warnings should be displayed
|
@@ -7,4 +7,4 @@ Feature: Sort warnings
|
|
7
7
|
Scenario: Recipe has warnings on lines that don't sort non-numerically
|
8
8
|
Given a cookbook with a single recipe which accesses node attributes with symbols on lines 2 and 10
|
9
9
|
When I check the cookbook
|
10
|
-
Then the
|
10
|
+
Then the node access warning 001 should warn on lines 2 and 10 in that order
|
@@ -758,6 +758,20 @@ Given 'a cookbook recipe with a service resource with an action specified via a
|
|
758
758
|
}.strip
|
759
759
|
end
|
760
760
|
|
761
|
+
Given 'a cookbook recipe with multiple execute resources where the last uses git' do
|
762
|
+
write_recipe %q{
|
763
|
+
execute "one" do
|
764
|
+
command "ls -al"
|
765
|
+
end
|
766
|
+
execute "two" do
|
767
|
+
command "df -H"
|
768
|
+
end
|
769
|
+
execute "three" do
|
770
|
+
command "git clone https://example.org/bar.git"
|
771
|
+
end
|
772
|
+
}.strip
|
773
|
+
end
|
774
|
+
|
761
775
|
Given 'a cookbook template that uses all variables passed' do
|
762
776
|
write_recipe %q{
|
763
777
|
template "/tmp/config.conf" do
|
@@ -1045,13 +1059,10 @@ Given 'a cookbook with a single recipe that mixes node access types in an interp
|
|
1045
1059
|
}
|
1046
1060
|
end
|
1047
1061
|
|
1048
|
-
Given 'a cookbook with a single recipe that
|
1062
|
+
Given 'a cookbook with a single recipe that accesses multiple node attributes via symbols' do
|
1049
1063
|
write_recipe %q{
|
1050
1064
|
node[:foo] = 'bar'
|
1051
|
-
node[:
|
1052
|
-
node[:wham] = 'shazam'
|
1053
|
-
node['testing'] = 'bar'
|
1054
|
-
node['testing2'] = 'bar2'
|
1065
|
+
node[:testing] = 'bar'
|
1055
1066
|
}
|
1056
1067
|
end
|
1057
1068
|
|
@@ -1159,12 +1170,12 @@ Given 'a cookbook with a single recipe which accesses node attributes with symbo
|
|
1159
1170
|
# Here we access the node attributes via a symbol
|
1160
1171
|
foo = node[:foo]
|
1161
1172
|
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1173
|
+
directory "/tmp/foo" do
|
1174
|
+
owner "root"
|
1175
|
+
group "root"
|
1176
|
+
action :create
|
1177
|
+
end
|
1166
1178
|
|
1167
|
-
# Second access via a symbol
|
1168
1179
|
bar = node[:bar]
|
1169
1180
|
}
|
1170
1181
|
end
|
@@ -1203,6 +1214,12 @@ Given /^a cookbook with a single recipe that searches but checks first( \(string
|
|
1203
1214
|
}
|
1204
1215
|
end
|
1205
1216
|
|
1217
|
+
Given 'a cookbook with a single recipe that searches but checks first (ternary) to see if this is server' do
|
1218
|
+
write_recipe %Q{
|
1219
|
+
required_node = Chef::Config[:solo] ? node : search(:node, query).first
|
1220
|
+
}
|
1221
|
+
end
|
1222
|
+
|
1206
1223
|
Given /^a cookbook with a single recipe that searches but checks with a negative first to see if this is server$/ do
|
1207
1224
|
write_recipe %q{
|
1208
1225
|
unless Chef::Config['solo']
|
@@ -1437,6 +1454,40 @@ Given 'a resource declared with a guard within a loop with multiple block argume
|
|
1437
1454
|
}
|
1438
1455
|
end
|
1439
1456
|
|
1457
|
+
Given 'a resource that declares a guard containing a block' do
|
1458
|
+
write_recipe %q{
|
1459
|
+
template '/etc/foo' do
|
1460
|
+
not_if do
|
1461
|
+
s = false
|
1462
|
+
node['mylist'].each do |realm|
|
1463
|
+
s = node['mylist'][realm].empty?
|
1464
|
+
break if s
|
1465
|
+
end
|
1466
|
+
s
|
1467
|
+
end
|
1468
|
+
owner 'root'
|
1469
|
+
group 'root'
|
1470
|
+
mode '0644'
|
1471
|
+
source 'foo.erb'
|
1472
|
+
end
|
1473
|
+
}
|
1474
|
+
end
|
1475
|
+
|
1476
|
+
|
1477
|
+
Given 'a resource declared within a definition' do
|
1478
|
+
write_recipe %q{
|
1479
|
+
define :toto, {
|
1480
|
+
} do
|
1481
|
+
[:a, :b].each do |x|
|
1482
|
+
package x do
|
1483
|
+
not_if { node['foo'] == x }
|
1484
|
+
action :install
|
1485
|
+
end
|
1486
|
+
end
|
1487
|
+
end
|
1488
|
+
}
|
1489
|
+
end
|
1490
|
+
|
1440
1491
|
Given /^a rule that (declares|does not declare) a version constraint(?: of ([^ ]+)? to ([^ ]+)?)?$/ do |constraint, from, to|
|
1441
1492
|
if from || to
|
1442
1493
|
rule_with_version_constraint(from, to)
|
@@ -1736,6 +1787,10 @@ When /^I check both cookbooks with the command-line (.*)$/ do |command_line|
|
|
1736
1787
|
run_lint(cmds)
|
1737
1788
|
end
|
1738
1789
|
|
1790
|
+
When 'I check both roles directories' do
|
1791
|
+
run_lint ['-R', 'roles1', '-R', 'roles2']
|
1792
|
+
end
|
1793
|
+
|
1739
1794
|
When 'I check the cookbooks, role and environment together' do
|
1740
1795
|
run_lint([
|
1741
1796
|
'-B', 'cookbooks/another_example', '-B', 'cookbooks/example',
|
@@ -1752,14 +1807,15 @@ When 'I check the environment directory' do
|
|
1752
1807
|
run_lint ['-E', 'environments']
|
1753
1808
|
end
|
1754
1809
|
|
1755
|
-
When 'I check both roles directories' do
|
1756
|
-
run_lint ['-R', 'roles1', '-R', 'roles2']
|
1757
|
-
end
|
1758
|
-
|
1759
1810
|
When 'I check the eu environment file only' do
|
1760
1811
|
run_lint ['-E', 'environments/production_eu.rb']
|
1761
1812
|
end
|
1762
1813
|
|
1814
|
+
When /^I check the cookbook( without)? excluding the ([^ ]+) directory$/ do |no_exclude, dir|
|
1815
|
+
options = no_exclude.nil? ? ['-X', dir] : []
|
1816
|
+
run_lint(options + ['cookbooks/example'])
|
1817
|
+
end
|
1818
|
+
|
1763
1819
|
When 'I check the recipe' do
|
1764
1820
|
run_lint(["cookbooks/example/recipes/default.rb"])
|
1765
1821
|
end
|
@@ -1852,11 +1908,11 @@ Then 'a warning for the custom rule should be displayed' do
|
|
1852
1908
|
end
|
1853
1909
|
|
1854
1910
|
Then 'all options should be documented in the man page' do
|
1855
|
-
man_page_options.
|
1911
|
+
man_page_options.must_equal usage_options_for_diff
|
1856
1912
|
end
|
1857
1913
|
|
1858
1914
|
Then /^an? '([^']+)' error should be displayed$/ do |expected_error|
|
1859
|
-
last_error.
|
1915
|
+
last_error.must_include expected_error
|
1860
1916
|
end
|
1861
1917
|
|
1862
1918
|
Then 'the attribute consistency warning 019 should be shown for both of the recipes that use symbols' do
|
@@ -1873,6 +1929,10 @@ Then /^the bare attribute keys warning 044 should not be displayed against the (
|
|
1873
1929
|
expect_warning 'FC044', {:expect_warning => false, :line => 2, :file_type => :attributes}
|
1874
1930
|
end
|
1875
1931
|
|
1932
|
+
Then 'the execute resource used to run git commands warning 040 should be displayed against the last resource' do
|
1933
|
+
expect_warning 'FC040', {:line => 7}
|
1934
|
+
end
|
1935
|
+
|
1876
1936
|
Then /^the LWRP does not notify when updated warning 017 should( not)? be shown against the :([^ ]+) action$/ do |not_shown, action|
|
1877
1937
|
line = action == 'create' ? 1 : 8
|
1878
1938
|
expect_warning('FC017', :file_type => :provider, :expect_warning => ! not_shown, :line => line)
|
@@ -1914,15 +1974,19 @@ end
|
|
1914
1974
|
|
1915
1975
|
Then /^the lint task will be listed( under the different name)?$/ do |diff_name|
|
1916
1976
|
expected_name = diff_name ? 'lint' : 'foodcritic'
|
1917
|
-
build_tasks.
|
1977
|
+
build_tasks.must_include([expected_name, 'Lint Chef cookbooks'])
|
1918
1978
|
end
|
1919
1979
|
|
1920
1980
|
Then 'no error should have occurred' do
|
1921
1981
|
assert_no_error_occurred
|
1922
1982
|
end
|
1923
1983
|
|
1924
|
-
Then /^no warnings will be displayed against the tests$/ do
|
1925
|
-
|
1984
|
+
Then /^(no )?warnings will be displayed against the tests$/ do |no_display|
|
1985
|
+
if no_display.nil?
|
1986
|
+
assert_test_warnings
|
1987
|
+
else
|
1988
|
+
assert_no_test_warnings
|
1989
|
+
end
|
1926
1990
|
end
|
1927
1991
|
|
1928
1992
|
Then 'the attribute consistency warning 019 should warn on lines 2 and 10 in that order' do
|
@@ -1982,7 +2046,7 @@ Then /^the build will (succeed|fail) with (?:no )?warnings(.*)$/ do |build_outco
|
|
1982
2046
|
end
|
1983
2047
|
|
1984
2048
|
Then 'the check for server warning 003 should not be displayed against the condition' do
|
1985
|
-
expect_warning("FC003", :line =>
|
2049
|
+
expect_warning("FC003", :line => nil, :expect_warning => false)
|
1986
2050
|
end
|
1987
2051
|
|
1988
2052
|
Then /^the check for server warning 003 should not be displayed against the search after the (.*) conditional$/ do |format|
|
@@ -2038,10 +2102,10 @@ end
|
|
2038
2102
|
|
2039
2103
|
Then /^the line number and line of code that triggered the warning(s)? should be displayed$/ do |multiple|
|
2040
2104
|
if multiple.nil?
|
2041
|
-
expect_line_shown
|
2105
|
+
expect_line_shown 1, "log node[:foo]"
|
2042
2106
|
else
|
2043
|
-
expect_line_shown
|
2044
|
-
expect_line_shown
|
2107
|
+
expect_line_shown 1, "node[:foo] = 'bar'"
|
2108
|
+
expect_line_shown 2, " node[:testing] = 'bar'"
|
2045
2109
|
end
|
2046
2110
|
end
|
2047
2111
|
|
@@ -2053,6 +2117,35 @@ Then /^the no leading cookbook name warning 029 should be (not )?shown$/ do |sho
|
|
2053
2117
|
expect_warning('FC029', :line => 1, :expect_warning => should_not.nil?, :file => 'metadata.rb')
|
2054
2118
|
end
|
2055
2119
|
|
2120
|
+
Then 'the node access warning 001 should be displayed for each match' do
|
2121
|
+
expect_warning('FC001', :line => 1)
|
2122
|
+
expect_warning('FC001', :line => 2)
|
2123
|
+
end
|
2124
|
+
|
2125
|
+
Then 'the node access warning 001 should be displayed against the variables' do
|
2126
|
+
expect_warning('FC001', :line => 4)
|
2127
|
+
expect_warning('FC001', :line => 5)
|
2128
|
+
end
|
2129
|
+
|
2130
|
+
Then 'the node access warning 001 should be displayed twice for the same line' do
|
2131
|
+
expect_warning('FC001', :line => 1, :num_occurrences => 2)
|
2132
|
+
end
|
2133
|
+
|
2134
|
+
Then 'the node access warning 001 should warn on lines 2 and 10 in that order' do
|
2135
|
+
expected_warnings = [2, 10].map do |line|
|
2136
|
+
"FC001: Use strings in preference to symbols to access node attributes: cookbooks/example/recipes/default.rb:#{line}"
|
2137
|
+
end
|
2138
|
+
expect_output(expected_warnings.join("\n"))
|
2139
|
+
end
|
2140
|
+
|
2141
|
+
Then 'the node access warning 001 should be displayed for the recipe' do
|
2142
|
+
expect_warning('FC001')
|
2143
|
+
end
|
2144
|
+
|
2145
|
+
Then 'the node access warning 001 should not be displayed for the attributes' do
|
2146
|
+
expect_warning("FC001", :file_type => :attributes, :line => 1, :expect_warning => false)
|
2147
|
+
end
|
2148
|
+
|
2056
2149
|
Then 'the prefer chef_gem to manual install warning 025 should be shown' do
|
2057
2150
|
expect_warning('FC025', :line => nil)
|
2058
2151
|
end
|
@@ -2115,7 +2208,7 @@ end
|
|
2115
2208
|
|
2116
2209
|
Then 'the usage text should include an option for specifying tags that will fail the build' do
|
2117
2210
|
expect_usage_option('f', 'epic-fail TAGS',
|
2118
|
-
"Fail the build
|
2211
|
+
"Fail the build based on tags. Use 'any' to fail on all warnings.")
|
2119
2212
|
end
|
2120
2213
|
|
2121
2214
|
Then /^the warnings shown should be (.*)$/ do |warnings|
|
@@ -5,8 +5,16 @@ module FoodCritic
|
|
5
5
|
# Unless the environment variable FC_FORK_PROCESS is set to 'true' then the features will be run in the same process.
|
6
6
|
module CommandHelpers
|
7
7
|
|
8
|
+
include MiniTest::Assertions
|
9
|
+
|
10
|
+
attr_writer :assertions
|
11
|
+
def assertions
|
12
|
+
@assertions ||= 0
|
13
|
+
end
|
14
|
+
|
8
15
|
# The warning codes and messages displayed to the end user.
|
9
16
|
WARNINGS = {
|
17
|
+
'FC001' => 'Use strings in preference to symbols to access node attributes',
|
10
18
|
'FC002' => 'Avoid string interpolation where not required',
|
11
19
|
'FC003' => 'Check whether you are running with chef server before using server-specific features',
|
12
20
|
'FC004' => 'Use a service resource to start and stop services',
|
@@ -131,6 +139,12 @@ module FoodCritic
|
|
131
139
|
expect_output(Regexp.new(expected_switch))
|
132
140
|
end
|
133
141
|
|
142
|
+
def has_test_warnings?(output)
|
143
|
+
output.split("\n").grep(/FC[0-9]+:/).map do |warn|
|
144
|
+
File.basename(File.dirname(warn.split(':').take(3).last.strip))
|
145
|
+
end.include?('test')
|
146
|
+
end
|
147
|
+
|
134
148
|
def man_page_options
|
135
149
|
man_path = Pathname.new(__FILE__) + '../../../man/foodcritic.1.ronn'
|
136
150
|
option_lines = File.read(man_path).split('## ').find do |s|
|
@@ -167,10 +181,10 @@ module FoodCritic
|
|
167
181
|
:description => 'Only check against rules valid for this version of Chef.'},
|
168
182
|
|
169
183
|
{:short => 'f', :long => 'epic-fail TAGS',
|
170
|
-
:description => "Fail the build
|
184
|
+
:description => "Fail the build based on tags. Use 'any' to fail on all warnings."},
|
171
185
|
|
172
186
|
{:short => 't', :long => 'tags TAGS',
|
173
|
-
:description => '
|
187
|
+
:description => 'Check against (or exclude ~) rules with the specified tags.'},
|
174
188
|
|
175
189
|
{:short => 'B', :long => 'cookbook-path PATH',
|
176
190
|
:description => 'Cookbook path(s) to check.'},
|
@@ -191,7 +205,10 @@ module FoodCritic
|
|
191
205
|
:description => 'Specify grammar to use when validating search syntax.'},
|
192
206
|
|
193
207
|
{:short => 'V', :long => 'version',
|
194
|
-
:description => 'Display the foodcritic version.'}
|
208
|
+
:description => 'Display the foodcritic version.'},
|
209
|
+
|
210
|
+
{:short => 'X', :long => 'exclude PATH',
|
211
|
+
:description => 'Exclude path(s) from being linted.'}
|
195
212
|
|
196
213
|
]
|
197
214
|
end
|
@@ -213,9 +230,9 @@ module FoodCritic
|
|
213
230
|
# @param [String] output The warning to check for.
|
214
231
|
def expect_output(output)
|
215
232
|
if output.respond_to?(:~)
|
216
|
-
@review.
|
233
|
+
@review.must_match(output)
|
217
234
|
else
|
218
|
-
@review.
|
235
|
+
@review.must_include(output)
|
219
236
|
end
|
220
237
|
end
|
221
238
|
|
@@ -224,20 +241,32 @@ module FoodCritic
|
|
224
241
|
# @param [String] output The output to check for.
|
225
242
|
def expect_no_output(output)
|
226
243
|
if output.respond_to?(:~)
|
227
|
-
@review.
|
244
|
+
@review.wont_match(output)
|
228
245
|
else
|
229
|
-
@review.
|
246
|
+
@review.wont_include(output)
|
230
247
|
end
|
231
248
|
end
|
232
249
|
|
233
250
|
# Assert that an error occurred following a lint check.
|
234
251
|
def assert_error_occurred
|
235
|
-
@status.
|
252
|
+
@status.wont_equal 0
|
236
253
|
end
|
237
254
|
|
238
255
|
# Assert that no error occurred following a lint check.
|
239
256
|
def assert_no_error_occurred
|
240
|
-
@status.
|
257
|
+
@status.must_equal 0
|
258
|
+
end
|
259
|
+
|
260
|
+
# Assert that warnings have not been raised against the test code which
|
261
|
+
# should have been excluded from linting.
|
262
|
+
def assert_no_test_warnings
|
263
|
+
refute has_test_warnings?(@review)
|
264
|
+
end
|
265
|
+
|
266
|
+
# Assert that warnings have been raised against the test code which
|
267
|
+
# shouldn't have been excluded from linting.
|
268
|
+
def assert_test_warnings
|
269
|
+
assert has_test_warnings?(@review)
|
241
270
|
end
|
242
271
|
|
243
272
|
# Run a lint check with the provided command line arguments.
|
@@ -278,9 +307,13 @@ module FoodCritic
|
|
278
307
|
# Assert that warnings have not been raised against the test code which
|
279
308
|
# should have been excluded from linting.
|
280
309
|
def assert_no_test_warnings
|
281
|
-
all_output
|
282
|
-
|
283
|
-
|
310
|
+
refute has_test_warnings?(all_output)
|
311
|
+
end
|
312
|
+
|
313
|
+
# Assert that warnings have been raised against the test code which
|
314
|
+
# shouldn't have been excluded from linting.
|
315
|
+
def assert_test_warnings
|
316
|
+
assert has_test_warnings?(all_output)
|
284
317
|
end
|
285
318
|
|
286
319
|
# The available tasks for this build
|