cookstyle 6.4.4 → 6.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/config/cookstyle.yml +287 -12
  4. data/config/disable_all.yml +12 -0
  5. data/config/upstream.yml +82 -19
  6. data/lib/cookstyle.rb +1 -1
  7. data/lib/cookstyle/version.rb +2 -2
  8. data/lib/rubocop/chef/platform_helpers.rb +2 -1
  9. data/lib/rubocop/cop/chef/correctness/invalid_platform_family_values_in_case.rb +77 -0
  10. data/lib/rubocop/cop/chef/correctness/invalid_platform_values_in_case.rb +77 -0
  11. data/lib/rubocop/cop/chef/correctness/invalid_version_metadata.rb +1 -1
  12. data/lib/rubocop/cop/chef/correctness/lazy_eval_node_attribute_defaults.rb +56 -0
  13. data/lib/rubocop/cop/chef/correctness/openssl_password_helpers.rb +45 -0
  14. data/lib/rubocop/cop/chef/deprecation/deprecated_chefspec_platform.rb +10 -4
  15. data/lib/rubocop/cop/chef/deprecation/hwrp_without_provides.rb +141 -0
  16. data/lib/rubocop/cop/chef/deprecation/resource_uses_only_resource_name.rb +86 -0
  17. data/lib/rubocop/cop/chef/deprecation/ruby_27_keyword_argument_warnings.rb +59 -0
  18. data/lib/rubocop/cop/chef/deprecation/xml_ruby_recipe.rb +3 -3
  19. data/lib/rubocop/cop/chef/modernize/includes_mixin_shellout.rb +24 -3
  20. data/lib/rubocop/cop/chef/modernize/shell_out_helper.rb +64 -0
  21. data/lib/rubocop/cop/chef/modernize/use_multipackage_installs.rb +8 -4
  22. data/lib/rubocop/cop/chef/sharing/invalid_license_string.rb +1 -1
  23. data/lib/rubocop/monkey_patches/team.rb +24 -0
  24. metadata +13 -6
  25. data/lib/rubocop/cop/chef/deprecation/resource_without_name_or_provides.rb +0 -81
  26. data/lib/rubocop/monkey_patches/commissioner.rb +0 -26
@@ -36,7 +36,7 @@ module RuboCop
36
36
 
37
37
  def on_send(node)
38
38
  version?(node) do |ver|
39
- if ver.value !~ /\A\d+\.\d+(\.\d+)?\z/ # entirely borrowed from Foodcritic.
39
+ unless /\A\d+\.\d+(\.\d+)?\z/.match?(ver.value) # entirely borrowed from Foodcritic.
40
40
  add_offense(ver, location: :expression, message: MSG, severity: :refactor)
41
41
  end
42
42
  end
@@ -0,0 +1,56 @@
1
+ #
2
+ # Copyright:: 2020, Chef Software Inc.
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module RuboCop
19
+ module Cop
20
+ module Chef
21
+ module ChefCorrectness
22
+ # When setting a node attribute as the default value for a custom resource property, wrap the node attribute in `lazy {}` so that its value is available when the resource executes.
23
+ #
24
+ # @example
25
+ #
26
+ # # bad
27
+ # property :Something, String, default: node['hostname']
28
+ #
29
+ # # good
30
+ # property :Something, String, default: lazy { node['hostname'] }
31
+ #
32
+ class LazyEvalNodeAttributeDefaults < Cop
33
+ include RuboCop::Chef::CookbookHelpers
34
+
35
+ MSG = 'When setting a node attribute as the default value for a custom resource property, wrap the node attribute in `lazy {}` so that its value is available when the resource executes.'.freeze
36
+
37
+ def_node_matcher :non_lazy_node_attribute_default?, <<-PATTERN
38
+ (send nil? :property (sym _) ... (hash <(pair (sym :default) $(send (send _ :node) :[] _) ) ...>))
39
+ PATTERN
40
+
41
+ def on_send(node)
42
+ non_lazy_node_attribute_default?(node) do |default|
43
+ add_offense(default, location: :expression, message: MSG, severity: :refactor)
44
+ end
45
+ end
46
+
47
+ def autocorrect(node)
48
+ lambda do |corrector|
49
+ corrector.replace(node.loc.expression, "lazy { #{node.loc.expression.source} }")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,45 @@
1
+
2
+ #
3
+ # Copyright:: Copyright 2020, Chef Software Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ module RuboCop
18
+ module Cop
19
+ module Chef
20
+ module ChefCorrectness
21
+ # The openSSL cookbook provides a deprecated `secure_password` helper in the `Opscode::OpenSSL::Password` class, which should not longer be used. This helper would generate a random password that would be used when a data bag or attribute was no present. The practice of generating passwords to be stored on the node is bad security as it exposes the password to anyone that can view the nodes, and deleting a node deletes the password. Passwords should be retrieved from a secure source for use in cookbooks.
22
+ #
23
+ # # bad
24
+ # ::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)
25
+ # basic_auth_password = secure_password
26
+ #
27
+ class OpenSSLPasswordHelpers < Cop
28
+ MSG = 'The `secure_password` helper from the openssl cookbooks `Opscode::OpenSSL::Password` class should not be used to generate passwords.'.freeze
29
+
30
+ def_node_matcher :openssl_helper?, <<~PATTERN
31
+ (const
32
+ (const
33
+ (const nil? :Opscode) :OpenSSL) :Password)
34
+ PATTERN
35
+
36
+ def on_const(node)
37
+ openssl_helper?(node) do
38
+ add_offense(node, location: :expression, message: MSG, severity: :warning)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -47,22 +47,28 @@ module RuboCop
47
47
  '> 16.04, < 18.04' => true,
48
48
  },
49
49
  'fedora' => {
50
- '< 30' => '30',
50
+ '< 31' => '31',
51
51
  },
52
52
  'freebsd' => {
53
- '< 11' => '12',
53
+ '~> 11.0, < 11.2' => '11',
54
+ '= 12.0' => '12',
55
+ '< 11' => true,
54
56
  },
55
57
  'mac_os_x' => {
56
58
  '< 10.12' => '10.15',
57
59
  },
60
+ 'suse' => {
61
+ '~> 12.0, < 12.4' => '12',
62
+ '< 12' => true,
63
+ },
58
64
  'opensuse' => {
59
65
  '< 14' => true,
60
66
  '~> 42.0' => true,
61
67
  },
62
68
  'debian' => {
63
69
  '< 8' => true,
64
- '> 8.0, < 8.9' => '8',
65
- '> 9.0, < 9.8' => '9',
70
+ '> 8.0, < 8.10' => '8',
71
+ '> 9.0, < 9.9' => '9',
66
72
  },
67
73
  'centos' => {
68
74
  '< 6.0' => true,
@@ -0,0 +1,141 @@
1
+ #
2
+ # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module RuboCop
19
+ module Cop
20
+ module Chef
21
+ module ChefDeprecations
22
+ # Chef Infra Client 16 and later a legacy HWRP resource must use `provides` to define how the resource is called in recipes or other resources. To maintain compatibility with Chef Infra Client < 16 use both `resource_name` and `provides`.
23
+ #
24
+ # @example
25
+ #
26
+ # # bad
27
+ # class Chef
28
+ # class Resource
29
+ # class UlimitRule < Chef::Resource
30
+ # property :type, [Symbol, String], required: true
31
+ # property :item, [Symbol, String], required: true
32
+ #
33
+ # # additional resource code
34
+ # end
35
+ # end
36
+ # end
37
+ #
38
+ # # bad
39
+ # class Chef
40
+ # class Resource
41
+ # class UlimitRule < Chef::Resource
42
+ # resource_name :ulimit_rule
43
+ #
44
+ # property :type, [Symbol, String], required: true
45
+ # property :item, [Symbol, String], required: true
46
+ #
47
+ # # additional resource code
48
+ # end
49
+ # end
50
+ # end
51
+ #
52
+ # # good when Chef Infra Client < 15 (but compatible with 16+ as well)
53
+ # class Chef
54
+ # class Resource
55
+ # class UlimitRule < Chef::Resource
56
+ # resource_name :ulimit_rule
57
+ # provides :ulimit_rule
58
+ #
59
+ # property :type, [Symbol, String], required: true
60
+ # property :item, [Symbol, String], required: true
61
+ #
62
+ # # additional resource code
63
+ # end
64
+ # end
65
+ # end
66
+ #
67
+ # # good when Chef Infra Client 16+
68
+ # class Chef
69
+ # class Resource
70
+ # class UlimitRule < Chef::Resource
71
+ # provides :ulimit_rule
72
+ #
73
+ # property :type, [Symbol, String], required: true
74
+ # property :item, [Symbol, String], required: true
75
+ #
76
+ # # additional resource code
77
+ # end
78
+ # end
79
+ # end
80
+ #
81
+ # # better
82
+ # Convert your legacy HWRPs to custom resources
83
+ #
84
+ class HWRPWithoutProvides < Cop
85
+ MSG = 'In Chef Infra Client 16 and later a legacy HWRP resource must use `provides` to define how the resource is called in recipes or other resources. To maintain compatibility with Chef Infra Client < 16 use both `resource_name` and `provides`.'.freeze
86
+
87
+ def_node_matcher :HWRP?, <<-PATTERN
88
+ (class
89
+ (const nil? :Chef) nil?
90
+ (class
91
+ (const nil? :Resource) nil?
92
+ $(class
93
+ (const nil? ... )
94
+ (const
95
+ (const nil? :Chef) :Resource)
96
+ (begin ... ))))
97
+ PATTERN
98
+
99
+ def_node_search :provides, '(send nil? :provides (sym $_) ...)'
100
+ def_node_search :resource_name_ast, '$(send nil? :resource_name ...)'
101
+ def_node_search :resource_name, '(send nil? :resource_name (sym $_))'
102
+
103
+ def on_class(node)
104
+ HWRP?(node) do |inherit|
105
+ add_offense(inherit, location: :expression, message: MSG, severity: :warning) unless has_provides?
106
+ end
107
+ end
108
+
109
+ def has_provides?
110
+ provides_ast = provides(processed_source.ast)
111
+ return false if provides_ast.count == 0
112
+
113
+ resource_ast = resource_name(processed_source.ast)
114
+
115
+ if resource_ast.count == 0
116
+ true # no resource_name, but provides
117
+ else
118
+ # since we have a resource and provides make sure the there is a provides that
119
+ # matches the resource name
120
+ provides_ast.include?(resource_ast.first)
121
+ end
122
+ end
123
+
124
+ def indentation(node)
125
+ node.source_range.source_line =~ /\S/
126
+ end
127
+
128
+ def autocorrect(node)
129
+ lambda do |corrector|
130
+ resource_name_ast(node) do |ast_match|
131
+ # build a new string to add after that includes the new line and the proper indentation
132
+ new_string = "\n" + ast_match.source.dup.gsub('resource_name', 'provides').prepend(' ' * indentation(ast_match))
133
+ corrector.insert_after(ast_match.source_range, new_string)
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,86 @@
1
+ #
2
+ # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+ module RuboCop
18
+ module Cop
19
+ module Chef
20
+ module ChefDeprecations
21
+ # Starting with Chef Infra Client 16, using `resource_name` without also using `provides` will result in resource failures. Make sure to use both `resource_name` and `provides` to change the name of the resource. You can also omit `resource_name` entirely if the value set matches the name Chef Infra Client automatically assigns based on COOKBOOKNAME_FILENAME.
22
+ #
23
+ # @example
24
+ #
25
+ # # bad
26
+ # mycookbook/resources/myresource.rb:
27
+ # resource_name :mycookbook_myresource
28
+ #
29
+ class ResourceUsesOnlyResourceName < Cop
30
+ include RuboCop::Chef::CookbookHelpers
31
+ include RangeHelp
32
+
33
+ MSG = 'Starting with Chef Infra Client 16, using `resource_name` without also using `provides` will result in resource failures. Make sure to use both `resource_name` and `provides` to change the name of the resource. You can also omit `resource_name` entirely if the value set matches the name Chef Infra Client automatically assigns based on COOKBOOKNAME_FILENAME.'.freeze
34
+
35
+ def_node_matcher :resource_name?, '(send nil? :resource_name (sym $_ ))'
36
+
37
+ def_node_search :cb_name_match, '(send nil? :name (str $_))'
38
+
39
+ def_node_search :provides, '(send nil? :provides (sym $_) ...)'
40
+
41
+ # determine the cookbook name either by parsing metdata.rb or by parsing metata.json
42
+ #
43
+ # @returns [String] the cookbook name
44
+ def cookbook_name
45
+ cb_path = File.expand_path(File.join(processed_source.file_path, '../..'))
46
+
47
+ if File.exist?(File.join(cb_path, 'metadata.rb'))
48
+ cb_metadata_ast = ProcessedSource.from_file(File.join(cb_path, 'metadata.rb'), @config.target_ruby_version).ast
49
+ cb_name_match(cb_metadata_ast).first
50
+ elsif File.exist?(File.join(cb_path, 'metadata.json')) # this exists only for supermarket files that lack metadata.rb
51
+ JSON.parse(File.read(File.join(cb_path, 'metadata.json')))['name']
52
+ end
53
+ end
54
+
55
+ # given a resource name make sure there's a provides that matches that name
56
+ #
57
+ # @returns [TrueClass, FalseClass]
58
+ def valid_provides?(resource_name)
59
+ provides_ast = provides(processed_source.ast)
60
+ return false unless provides_ast
61
+
62
+ provides_ast.include?(resource_name)
63
+ end
64
+
65
+ def on_send(node)
66
+ resource_name?(node) do |r_name|
67
+ add_offense(node, location: :expression, message: MSG, severity: :warning) unless valid_provides?(r_name)
68
+ end
69
+ end
70
+
71
+ def autocorrect(node)
72
+ lambda do |corrector|
73
+ resource_name?(node) do |name|
74
+ if name.to_s == "#{cookbook_name}_#{File.basename(processed_source.path, '.rb')}"
75
+ corrector.remove(range_with_surrounding_space(range: node.loc.expression, side: :left))
76
+ else
77
+ corrector.insert_after(node.source_range, "\n#{node.source.gsub('resource_name', 'provides')}")
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,59 @@
1
+ #
2
+ # Copyright:: 2020, Chef Software, Inc.
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module RuboCop
19
+ module Cop
20
+ module Chef
21
+ module ChefDeprecations
22
+ # Pass options to shell_out helpers without the brackets to avoid Ruby 2.7 deprecation warnings.
23
+ #
24
+ # @example
25
+ #
26
+ # # bad
27
+ # shell_out!('hostnamectl status', { returns: [0, 1] })
28
+ # shell_out('hostnamectl status', { returns: [0, 1] })
29
+ #
30
+ # # good
31
+ # shell_out!('hostnamectl status', returns: [0, 1])
32
+ # shell_out('hostnamectl status', returns: [0, 1])
33
+ #
34
+ class Ruby27KeywordArgumentWarnings < Cop
35
+ include RuboCop::Chef::CookbookHelpers
36
+
37
+ MSG = 'Pass options to shell_out helpers without the brackets to avoid Ruby 2.7 deprecation warnings.'.freeze
38
+
39
+ def_node_matcher :positional_shellout?, <<-PATTERN
40
+ (send nil? {:shell_out :shell_out!} ... $(hash ... ))
41
+ PATTERN
42
+
43
+ def on_send(node)
44
+ positional_shellout?(node) do |h|
45
+ add_offense(h, location: :expression, message: MSG, severity: :refactor) if h.braces?
46
+ end
47
+ end
48
+
49
+ def autocorrect(node)
50
+ lambda do |corrector|
51
+ # @todo when we drop ruby 2.4 support we can convert to to just delete_prefix delete_suffix
52
+ corrector.replace(node.loc.expression, node.loc.expression.source.gsub(/^{/, '').gsub(/}$/, ''))
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: 2019, Chef Software, Inc.
2
+ # Copyright:: 2019-2020, Chef Software, Inc.
3
3
  # Author:: Tim Smith (<tsmith@chef.io>)
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +18,7 @@ module RuboCop
18
18
  module Cop
19
19
  module Chef
20
20
  module ChefDeprecations
21
- # Do not include the deprecated xml::ruby recipe to install the nokogiri gem.
22
- # Chef Infra Client 12 and later ships with nokogiri included.
21
+ # Do not include the deprecated xml::ruby recipe to install the nokogiri gem. Chef Infra Client 12 and later ships with nokogiri included.
23
22
  #
24
23
  # @example
25
24
  #
@@ -35,6 +34,7 @@ module RuboCop
35
34
 
36
35
  def on_send(node)
37
36
  xml_ruby_recipe?(node) do
37
+ node = node.parent if node.parent&.conditional? && node.parent&.single_line_condition? # make sure we catch any inline conditionals
38
38
  add_offense(node, location: :expression, message: MSG, severity: :warning)
39
39
  end
40
40
  end