foodcritic 12.1.0 → 12.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/chef_dsl_metadata/chef_13.6.0.json +20328 -0
- data/lib/foodcritic/dsl.rb +1 -1
- data/lib/foodcritic/linter.rb +1 -1
- data/lib/foodcritic/rules/fc075.rb +1 -3
- data/lib/foodcritic/rules/fc082.rb +1 -3
- data/lib/foodcritic/rules/fc084.rb +1 -4
- data/lib/foodcritic/rules/fc085.rb +35 -2
- data/lib/foodcritic/rules/fc086.rb +2 -6
- data/lib/foodcritic/rules/fc087.rb +0 -1
- data/lib/foodcritic/rules/fc088.rb +1 -6
- data/lib/foodcritic/rules/fc089.rb +1 -6
- data/lib/foodcritic/rules/fc091.rb +0 -1
- data/lib/foodcritic/rules/fc092.rb +0 -1
- data/lib/foodcritic/rules/fc093.rb +0 -1
- data/lib/foodcritic/rules/fc094.rb +0 -1
- data/lib/foodcritic/rules/fc095.rb +0 -1
- data/lib/foodcritic/rules/fc096.rb +0 -1
- data/lib/foodcritic/rules/fc097.rb +1 -5
- data/lib/foodcritic/rules/fc098.rb +1 -5
- data/lib/foodcritic/rules/fc099.rb +1 -5
- data/lib/foodcritic/rules/fc100.rb +1 -5
- data/lib/foodcritic/rules/fc102.rb +1 -5
- data/lib/foodcritic/rules/fc103.rb +8 -0
- data/lib/foodcritic/rules/fc104.rb +18 -0
- data/lib/foodcritic/rules/fc105.rb +6 -0
- data/lib/foodcritic/rules/fc106.rb +8 -0
- data/lib/foodcritic/rules/fc107.rb +6 -0
- data/lib/foodcritic/rules/fc108.rb +12 -0
- data/lib/foodcritic/rules/fc109.rb +8 -0
- data/lib/foodcritic/version.rb +1 -1
- data/spec/functional/fc085_spec.rb +23 -4
- data/spec/functional/fc086_spec.rb +6 -2
- data/spec/functional/fc103_spec.rb +30 -0
- data/spec/functional/fc104_spec.rb +45 -0
- data/spec/functional/fc105_spec.rb +36 -0
- data/spec/functional/fc106_spec.rb +21 -0
- data/spec/functional/fc107_spec.rb +22 -0
- data/spec/functional/fc108_spec.rb +43 -0
- data/spec/functional/fc109_spec.rb +22 -0
- data/spec/regression/expected/database.txt +0 -1
- data/spec/unit/linter_spec.rb +1 -1
- metadata +18 -3
data/lib/foodcritic/dsl.rb
CHANGED
@@ -56,7 +56,7 @@ module FoodCritic
|
|
56
56
|
end
|
57
57
|
|
58
58
|
# The most frequently used block within a rule. A slight misnomer because
|
59
|
-
# `recipe` rule blocks are also evaluated against providers
|
59
|
+
# `recipe` rule blocks are also evaluated against resources, providers and libraries
|
60
60
|
rule_block :recipe
|
61
61
|
|
62
62
|
rule_block :cookbook
|
data/lib/foodcritic/linter.rb
CHANGED
@@ -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 = "13.
|
12
|
+
DEFAULT_CHEF_VERSION = "13.6.0"
|
13
13
|
attr_reader :chef_version
|
14
14
|
|
15
15
|
# Perform a lint check. This method is intended for use by the command-line
|
@@ -1,9 +1,7 @@
|
|
1
1
|
rule "FC075", "Cookbook uses node.save to save partial node data to the chef-server mid-run" do
|
2
2
|
tags %w{correctness}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
ast.xpath('//call[(vcall|var_ref)/ident/@value="node"]
|
5
5
|
[ident/@value="save"]')
|
6
6
|
end
|
7
|
-
recipe { |ast| node_saves(ast) }
|
8
|
-
library { |ast| node_saves(ast) }
|
9
7
|
end
|
@@ -1,9 +1,7 @@
|
|
1
1
|
rule "FC082", "Deprecated node.set or node.set_unless used to set node attributes" do
|
2
2
|
tags %w{chef14 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
ast.xpath('//call[(vcall|var_ref)/ident/@value="node"]
|
5
5
|
[ident[@value="set" or @value="set_unless"]]')
|
6
6
|
end
|
7
|
-
recipe { |ast| node_sets(ast) }
|
8
|
-
library { |ast| node_sets(ast) }
|
9
7
|
end
|
@@ -1,9 +1,6 @@
|
|
1
1
|
rule "FC084", "Deprecated Chef::REST class used" do
|
2
2
|
tags %w{chef13 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
ast.xpath('//const_path_ref/const[@value="REST"]/..//const[@value="Chef"]/../../..')
|
5
5
|
end
|
6
|
-
recipe { |ast| rest(ast) }
|
7
|
-
library { |ast| rest(ast) }
|
8
|
-
|
9
6
|
end
|
@@ -1,8 +1,41 @@
|
|
1
1
|
rule "FC085", "Resource using new_resource.updated_by_last_action to converge resource" do
|
2
2
|
tags %w{chef13 deprecated}
|
3
3
|
def updated_by(ast)
|
4
|
-
|
5
|
-
|
4
|
+
# we need to handle both @new_resource.updated_by_last_action(true) or new_resource.updated_by_last_action(true)
|
5
|
+
# Here's the ast that xpath sees in all 3 possible scenarios from those two:
|
6
|
+
# <call value=".">
|
7
|
+
# <vcall value="vcall">
|
8
|
+
# <ident value="new_resource">
|
9
|
+
# <pos line="26" column="0"/>
|
10
|
+
# </ident>
|
11
|
+
# </vcall>
|
12
|
+
# <ident value="updated_by_last_action">
|
13
|
+
# <pos line="26" column="13"/>
|
14
|
+
# </ident>
|
15
|
+
# </call>
|
16
|
+
#
|
17
|
+
# <call value=".">
|
18
|
+
# <var_ref value="var_ref">
|
19
|
+
# <ivar value="@new_resource">
|
20
|
+
# <pos line="25" column="0"/>
|
21
|
+
# </ivar>
|
22
|
+
# </var_ref>
|
23
|
+
# <ident value="updated_by_last_action">
|
24
|
+
# <pos line="25" column="14"/>
|
25
|
+
# </ident>
|
26
|
+
# </call>
|
27
|
+
#
|
28
|
+
# <call value=".">
|
29
|
+
# <var_ref value="var_ref">
|
30
|
+
# <ident value="new_resource">
|
31
|
+
# <pos line="27" column="0"/>
|
32
|
+
# </ident>
|
33
|
+
# </vcall>
|
34
|
+
# <ident value="updated_by_last_action">
|
35
|
+
# <pos line="27" column="13"/>
|
36
|
+
# </ident>
|
37
|
+
# </call>
|
38
|
+
ast.xpath('descendant::*[self::var_ref/ident/@value="new_resource" or self::vcall/ident/@value="new_resource" or self::var_ref/ivar/@value="@new_resource"]/../ident[@value="updated_by_last_action"]')
|
6
39
|
end
|
7
40
|
|
8
41
|
resource { |ast| updated_by(ast) }
|
@@ -1,10 +1,6 @@
|
|
1
1
|
rule "FC086", "Use databag helper methods to load data bag items" do
|
2
2
|
tags %w{style}
|
3
|
-
|
4
|
-
ast.xpath('//const_path_ref/const[@value="EncryptedDataBagItem" or @value="DataBagItem"]/..//const[@value="Chef"]/../../..//ident[@value
|
3
|
+
recipe do |ast|
|
4
|
+
ast.xpath('//const_path_ref/const[@value="EncryptedDataBagItem" or @value="DataBagItem"]/..//const[@value="Chef"]/../../..//ident[@value="load"]/..')
|
5
5
|
end
|
6
|
-
|
7
|
-
resource { |ast| old_dbag(ast) }
|
8
|
-
recipe { |ast| old_dbag(ast) }
|
9
|
-
library { |ast| old_dbag(ast) }
|
10
6
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
rule "FC087", "Library uses deprecated Chef::Platform methods" do
|
2
2
|
tags %w{chef13 deprecated}
|
3
|
-
|
4
3
|
library do |ast|
|
5
4
|
ast.xpath('//const_path_ref/const[@value="Platform"]/..//const[@value="Chef"]/../../../ident[@value="set" or @value="provider_for_resource" or @value="find_provider"]')
|
6
5
|
end
|
@@ -1,11 +1,6 @@
|
|
1
1
|
rule "FC088", "Prefer Mixlib::Shellout over deprecated Chef::Mixin::Command" do
|
2
2
|
tags %w{chef13 deprecated}
|
3
|
-
|
4
|
-
def includes_command(ast)
|
3
|
+
recipe do |ast|
|
5
4
|
ast.xpath('//const_path_ref/const[@value="Command"]/..//const[@value="Mixin"]/..//const[@value="Chef"]')
|
6
5
|
end
|
7
|
-
|
8
|
-
resource { |ast| includes_command(ast) }
|
9
|
-
recipe { |ast| includes_command(ast) }
|
10
|
-
library { |ast| includes_command(ast) }
|
11
6
|
end
|
@@ -1,11 +1,6 @@
|
|
1
1
|
rule "FC089", "Prefer Mixlib::Shellout over deprecated Chef::ShellOut" do
|
2
2
|
tags %w{chef13 deprecated}
|
3
|
-
|
4
|
-
def old_shellout(ast)
|
3
|
+
recipe do |ast|
|
5
4
|
ast.xpath('//const_path_ref[var_ref/const[@value="Chef"]]/const[@value="ShellOut"]')
|
6
5
|
end
|
7
|
-
|
8
|
-
resource { |ast| old_shellout(ast) }
|
9
|
-
recipe { |ast| old_shellout(ast) }
|
10
|
-
library { |ast| old_shellout(ast) }
|
11
6
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
rule "FC096", "Cookbook uses deprecated libvirt virtualization ohai data" do
|
2
2
|
tags %w{deprecated chef14}
|
3
|
-
|
4
3
|
recipe do |ast|
|
5
4
|
ast.xpath('//aref[aref/vcall/ident/@value="node"]
|
6
5
|
[aref/args_add_block/args_add/string_literal/string_add/tstring_content/@value="virtualization" and
|
@@ -1,11 +1,7 @@
|
|
1
1
|
rule "FC097", "Deprecated Chef::Mixin::LanguageIncludeAttribute mixin used" do
|
2
2
|
tags %w{chef14 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
# include Chef::Mixin::LanguageIncludeAttribute
|
5
5
|
ast.xpath('//const_path_ref/const[@value="LanguageIncludeAttribute"]/..//const[@value="Mixin"]/..//const[@value="Chef"]')
|
6
6
|
end
|
7
|
-
recipe { |ast| lang_include_attrib_mixin(ast) }
|
8
|
-
library { |ast| lang_include_attrib_mixin(ast) }
|
9
|
-
resource { |ast| lang_include_attrib_mixin(ast) }
|
10
|
-
|
11
7
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
rule "FC098", "Deprecated Chef::Mixin::RecipeDefinitionDSLCore mixin used" do
|
2
2
|
tags %w{chef14 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
# include Chef::Mixin::RecipeDefinitionDSLCore
|
5
5
|
ast.xpath('//const_path_ref/const[@value="RecipeDefinitionDSLCore"]/..//const[@value="Mixin"]/..//const[@value="Chef"]')
|
6
6
|
end
|
7
|
-
recipe { |ast| recipe_def_mixin(ast) }
|
8
|
-
library { |ast| recipe_def_mixin(ast) }
|
9
|
-
resource { |ast| recipe_def_mixin(ast) }
|
10
|
-
|
11
7
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
rule "FC099", "Deprecated Chef::Mixin::LanguageIncludeRecipe mixin used" do
|
2
2
|
tags %w{chef14 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
# include Chef::Mixin::LanguageIncludeRecipe
|
5
5
|
ast.xpath('//const_path_ref/const[@value="LanguageIncludeRecipe"]/..//const[@value="Mixin"]/..//const[@value="Chef"]')
|
6
6
|
end
|
7
|
-
recipe { |ast| lang_include_mixin(ast) }
|
8
|
-
library { |ast| lang_include_mixin(ast) }
|
9
|
-
resource { |ast| lang_include_mixin(ast) }
|
10
|
-
|
11
7
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
rule "FC100", "Deprecated Chef::Mixin::Language mixin used" do
|
2
2
|
tags %w{chef14 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
# include Chef::Mixin::Language
|
5
5
|
ast.xpath('//const_path_ref/const[@value="Language"]/..//const[@value="Mixin"]/..//const[@value="Chef"]')
|
6
6
|
end
|
7
|
-
recipe { |ast| lang_mixin(ast) }
|
8
|
-
library { |ast| lang_mixin(ast) }
|
9
|
-
resource { |ast| lang_mixin(ast) }
|
10
|
-
|
11
7
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
rule "FC102", "Deprecated Chef::DSL::Recipe::FullDSL class used" do
|
2
2
|
tags %w{chef14 deprecated}
|
3
|
-
|
3
|
+
recipe do |ast|
|
4
4
|
# include Chef::DSL::Recipe::FullDSL
|
5
5
|
ast.xpath('//const_path_ref/const[@value="FullDSL"]/..//const[@value="Recipe"]/..//const[@value="DSL"]/..//const[@value="Chef"]')
|
6
6
|
end
|
7
|
-
recipe { |ast| full_dsl(ast) }
|
8
|
-
library { |ast| full_dsl(ast) }
|
9
|
-
resource { |ast| full_dsl(ast) }
|
10
|
-
|
11
7
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
rule "FC103", "Deprecated :uninstall action in chocolatey_package used" do
|
2
|
+
tags %w{deprecated chef14}
|
3
|
+
recipe do |ast|
|
4
|
+
find_resources(ast, type: "chocolatey_package").find_all do |choco_resource|
|
5
|
+
resource_attribute(choco_resource, "action") == :uninstall
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
rule "FC104", "Use the :run action in ruby_block instead of :create" do
|
2
|
+
tags %w{correctness}
|
3
|
+
recipe do |ast|
|
4
|
+
matches = []
|
5
|
+
find_resources(ast).each do |resource|
|
6
|
+
# if it's a ruby_block check for the :create action
|
7
|
+
if ast.xpath('//method_add_block[command/ident[@value="ruby_block"]]')
|
8
|
+
matches << resource if resource_attribute(resource, "action") == :create
|
9
|
+
end
|
10
|
+
|
11
|
+
# no matter what check notification
|
12
|
+
notifications(resource).any? do |notification|
|
13
|
+
matches << resource if notification[:resource_type] == :ruby_block && notification[:action] == :create
|
14
|
+
end
|
15
|
+
end
|
16
|
+
matches
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
rule "FC108", "Resource should not define a property named 'name'" do
|
2
|
+
tags %w{correctness}
|
3
|
+
resource do |ast|
|
4
|
+
# Make sure we're in a custom resource not an LWRP
|
5
|
+
if ast.xpath("//command/ident/@value='action'")
|
6
|
+
# command has a child of type ident with a value of "property". That tells us
|
7
|
+
# we're in a property. Quite a ways desecendant from that is another ident
|
8
|
+
# with value of "name"
|
9
|
+
ast.xpath("//command[ident/@value='property' and descendant::symbol_literal/symbol/ident/@value='name']")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
rule "FC109", "Use platform-specific package resources instead of provider property" do
|
2
|
+
tags %w{correctness}
|
3
|
+
recipe do |ast|
|
4
|
+
find_resources(ast, type: "package").find_all do |package_resources|
|
5
|
+
resource_attribute(package_resources, "provider")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
data/lib/foodcritic/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "FC085" do
|
4
|
-
context "with a cookbook with a custom resource that converges with updated_by_last_action" do
|
4
|
+
context "with a cookbook with a custom resource that converges with new_resource.updated_by_last_action" do
|
5
5
|
resource_file <<-EOF
|
6
6
|
action :create do
|
7
7
|
template "/etc/something.conf" do
|
@@ -14,8 +14,8 @@ describe "FC085" do
|
|
14
14
|
it { is_expected.to violate_rule }
|
15
15
|
end
|
16
16
|
|
17
|
-
context "with a cookbook with a LWRP that converges with updated_by_last_action" do
|
18
|
-
|
17
|
+
context "with a cookbook with a LWRP that converges with @new_resource.updated_by_last_action" do
|
18
|
+
provider_file <<-EOF
|
19
19
|
use_inline_resources
|
20
20
|
|
21
21
|
action :create do
|
@@ -23,6 +23,15 @@ describe "FC085" do
|
|
23
23
|
notifies :restart, "service[something]"
|
24
24
|
end
|
25
25
|
|
26
|
+
@new_resource.updated_by_last_action(true)
|
27
|
+
end
|
28
|
+
EOF
|
29
|
+
it { is_expected.to violate_rule }
|
30
|
+
end
|
31
|
+
|
32
|
+
context "with a cookbook with a LWRP that converges with new_resource.updated_by_last_action in a method" do
|
33
|
+
provider_file <<-EOF
|
34
|
+
def update_me(new_resource)
|
26
35
|
new_resource.updated_by_last_action(true)
|
27
36
|
end
|
28
37
|
EOF
|
@@ -42,7 +51,7 @@ describe "FC085" do
|
|
42
51
|
end
|
43
52
|
|
44
53
|
context "with a cookbook with a LWRP that relies on resources for convergence" do
|
45
|
-
|
54
|
+
provider_file <<-EOF
|
46
55
|
use_inline_resources
|
47
56
|
|
48
57
|
action :create do
|
@@ -55,4 +64,14 @@ describe "FC085" do
|
|
55
64
|
it { is_expected.to_not violate_rule }
|
56
65
|
end
|
57
66
|
|
67
|
+
context "with a cookbook with a LWRP that calls foo.updated_by_last_action" do
|
68
|
+
provider_file <<-EOF
|
69
|
+
use_inline_resources
|
70
|
+
|
71
|
+
action :create do
|
72
|
+
foo.updated_by_last_action(true)
|
73
|
+
EOF
|
74
|
+
it { is_expected.to_not violate_rule }
|
75
|
+
end
|
76
|
+
|
58
77
|
end
|
@@ -34,8 +34,12 @@ describe "FC086" do
|
|
34
34
|
it { is_expected.not_to violate_rule }
|
35
35
|
end
|
36
36
|
|
37
|
-
context "with a recipe that uses Chef::EncryptedDataBagItem
|
38
|
-
recipe_file
|
37
|
+
context "with a recipe that uses other Chef::EncryptedDataBagItem methods" do
|
38
|
+
recipe_file <<-EOF
|
39
|
+
data_bag_item('bag', 'item', Chef::EncryptedDataBagItem.load_secret('secret_file'))
|
40
|
+
encrypted_item = Chef::EncryptedDataBagItem.encrypt_data_bag_item(original_item, Chef::EncryptedDataBagItem.load_secret)
|
41
|
+
bag = Chef::DataBagItem.new
|
42
|
+
EOF
|
39
43
|
it { is_expected.not_to violate_rule }
|
40
44
|
end
|
41
45
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "FC103" do
|
4
|
+
context "with a cookbook with a custom resource that uses the :uninstall resource in chocolatey_package" do
|
5
|
+
resource_file <<-EOF
|
6
|
+
chocolatey_package 'name' do
|
7
|
+
action :uninstall
|
8
|
+
end
|
9
|
+
EOF
|
10
|
+
it { is_expected.to violate_rule }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "with a cookbook with a recipe that uses the :uninstall resource in chocolatey_package" do
|
14
|
+
recipe_file <<-EOF
|
15
|
+
chocolatey_package 'name' do
|
16
|
+
action :uninstall
|
17
|
+
end
|
18
|
+
EOF
|
19
|
+
it { is_expected.to violate_rule }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with a cookbook with a library that uses the :uninstall resource in chocolatey_package" do
|
23
|
+
library_file <<-EOF
|
24
|
+
chocolatey_package 'name' do
|
25
|
+
action :uninstall
|
26
|
+
end
|
27
|
+
EOF
|
28
|
+
it { is_expected.to violate_rule }
|
29
|
+
end
|
30
|
+
end
|