foodcritic 10.0.0 → 10.1.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 +12 -1
- data/Gemfile +2 -2
- data/features/031_check_for_metadata_existence.feature +2 -2
- data/features/choose_rules_to_apply.feature +27 -27
- data/features/continuous_integration_support.feature +2 -2
- data/features/support/command_helpers.rb +2 -2
- data/lib/foodcritic/api.rb +29 -3
- data/lib/foodcritic/linter.rb +1 -1
- data/lib/foodcritic/rules/fc001.rb +7 -0
- data/lib/foodcritic/rules/fc002.rb +8 -0
- data/lib/foodcritic/rules/fc004.rb +12 -0
- data/lib/foodcritic/rules/fc005.rb +29 -0
- data/lib/foodcritic/rules/fc006.rb +11 -0
- data/lib/foodcritic/rules/fc007.rb +19 -0
- data/lib/foodcritic/rules/fc008.rb +12 -0
- data/lib/foodcritic/rules/fc009.rb +18 -0
- data/lib/foodcritic/rules/fc010.rb +7 -0
- data/lib/foodcritic/rules/fc011.rb +8 -0
- data/lib/foodcritic/rules/fc012.rb +8 -0
- data/lib/foodcritic/rules/fc013.rb +10 -0
- data/lib/foodcritic/rules/fc014.rb +10 -0
- data/lib/foodcritic/rules/fc015.rb +8 -0
- data/lib/foodcritic/rules/fc016.rb +10 -0
- data/lib/foodcritic/rules/fc017.rb +29 -0
- data/lib/foodcritic/rules/fc018.rb +9 -0
- data/lib/foodcritic/rules/fc019.rb +34 -0
- data/lib/foodcritic/rules/fc021.rb +13 -0
- data/lib/foodcritic/rules/fc022.rb +33 -0
- data/lib/foodcritic/rules/fc024.rb +31 -0
- data/lib/foodcritic/rules/fc025.rb +17 -0
- data/lib/foodcritic/rules/fc026.rb +14 -0
- data/lib/foodcritic/rules/fc027.rb +9 -0
- data/lib/foodcritic/rules/fc028.rb +8 -0
- data/lib/foodcritic/rules/fc029.rb +14 -0
- data/lib/foodcritic/rules/fc030.rb +11 -0
- data/lib/foodcritic/rules/fc031.rb +8 -0
- data/lib/foodcritic/rules/fc032.rb +15 -0
- data/lib/foodcritic/rules/fc033.rb +26 -0
- data/lib/foodcritic/rules/fc034.rb +31 -0
- data/lib/foodcritic/rules/fc037.rb +14 -0
- data/lib/foodcritic/rules/fc038.rb +17 -0
- data/lib/foodcritic/rules/fc039.rb +19 -0
- data/lib/foodcritic/rules/fc040.rb +12 -0
- data/lib/foodcritic/rules/fc041.rb +9 -0
- data/lib/foodcritic/rules/fc042.rb +6 -0
- data/lib/foodcritic/rules/fc043.rb +8 -0
- data/lib/foodcritic/rules/fc044.rb +22 -0
- data/lib/foodcritic/rules/fc045.rb +13 -0
- data/lib/foodcritic/rules/fc046.rb +8 -0
- data/lib/foodcritic/rules/fc047.rb +16 -0
- data/lib/foodcritic/rules/fc048.rb +13 -0
- data/lib/foodcritic/rules/fc049.rb +10 -0
- data/lib/foodcritic/rules/fc050.rb +8 -0
- data/lib/foodcritic/rules/fc051.rb +15 -0
- data/lib/foodcritic/rules/fc052.rb +6 -0
- data/lib/foodcritic/rules/fc053.rb +6 -0
- data/lib/foodcritic/rules/fc055.rb +6 -0
- data/lib/foodcritic/rules/fc056.rb +6 -0
- data/lib/foodcritic/rules/fc057.rb +8 -0
- data/lib/foodcritic/rules/fc058.rb +9 -0
- data/lib/foodcritic/rules/fc059.rb +10 -0
- data/lib/foodcritic/rules/fc060.rb +10 -0
- data/lib/foodcritic/rules/fc061.rb +10 -0
- data/lib/foodcritic/rules/fc062.rb +6 -0
- data/lib/foodcritic/rules/fc063.rb +8 -0
- data/lib/foodcritic/rules/fc064.rb +6 -0
- data/lib/foodcritic/rules/fc065.rb +6 -0
- data/lib/foodcritic/version.rb +1 -1
- data/spec/foodcritic/api_spec.rb +62 -0
- data/spec/foodcritic/coverage/assets/0.10.0/application.css +799 -0
- data/spec/foodcritic/coverage/assets/0.10.0/application.js +1707 -0
- data/spec/foodcritic/coverage/assets/0.10.0/colorbox/border.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/colorbox/controls.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/favicon_green.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/favicon_red.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/favicon_yellow.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/loading.gif +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/magnify.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/foodcritic/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/foodcritic/coverage/index.html +72 -0
- data/spec/foodcritic/linter_spec.rb +7 -6
- data/spec/regression/expected-output.txt +0 -12
- data/spec/spec_helper.rb +3 -1
- metadata +88 -6
- data/features/023_check_for_condition_around_resource.feature +0 -52
- data/lib/foodcritic/rules.rb +0 -852
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d13edaa29dc5980c6783c28bdfa72c6ae5624ecd
|
4
|
+
data.tar.gz: 95e285806cc9168efa32ab6e1511e291bff66e3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1d7d8da69d8092724ccc970aa9a236175af58bb2c76a77582e6792ae3732efc924b98496faefecc3f02be8ce8315f61a412f2b71e80916c066956a1e7f5b5e9
|
7
|
+
data.tar.gz: 22c4676382a67e8c685af190bd473f22cdb161397e84479f4fa76666e4f89fff60d64fc88d121e808d3bbf9a32aea9fa754a79f9232abe08553afc42bd9b8112
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
# Foodcritic Changelog:
|
2
2
|
|
3
|
-
## [10.
|
3
|
+
## [10.1.0](https://github.com/acrmp/foodcritic/tree/10.1.0) (2017-03-29)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/acrmp/foodcritic/compare/v10.0.0...v10.1.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Remove FC023 which is no longer considered best practice [#523](https://github.com/acrmp/foodcritic/pull/523) ([tas50](https://github.com/tas50))
|
10
|
+
- Add basic testing of the metadata_field api [#522](https://github.com/acrmp/foodcritic/pull/522) ([tas50](https://github.com/tas50))
|
11
|
+
- Add a more robust cookbook_base_path helper to the API [#520](https://github.com/acrmp/foodcritic/pull/520) ([tas50](https://github.com/tas50))
|
12
|
+
- Update various tags to better align the rules with the tag categories [#517](https://github.com/acrmp/foodcritic/pull/517) ([tas50](https://github.com/tas50))
|
13
|
+
|
14
|
+
## [v10.0.0](https://github.com/acrmp/foodcritic/tree/v10.0.0) (2017-03-14)
|
4
15
|
|
5
16
|
[Full Changelog](https://github.com/acrmp/foodcritic/compare/v9.0.0...v10.0.0)
|
6
17
|
|
data/Gemfile
CHANGED
@@ -6,12 +6,12 @@ group :test do
|
|
6
6
|
gem "aruba", "~> 0.5"
|
7
7
|
gem "cucumber", ">= 2"
|
8
8
|
gem "minitest", "~> 5.3"
|
9
|
+
gem "minitest-reporters"
|
9
10
|
gem "simplecov", "~> 0.8"
|
11
|
+
gem "chefstyle", "~> 0.5"
|
10
12
|
end
|
11
13
|
|
12
14
|
group :development do
|
13
|
-
gem "chef", "~> 12.1"
|
14
|
-
gem "chefstyle", "~> 0.4"
|
15
15
|
gem "ronn", "~> 0.7"
|
16
16
|
end
|
17
17
|
|
@@ -4,12 +4,12 @@ Feature: Check for metadata existence
|
|
4
4
|
As a developer
|
5
5
|
I want to verify that the metadata file exist
|
6
6
|
|
7
|
-
Scenario: Cookbook without metadata file
|
7
|
+
Scenario: Cookbook without metadata.rb file
|
8
8
|
Given a cookbook that does not have defined metadata
|
9
9
|
When I check the cookbook
|
10
10
|
Then the non existing metadata warning 031 should be displayed against the metadata file
|
11
11
|
|
12
|
-
Scenario: Cookbook with metadata file
|
12
|
+
Scenario: Cookbook with metadata.rb file
|
13
13
|
Given a cookbook that has the default boilerplate metadata generated by knife
|
14
14
|
When I check the cookbook
|
15
15
|
Then the non existing metadata warning 031 should not be displayed against the metadata file
|
@@ -10,19 +10,19 @@ Feature: Choose rules to apply
|
|
10
10
|
Then the warnings shown should be <warnings_shown>
|
11
11
|
|
12
12
|
Examples:
|
13
|
-
| cookbook_matches | tag_arguments
|
14
|
-
| FC002,FC004,FC005 |
|
15
|
-
| FC002 | -t FC002
|
16
|
-
| FC002,FC004,FC005 | --tags FC002
|
17
|
-
| FC002,FC004,FC005 | --tags fc002
|
18
|
-
| FC002,FC004,FC005 | --tags FC006
|
19
|
-
| FC002,FC004,FC005 | --tags ~FC002
|
20
|
-
| | --tags FC002
|
21
|
-
| FC002,FC004,FC005 | --tags @FC002
|
22
|
-
| FC002,FC004,FC005 | --tags style
|
23
|
-
| FC002,FC004,FC005 | --tags FC002 --tags FC004
|
24
|
-
| FC002,FC004,FC005 | --tags
|
25
|
-
| FC002,FC004,FC005 | --tags style,services
|
13
|
+
| cookbook_matches | tag_arguments | warnings_shown |
|
14
|
+
| FC002,FC004,FC005 | | FC002,FC004,FC005 |
|
15
|
+
| FC002 | -t FC002 | FC002 |
|
16
|
+
| FC002,FC004,FC005 | --tags FC002 | FC002 |
|
17
|
+
| FC002,FC004,FC005 | --tags fc002 | |
|
18
|
+
| FC002,FC004,FC005 | --tags FC006 | |
|
19
|
+
| FC002,FC004,FC005 | --tags ~FC002 | FC004,FC005 |
|
20
|
+
| | --tags FC002 | |
|
21
|
+
| FC002,FC004,FC005 | --tags @FC002 | |
|
22
|
+
| FC002,FC004,FC005 | --tags style | FC002 |
|
23
|
+
| FC002,FC004,FC005 | --tags FC002 --tags FC004 | |
|
24
|
+
| FC002,FC004,FC005 | --tags portability --tags services | FC004 |
|
25
|
+
| FC002,FC004,FC005 | --tags style,services,portability | FC002,FC004 |
|
26
26
|
|
27
27
|
Scenario Outline: Specified tags in cookbook .foodcritic file
|
28
28
|
Given a cookbook that matches rules <cookbook_matches>
|
@@ -31,17 +31,17 @@ Feature: Choose rules to apply
|
|
31
31
|
Then the warnings shown should be <warnings_shown>
|
32
32
|
|
33
33
|
Examples:
|
34
|
-
| cookbook_matches | tag_file
|
35
|
-
| FC002,FC004 |
|
36
|
-
| FC002 | FC002
|
37
|
-
| FC002 | ~FC002
|
38
|
-
| FC002 | fc002
|
39
|
-
| FC002,FC004 | FC005
|
40
|
-
| FC002,FC004 | FC005
|
41
|
-
| FC002,FC004 | ~FC002
|
42
|
-
| FC002,FC004 | ~FC002
|
43
|
-
| | FC002
|
44
|
-
| FC002,FC004 | @FC002
|
45
|
-
| FC002,FC004 | style
|
46
|
-
| FC002,FC004 | FC002
|
47
|
-
| FC002,FC004 | style,
|
34
|
+
| cookbook_matches | tag_file | tag_arguments | warnings_shown |
|
35
|
+
| FC002,FC004 | | | FC002,FC004 |
|
36
|
+
| FC002 | FC002 | | FC002 |
|
37
|
+
| FC002 | ~FC002 | --tags FC002 | FC002 |
|
38
|
+
| FC002 | fc002 | | |
|
39
|
+
| FC002,FC004 | FC005 | | |
|
40
|
+
| FC002,FC004 | FC005 | -t FC002 | FC002 |
|
41
|
+
| FC002,FC004 | ~FC002 | | FC004 |
|
42
|
+
| FC002,FC004 | ~FC002 | -t FC002 | FC002 |
|
43
|
+
| | FC002 | | |
|
44
|
+
| FC002,FC004 | @FC002 | | |
|
45
|
+
| FC002,FC004 | style | | FC002 |
|
46
|
+
| FC002,FC004 | FC002 | | |
|
47
|
+
| FC002,FC004 | style,portability | | FC002,FC004 |
|
@@ -18,8 +18,8 @@ Feature: Continuous Integration Support
|
|
18
18
|
Examples:
|
19
19
|
| cookbook_matches | tag_arguments | warnings_shown | build_status |
|
20
20
|
| FC002,FC004 | | FC002,FC004 | failed |
|
21
|
-
| FC002,FC004 | -t style | FC002
|
22
|
-
| FC002,FC004 | -t style -f ~any | FC002
|
21
|
+
| FC002,FC004 | -t style | FC002 | failed |
|
22
|
+
| FC002,FC004 | -t style -f ~any | FC002 | successful |
|
23
23
|
| FC002,FC004 | -f FC005 | FC002,FC004 | successful |
|
24
24
|
| FC002,FC004 | -f FC004 | FC002,FC004 | failed |
|
25
25
|
| FC002,FC004 | --epic-fail FC002 | FC002,FC004 | failed |
|
@@ -35,7 +35,7 @@ module FoodCritic
|
|
35
35
|
"FC019" => "Access node attributes in a consistent manner",
|
36
36
|
"FC021" => "Resource condition in provider may not behave as expected",
|
37
37
|
"FC022" => "Resource condition within loop may not behave as expected",
|
38
|
-
|
38
|
+
# FC023 was yanked and is considered reserved, do not reuse it
|
39
39
|
"FC024" => "Consider adding platform equivalents",
|
40
40
|
"FC025" => "Prefer chef_gem to compile-time gem install",
|
41
41
|
"FC026" => "Conditional execution block attribute contains only string",
|
@@ -43,7 +43,7 @@ module FoodCritic
|
|
43
43
|
"FC028" => "Incorrect #platform? usage",
|
44
44
|
"FC029" => "No leading cookbook name in recipe metadata",
|
45
45
|
"FC030" => "Cookbook contains debugger breakpoints",
|
46
|
-
"FC031" => "Cookbook without metadata file",
|
46
|
+
"FC031" => "Cookbook without metadata.rb file",
|
47
47
|
"FC032" => "Invalid notification timing",
|
48
48
|
"FC033" => "Missing template",
|
49
49
|
"FC034" => "Unused template variables",
|
data/lib/foodcritic/api.rb
CHANGED
@@ -33,7 +33,11 @@ module FoodCritic
|
|
33
33
|
end
|
34
34
|
|
35
35
|
# Does the specified recipe check for Chef Solo?
|
36
|
+
#
|
37
|
+
# @deprecated chef-solo functionality in Chef has been replaced with local-mode
|
38
|
+
# so this helper is no longer necessary and will be removed in Foodcritic 11.0
|
36
39
|
def checks_for_chef_solo?(ast)
|
40
|
+
puts "the checks_for_chef_solo? helper is deprecated and will be removed from the next release of Foodcritic"
|
37
41
|
raise_unless_xpath!(ast)
|
38
42
|
# TODO: This expression is too loose, but also will fail to match other
|
39
43
|
# types of conditionals.
|
@@ -51,10 +55,13 @@ module FoodCritic
|
|
51
55
|
end == %w{Chef Config}
|
52
56
|
end
|
53
57
|
|
54
|
-
# Is the
|
55
|
-
#
|
56
|
-
#
|
58
|
+
# Is the chef-solo-search library available?
|
59
|
+
#
|
60
|
+
# @see https://github.com/edelight/chef-solo-search
|
61
|
+
# @deprecated chef-solo functionality in Chef has been replaced with local-mode
|
62
|
+
# so this helper is no longer necessary and will be removed in Foodcritic 11.0
|
57
63
|
def chef_solo_search_supported?(recipe_path)
|
64
|
+
puts "the chef_solo_search_supported? helper is deprecated and will be removed from the next release of Foodcritic"
|
58
65
|
return false if recipe_path.nil? || !File.exist?(recipe_path)
|
59
66
|
|
60
67
|
# Look for the chef-solo-search library.
|
@@ -75,6 +82,25 @@ module FoodCritic
|
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
85
|
+
# The absolute path of a cookbook from the specified file.
|
86
|
+
#
|
87
|
+
# @author Tim Smith - tsmith@chef.io
|
88
|
+
# @since 11.0
|
89
|
+
# @param file [String, Pathname] relative or absolute path to a file in the cookbook
|
90
|
+
# @return [String] the absolute path to the base of the cookbook
|
91
|
+
def cookbook_base_path(file)
|
92
|
+
file = File.expand_path(file) # make sure we get an absolute path
|
93
|
+
file = File.dirname(file) unless File.directory?(file) # get the dir only
|
94
|
+
|
95
|
+
# get list of items in the dir and intersect with metadata array.
|
96
|
+
# until we get an interfact (we have a metadata) walk up the dir structure
|
97
|
+
until (Dir.entries(file) & %w{metadata.rb metadata.json}).any?
|
98
|
+
file = File.dirname(file)
|
99
|
+
end
|
100
|
+
|
101
|
+
file
|
102
|
+
end
|
103
|
+
|
78
104
|
# Support function to retrieve a metadata field
|
79
105
|
def metadata_field(file, field)
|
80
106
|
until (file.split(File::SEPARATOR) & standard_cookbook_subdirs).empty?
|
data/lib/foodcritic/linter.rb
CHANGED
@@ -157,7 +157,7 @@ module FoodCritic
|
|
157
157
|
end
|
158
158
|
|
159
159
|
def load_rules!(options)
|
160
|
-
rule_files =
|
160
|
+
rule_files = Dir.glob(File.join(File.dirname(__FILE__), "rules", "*"))
|
161
161
|
rule_files << options[:include_rules]
|
162
162
|
rule_files << rule_files_in_gems if options[:search_gems]
|
163
163
|
@rules = RuleDsl.load(rule_files.flatten.compact, chef_version)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
rule "FC004", "Use a service resource to start and stop services" do
|
2
|
+
tags %w{portability services}
|
3
|
+
recipe do |ast|
|
4
|
+
find_resources(ast, type: "execute").find_all do |cmd|
|
5
|
+
cmd_str = (resource_attribute(cmd, "command") || resource_name(cmd)).to_s
|
6
|
+
(cmd_str.include?("/etc/init.d") || ["service ", "/sbin/service ",
|
7
|
+
"start ", "stop ", "invoke-rc.d "].any? do |service_cmd|
|
8
|
+
cmd_str.start_with?(service_cmd)
|
9
|
+
end) && %w{start stop restart reload}.any? { |a| cmd_str.include?(a) }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
rule "FC005", "Avoid repetition of resource declarations" do
|
2
|
+
tags %w{style}
|
3
|
+
recipe do |ast|
|
4
|
+
resources = find_resources(ast).map do |res|
|
5
|
+
resource_attributes(res).merge({ type: resource_type(res),
|
6
|
+
ast: res })
|
7
|
+
end.chunk do |res|
|
8
|
+
res[:type] +
|
9
|
+
res[:ast].xpath("ancestor::*[self::if | self::unless | self::elsif |
|
10
|
+
self::else | self::when | self::method_add_block/call][position() = 1]/
|
11
|
+
descendant::pos[position() = 1]").to_s +
|
12
|
+
res[:ast].xpath("ancestor::method_add_block/command[
|
13
|
+
ident/@value='action']/args_add_block/descendant::ident/@value").to_s
|
14
|
+
end.reject { |res| res[1].size < 3 }
|
15
|
+
resources.map do |cont_res|
|
16
|
+
first_resource = cont_res[1][0][:ast]
|
17
|
+
# we have contiguous resources of the same type, but do they share the
|
18
|
+
# same attributes?
|
19
|
+
sorted_atts = cont_res[1].map do |atts|
|
20
|
+
atts.delete_if { |k| k == :ast }.to_a.sort do |x, y|
|
21
|
+
x.first.to_s <=> y.first.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
first_resource if sorted_atts.all? do |att|
|
25
|
+
(att - sorted_atts.inject { |atts, a| atts & a }).length == 1
|
26
|
+
end
|
27
|
+
end.compact
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
rule "FC006", "Mode should be quoted or fully specified when "\
|
2
|
+
"setting file permissions" do
|
3
|
+
tags %w{correctness files}
|
4
|
+
recipe do |ast|
|
5
|
+
ast.xpath(%q{//ident[@value='mode']/parent::command/
|
6
|
+
descendant::int[string-length(@value) < 5
|
7
|
+
and not(starts-with(@value, "0")
|
8
|
+
and string-length(@value) = 4)][count(ancestor::aref) = 0]/
|
9
|
+
ancestor::method_add_block})
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
rule "FC007", "Ensure recipe dependencies are reflected in cookbook metadata" do
|
2
|
+
tags %w{correctness metadata}
|
3
|
+
recipe do |ast, filename|
|
4
|
+
metadata_path = Pathname.new(
|
5
|
+
File.join(File.dirname(filename), "..", "metadata.rb")).cleanpath
|
6
|
+
next unless File.exist? metadata_path
|
7
|
+
actual_included = included_recipes(ast, with_partial_names: false)
|
8
|
+
undeclared = actual_included.keys.map do |recipe|
|
9
|
+
recipe.split("::").first
|
10
|
+
end - [cookbook_name(filename)] -
|
11
|
+
declared_dependencies(read_ast(metadata_path))
|
12
|
+
actual_included.map do |recipe, include_stmts|
|
13
|
+
if undeclared.include?(recipe) ||
|
14
|
+
undeclared.any? { |u| recipe.start_with?("#{u}::") }
|
15
|
+
include_stmts
|
16
|
+
end
|
17
|
+
end.flatten.compact
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
rule "FC008", "Generated cookbook metadata needs updating" do
|
2
|
+
tags %w{metadata supermarket}
|
3
|
+
metadata do |ast, filename|
|
4
|
+
{
|
5
|
+
"maintainer" => "YOUR_COMPANY_NAME",
|
6
|
+
"maintainer_email" => "YOUR_EMAIL",
|
7
|
+
}.map do |field, value|
|
8
|
+
ast.xpath(%Q{//command[ident/@value='#{field}']/
|
9
|
+
descendant::tstring_content[@value='#{value}']})
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
rule "FC009", "Resource attribute not recognised" do
|
2
|
+
tags %w{correctness}
|
3
|
+
recipe do |ast|
|
4
|
+
matches = []
|
5
|
+
resource_attributes_by_type(ast).each do |type, resources|
|
6
|
+
resources.each do |resource|
|
7
|
+
resource.keys.map(&:to_sym).reject do |att|
|
8
|
+
resource_attribute?(type.to_sym, att)
|
9
|
+
end.each do |invalid_att|
|
10
|
+
matches << find_resources(ast, type: type).find do |res|
|
11
|
+
resource_attributes(res).include?(invalid_att.to_s)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
matches
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
rule "FC013", "Use file_cache_path rather than hard-coding tmp paths" do
|
2
|
+
tags %w{files portability}
|
3
|
+
recipe do |ast|
|
4
|
+
find_resources(ast, type: "remote_file").find_all do |download|
|
5
|
+
path = (resource_attribute(download, "path") ||
|
6
|
+
resource_name(download)).to_s
|
7
|
+
path.start_with?("/tmp/")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
rule "FC014", "Consider extracting long ruby_block to library" do
|
2
|
+
tags %w{style libraries}
|
3
|
+
recipe do |ast|
|
4
|
+
find_resources(ast, type: "ruby_block").find_all do |rb|
|
5
|
+
lines = rb.xpath("descendant::fcall[ident/@value='block']/../../
|
6
|
+
descendant::*[@line]/@line").map { |n| n.value.to_i }.sort
|
7
|
+
(!lines.empty?) && (lines.last - lines.first) > 15
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
rule "FC016", "LWRP does not declare a default action" do
|
2
|
+
tags %w{correctness lwrp}
|
3
|
+
resource do |ast, filename|
|
4
|
+
unless ["//ident/@value='default_action'",
|
5
|
+
"//def/bodystmt/descendant::assign/
|
6
|
+
var_field/ivar/@value='@action'"].any? { |expr| ast.xpath(expr) }
|
7
|
+
[file_match(filename)]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
rule "FC017", "LWRP does not notify when updated" do
|
2
|
+
tags %w{correctness lwrp}
|
3
|
+
provider do |ast, filename|
|
4
|
+
|
5
|
+
use_inline_resources = !ast.xpath('//*[self::vcall or self::var_ref]/ident
|
6
|
+
[@value="use_inline_resources"]').empty?
|
7
|
+
|
8
|
+
unless use_inline_resources
|
9
|
+
actions = ast.xpath('//method_add_block/command[ident/@value="action"]/
|
10
|
+
args_add_block/descendant::symbol/ident')
|
11
|
+
|
12
|
+
actions.reject do |action|
|
13
|
+
blk = action.xpath('ancestor::command[1]/
|
14
|
+
following-sibling::*[self::do_block or self::brace_block]')
|
15
|
+
empty = !blk.xpath("stmts_add/void_stmt").empty?
|
16
|
+
converge_by = !blk.xpath('descendant::*[self::command or self::fcall]
|
17
|
+
/ident[@value="converge_by"]').empty?
|
18
|
+
|
19
|
+
updated_by_last_action = !blk.xpath('descendant::*[self::call or
|
20
|
+
self::command_call]/*[self::vcall or self::var_ref/ident/
|
21
|
+
@value="new_resource"]/../ident[@value="updated_by_last_action"]
|
22
|
+
').empty?
|
23
|
+
|
24
|
+
empty || converge_by || updated_by_last_action
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|