cookstyle 5.15.7 → 5.16.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/config/cookstyle.yml +172 -4
  3. data/lib/cookstyle.rb +6 -0
  4. data/lib/cookstyle/version.rb +1 -1
  5. data/lib/rubocop/chef/cookbook_helpers.rb +12 -4
  6. data/lib/rubocop/cop/chef/correctness/dnf_package_allow_downgrades.rb +50 -0
  7. data/lib/rubocop/cop/chef/correctness/invalid_notification_timing.rb +53 -0
  8. data/lib/rubocop/cop/chef/correctness/malformed_value_for_platform.rb +67 -0
  9. data/lib/rubocop/cop/chef/correctness/notifies_action_not_symbol.rb +11 -3
  10. data/lib/rubocop/cop/chef/deprecation/chef_rewind.rb +6 -3
  11. data/lib/rubocop/cop/chef/deprecation/depends_compat_resource.rb +4 -0
  12. data/lib/rubocop/cop/chef/deprecation/deprecated_platform_methods.rb +56 -0
  13. data/lib/rubocop/cop/chef/deprecation/legacy_notify_syntax.rb +11 -3
  14. data/lib/rubocop/cop/chef/deprecation/name_property_and_default.rb +18 -22
  15. data/lib/rubocop/cop/chef/deprecation/ruby_block_create_action.rb +64 -0
  16. data/lib/rubocop/cop/chef/modernize/apt_default_recipe.rb +5 -2
  17. data/lib/rubocop/cop/chef/modernize/chef_14_resources.rb +4 -0
  18. data/lib/rubocop/cop/chef/modernize/cron_manage_resource.rb +4 -0
  19. data/lib/rubocop/cop/chef/modernize/depends_zypper_cookbook.rb +4 -0
  20. data/lib/rubocop/cop/chef/modernize/execute_sc_exe.rb +66 -0
  21. data/lib/rubocop/cop/chef/modernize/execute_sleep.rb +77 -0
  22. data/lib/rubocop/cop/chef/modernize/execute_tzutil.rb +3 -0
  23. data/lib/rubocop/cop/chef/modernize/foodcritic_comments.rb +51 -0
  24. data/lib/rubocop/cop/chef/modernize/libarchive_file.rb +4 -0
  25. data/lib/rubocop/cop/chef/modernize/macos_user_defaults.rb +4 -0
  26. data/lib/rubocop/cop/chef/modernize/openssl_rsa_key_resource.rb +4 -0
  27. data/lib/rubocop/cop/chef/modernize/openssl_x509_resource.rb +4 -0
  28. data/lib/rubocop/cop/chef/modernize/powershell_expand_archive.rb +3 -0
  29. data/lib/rubocop/cop/chef/modernize/powershell_guard_interpreter.rb +3 -0
  30. data/lib/rubocop/cop/chef/modernize/powershell_install_package.rb +3 -0
  31. data/lib/rubocop/cop/chef/modernize/powershell_install_windowsfeature.rb +3 -0
  32. data/lib/rubocop/cop/chef/modernize/property_with_name_attribute.rb +13 -15
  33. data/lib/rubocop/cop/chef/modernize/respond_to_metadata.rb +4 -0
  34. data/lib/rubocop/cop/chef/modernize/sc_windows_resource.rb +49 -0
  35. data/lib/rubocop/cop/chef/modernize/seven_zip_archive.rb +4 -0
  36. data/lib/rubocop/cop/chef/modernize/systctl_param_resource.rb +4 -2
  37. data/lib/rubocop/cop/chef/modernize/whyrun_supported_true.rb +4 -0
  38. data/lib/rubocop/cop/chef/modernize/windows_default_recipe.rb +1 -2
  39. data/lib/rubocop/cop/chef/modernize/windows_zipfile.rb +4 -0
  40. data/lib/rubocop/cop/chef/modernize/zipfile_resource.rb +3 -0
  41. data/lib/rubocop/cop/chef/modernize/zypper_repo.rb +4 -0
  42. data/lib/rubocop/cop/chef/redundant/custom_resource_with_allowed_actions.rb +1 -1
  43. data/lib/rubocop/cop/chef/redundant/long_description_metadata.rb +0 -1
  44. data/lib/rubocop/cop/chef/redundant/sensitive_property_in_resource.rb +48 -0
  45. data/lib/rubocop/cop/chef/redundant/unnecessary_desired_state.rb +57 -0
  46. data/lib/rubocop/cop/chef/redundant/unnecessary_name_property.rb +10 -7
  47. data/lib/rubocop/cop/chef/style/immediate_notification_timing.rb +59 -0
  48. data/lib/rubocop/cop/chef/style/true_false_resource_properties.rb +55 -0
  49. data/lib/rubocop/cop/chef/style/unnecessary_platform_case_statement.rb +90 -0
  50. data/lib/rubocop/cop/chef/style/use_platform_helpers.rb +21 -5
  51. data/lib/rubocop/cop/target_chef_version.rb +18 -0
  52. data/lib/rubocop/monkey_patches/commissioner.rb +26 -0
  53. data/lib/rubocop/monkey_patches/config.rb +15 -0
  54. data/lib/rubocop/monkey_patches/cop.rb +10 -0
  55. metadata +20 -2
@@ -9,6 +9,11 @@ require 'rubocop'
9
9
  require 'rubocop/monkey_patches/comment_config.rb'
10
10
  require 'rubocop/monkey_patches/json_formatter.rb'
11
11
 
12
+ # monkey patches needed for the TargetChefVersion config option
13
+ require 'rubocop/monkey_patches/config.rb'
14
+ require 'rubocop/monkey_patches/cop.rb'
15
+ require 'rubocop/monkey_patches/commissioner.rb'
16
+
12
17
  module RuboCop
13
18
  class ConfigLoader
14
19
  RUBOCOP_HOME.gsub!(
@@ -36,6 +41,7 @@ require 'rubocop/chef'
36
41
  require 'rubocop/chef/cookbook_helpers'
37
42
  require 'rubocop/chef/platform_helpers'
38
43
  require 'rubocop/chef/cookbook_only'
44
+ require 'rubocop/cop/target_chef_version'
39
45
 
40
46
  # Chef specific cops
41
47
  Dir.glob(File.dirname(__FILE__) + '/rubocop/cop/chef/**/*.rb') do |file|
@@ -1,4 +1,4 @@
1
1
  module Cookstyle
2
- VERSION = "5.15.7".freeze # rubocop: disable Style/StringLiterals
2
+ VERSION = "5.16.10".freeze # rubocop: disable Style/StringLiterals
3
3
  RUBOCOP_VERSION = '0.75.1'.freeze
4
4
  end
@@ -40,27 +40,28 @@ module RuboCop
40
40
  # Match particular properties within a resource
41
41
  #
42
42
  # @param [String] resource_name The name of the resource to match
43
- # @param [String] property_name The name of the property to match (or action)
43
+ # @param [String] property_names The name of the property to match (or action)
44
44
  # @param [RuboCop::AST::Node] node The rubocop ast node to search
45
45
  #
46
46
  # @yield
47
47
  #
48
- def match_property_in_resource?(resource_name, property_name, node)
48
+ def match_property_in_resource?(resource_name, property_names, node)
49
49
  return unless looks_like_resource?(node)
50
50
  # bail out if we're not in the resource we care about or nil was passed (all resources)
51
51
  return unless resource_name.nil? || node.children.first.method?(resource_name.to_sym) # see if we're in the right resource
52
52
 
53
53
  resource_block = node.children[2] # the 3rd child is the actual block in the resource
54
54
  return unless resource_block # nil would be an empty block
55
+
55
56
  if resource_block.begin_type? # if begin_type we need to iterate over the children
56
57
  resource_block.children.each do |resource_blk_child|
57
58
  extract_send_types(resource_blk_child) do |p|
58
- yield(p) if p.method_name == property_name.to_sym
59
+ yield(p) if symbolized_property_types(property_names).include?(p.method_name)
59
60
  end
60
61
  end
61
62
  else # there's only a single property to check
62
63
  extract_send_types(resource_block) do |p|
63
- yield(p) if p.method_name == property_name.to_sym
64
+ yield(p) if symbolized_property_types(property_names).include?(p.method_name)
64
65
  end
65
66
  end
66
67
  end
@@ -75,6 +76,13 @@ module RuboCop
75
76
 
76
77
  private
77
78
 
79
+ # @param [String, Array] property
80
+ #
81
+ # @return [Array]
82
+ def symbolized_property_types(property)
83
+ Array(property).map(&:to_sym)
84
+ end
85
+
78
86
  #
79
87
  # given a node object does it look like a chef resource or not?
80
88
  # warning: currently this requires a resource with properties since we key off blocks and property-less resources look like methods
@@ -0,0 +1,50 @@
1
+ #
2
+ # Copyright:: Copyright 2019, 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 ChefCorrectness
21
+ # dnf_package does not support the allow_downgrades property
22
+ #
23
+ # @example
24
+ #
25
+ # # bad
26
+ # dnf_package 'nginx' do
27
+ # version '1.2.3'
28
+ # allow_downgrades true
29
+ # end
30
+ #
31
+ # # good
32
+ # dnf_package 'nginx' do
33
+ # version '1.2.3'
34
+ # end
35
+ #
36
+ class DnfPackageAllowDowngrades < Cop
37
+ include RuboCop::Chef::CookbookHelpers
38
+
39
+ MSG = 'dnf_package does not support the allow_downgrades property'.freeze
40
+
41
+ def on_block(node)
42
+ match_property_in_resource?(:dnf_package, :allow_downgrades, node) do |prop|
43
+ add_offense(prop, location: :expression, message: MSG, severity: :refactor)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,53 @@
1
+ #
2
+ # Copyright:: 2019, 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 ChefCorrectness
21
+ # Valid notification timings are :immediately, :immediate (alias for :immediately), :delayed, and :before.
22
+ #
23
+ # @example
24
+ #
25
+ # # bad
26
+ #
27
+ # template '/etc/www/configures-apache.conf' do
28
+ # notifies :restart, 'service[apache]', :nope
29
+ # end
30
+ #
31
+ # # good
32
+ #
33
+ # template '/etc/www/configures-apache.conf' do
34
+ # notifies :restart, 'service[apache]', :immediately
35
+ # end
36
+ #
37
+ class InvalidNotificationTiming < Cop
38
+ MSG = 'Valid notification timings are :immediately, :immediate (alias for :immediately), :delayed, and :before.'.freeze
39
+
40
+ def_node_matcher :notification_with_timing?, <<-PATTERN
41
+ (send nil? {:notifies :subscribes} (sym _) (...) $(sym _))
42
+ PATTERN
43
+
44
+ def on_send(node)
45
+ notification_with_timing?(node) do |timing|
46
+ add_offense(timing, location: :expression, message: MSG, severity: :refactor) unless %i(immediate immediately delayed before).include?(timing.value)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Copyright:: Copyright 2019, 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 ChefCorrectness
21
+ # When using the value_for_platform helper you must include a hash of possible platforms where each platform contains a hash of versions and potential values. If you don't wish to match on a particular version you can instead use the key 'default'.
22
+ #
23
+ # @example
24
+ #
25
+ # # bad
26
+ # value_for_platform(
27
+ # %w(redhat oracle) => 'baz'
28
+ # )
29
+ #
30
+ # # good
31
+ # value_for_platform(
32
+ # %w(redhat oracle) => {
33
+ # '5' => 'foo',
34
+ # '6' => 'bar',
35
+ # 'default'd => 'baz',
36
+ # }
37
+ # )
38
+ #
39
+ # value_for_platform(
40
+ # %w(redhat oracle) => {
41
+ # 'default' => 'foo',
42
+ # },
43
+ # 'default' => 'bar'
44
+ # )
45
+ #
46
+ class MalformedPlatformValueForPlatformHelper < Cop
47
+ def on_send(node)
48
+ return unless node.method_name == :value_for_platform
49
+
50
+ if node.arguments.count > 1
51
+ msg = 'Malformed value_for_platform helper argument. The value_for_platform helper takes a single hash of platforms as an argument.'
52
+ add_offense(node, location: :expression, message: msg, severity: :refactor)
53
+ elsif node.arguments.first.hash_type? # if it's a variable we can't check what's in that variable so skip
54
+ msg = "Malformed value_for_platform helper argument. The value for each platform in your hash must be a hash of either platform version strings or a value with a key of 'default'"
55
+ node.arguments.first.each_pair do |plats, plat_vals|
56
+ # instead of a platform the hash key can be default with a value of anything. Depending on the hash format this is a string or symbol
57
+ unless plat_vals.hash_type? || plats == s(:str, 'default') || plats == s(:sym, :default)
58
+ add_offense(plat_vals, location: :expression, message: msg, severity: :refactor)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  module Cop
20
20
  module Chef
21
21
  module ChefCorrectness
22
- # When notifying an action within a resource the action should always be a symbol. In Chef Infra Client releases before 14.0 this may result in double notification.
22
+ # When notifying or subscribing an action within a resource the action should always be a symbol. In Chef Infra Client releases before 14.0 this may result in double notification.
23
23
  #
24
24
  # @example
25
25
  #
@@ -28,18 +28,26 @@ module RuboCop
28
28
  # notifies 'restart', 'service[httpd]', 'delayed'
29
29
  # end
30
30
  #
31
+ # execute 'some commmand' do
32
+ # subscribes 'restart', 'service[httpd]', 'delayed'
33
+ # end
34
+ #
31
35
  # # good
32
36
  # execute 'some commmand' do
33
37
  # notifies :restart, 'service[httpd]', 'delayed'
34
38
  # end
35
39
  #
40
+ # execute 'some commmand' do
41
+ # subscribes :restart, 'service[httpd]', 'delayed'
42
+ # end
43
+ #
36
44
  class NotifiesActionNotSymbol < Cop
37
45
  include RuboCop::Chef::CookbookHelpers
38
46
 
39
- MSG = 'Resource notifcation actions should be symbols not strings.'.freeze
47
+ MSG = 'Resource notification and subscription actions should be symbols not strings.'.freeze
40
48
 
41
49
  def on_block(node)
42
- match_property_in_resource?(nil, 'notifies', node) do |notifies_property|
50
+ match_property_in_resource?(nil, %w(notifies subscribes), node) do |notifies_property|
43
51
  add_offense(notifies_property, location: :expression, message: MSG, severity: :refactor) if notifies_property.node_parts[2].str_type?
44
52
  end
45
53
  end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  module Cop
20
20
  module Chef
21
21
  module ChefDeprecations
22
- # Use delete_resource / edit_resource instead of functionality in the deprecated chef-rewind gem
22
+ # Use delete_resource / edit_resource introduced in Chef Infra Client 12.10 instead of functionality in the deprecated chef-rewind gem
23
23
  #
24
24
  # @example
25
25
  #
@@ -29,20 +29,23 @@ module RuboCop
29
29
  #
30
30
  # rewind "user[postgres]" do
31
31
  # home '/var/lib/pgsql/9.2'
32
- # cookbook 'my-postgresql' # or `cookbook cookbook_name()`
32
+ # cookbook 'my-postgresql'
33
33
  # end
34
34
  #
35
35
  # unwind "user[postgres]"
36
36
  #
37
37
  class ChefRewind < Cop
38
38
  include RuboCop::Chef::CookbookHelpers
39
+ extend TargetChefVersion
40
+
41
+ minimum_target_chef_version '12.10'
39
42
 
40
43
  MAPPING = {
41
44
  rewind: 'edit_resource',
42
45
  unwind: 'delete_resource',
43
46
  }.freeze
44
47
 
45
- MSG = 'Use delete_resource / edit_resource instead of functionality in the deprecated chef-rewind gem'.freeze
48
+ MSG = 'Use delete_resource / edit_resource introduced in Chef Infra Client 12.10 instead of functionality in the deprecated chef-rewind gem'.freeze
46
49
 
47
50
  def_node_matcher :rewind_gem_install?, <<-PATTERN
48
51
  (send nil? :chef_gem (str "chef-rewind"))
@@ -26,6 +26,10 @@ module RuboCop
26
26
  # depends 'compat_resource'
27
27
  #
28
28
  class CookbookDependsOnCompatResource < Cop
29
+ extend TargetChefVersion
30
+
31
+ minimum_target_chef_version '12.19'
32
+
29
33
  MSG = "Don't depend on the deprecated compat_resource cookbook made obsolete by Chef 12.19+".freeze
30
34
 
31
35
  def_node_matcher :depends_compat_resource?, <<-PATTERN
@@ -0,0 +1,56 @@
1
+ #
2
+ # Copyright:: 2019, 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
+ # Use provider_for_action instead of the deprecated Chef::Platform methods in resources, which were removed in Chef Infra Client 13.
23
+ #
24
+ # @example
25
+ #
26
+ # # bad
27
+ # resource = Chef::Resource::File.new("/tmp/foo.xyz", run_context)
28
+ # provider = Chef::Platform.provider_for_resource(resource, :create)
29
+ #
30
+ # resource = Chef::Resource::File.new("/tmp/foo.xyz", run_context)
31
+ # provider = Chef::Platform.find_provider("ubuntu", "16.04", resource)
32
+ #
33
+ # resource = Chef::Resource::File.new("/tmp/foo.xyz", run_context)
34
+ # provider = Chef::Platform.find_provider_for_node(node, resource)
35
+ #
36
+ # # good
37
+ # resource = Chef::Resource::File.new("/tmp/foo.xyz", run_context)
38
+ # provider = resource.provider_for_action(:create)
39
+ #
40
+ class DeprecatedPlatformMethods < Cop
41
+ MSG = 'Use provider_for_action instead of the deprecated Chef::Platform methods in resources, which were removed in Chef Infra Client 13.'.freeze
42
+
43
+ def_node_matcher :platform_method?, <<-PATTERN
44
+ (send (const (const nil? :Chef) :Platform) {:provider_for_resource :find_provider :find_provider_for_node} ... )
45
+ PATTERN
46
+
47
+ def on_send(node)
48
+ platform_method?(node) do
49
+ add_offense(node, location: :expression, message: MSG, severity: :refactor)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -35,6 +35,10 @@ module RuboCop
35
35
  # notifies :restart, resources(service: service_name_variable), :immediately
36
36
  # end
37
37
  #
38
+ # template '/etc/www/configures-apache.conf' do
39
+ # subscribes :restart, resources(service: service_name_variable), :immediately
40
+ # end
41
+ #
38
42
  # # good
39
43
  # template '/etc/www/configures-apache.conf' do
40
44
  # notifies :restart, 'service[apache]'
@@ -48,11 +52,15 @@ module RuboCop
48
52
  # notifies :restart, "service[#{service_name_variable}]", :immediately
49
53
  # end
50
54
  #
55
+ # template '/etc/www/configures-apache.conf' do
56
+ # subscribes :restart, "service[#{service_name_variable}]", :immediately
57
+ # end
58
+ #
51
59
  class LegacyNotifySyntax < Cop
52
60
  MSG = 'Use the new-style notification syntax which allows you to notify resources defined later in a recipe or resource.'.freeze
53
61
 
54
62
  def_node_matcher :legacy_notify?, <<-PATTERN
55
- (send nil? :notifies $(sym _) (send nil? :resources (hash (pair $(sym _) $(...) ) ) ) $... )
63
+ (send nil? ${:notifies :subscribes} $(sym _) (send nil? :resources (hash (pair $(sym _) $(...) ) ) ) $... )
56
64
  PATTERN
57
65
 
58
66
  def on_send(node)
@@ -63,7 +71,7 @@ module RuboCop
63
71
 
64
72
  def autocorrect(node)
65
73
  lambda do |corrector|
66
- legacy_notify?(node) do |action, type, name, timing|
74
+ legacy_notify?(node) do |notify_type, action, type, name, timing|
67
75
  service_value = case name.type
68
76
  when :str
69
77
  "'#{type.source}[#{name.value}]'"
@@ -72,7 +80,7 @@ module RuboCop
72
80
  else
73
81
  "\"#{type.source}[\#{#{name.source}}]\""
74
82
  end
75
- new_val = "notifies #{action.source}, #{service_value}"
83
+ new_val = "#{notify_type} #{action.source}, #{service_value}"
76
84
  new_val << ", #{timing.first.source}" unless timing.empty?
77
85
  corrector.replace(node.loc.expression, new_val)
78
86
  end
@@ -18,46 +18,42 @@ module RuboCop
18
18
  module Cop
19
19
  module Chef
20
20
  module ChefDeprecations
21
- # A custom resource property can't be marked as a name_property and also have a default value. The name property is a special property that is derived from the name of the resource block in and thus always has a value passed to the resource. For example if you define `my_resource 'foo'` in recipe, then the name property of `my_resource` will automatically be set to `foo`. Setting a property to be both a name_property and have a default value will cause Chef Infra Client failures in 13.0 and later releases.
21
+ # A resource property (or attribute) can't be marked as a name_property (or name_attribute) and also have a default value. The name property is a special property that is derived from the name of the resource block in and thus always has a value passed to the resource. For example if you define `my_resource 'foo'` in recipe, then the name property of `my_resource` will automatically be set to `foo`. Setting a property to be both a name_property and have a default value will cause Chef Infra Client failures in 13.0 and later releases.
22
22
  #
23
23
  # @example
24
24
  #
25
25
  # # bad
26
26
  # property :config_file, String, default: 'foo', name_property: true
27
+ # attribute :config_file, String, default: 'foo', name_attribute: true
27
28
  #
28
29
  # # good
29
30
  # property :config_file, String, name_property: true
31
+ # attribute :config_file, String, name_attribute: true
30
32
  #
31
33
  class NamePropertyWithDefaultValue < Cop
34
+ include RangeHelp
35
+
32
36
  MSG = "A resource property can't be marked as a name_property and also have a default value. This will fail in Chef Infra Client 13 or later.".freeze
33
37
 
38
+ # match on a property or attribute that has any name and any type and a hash that
39
+ # contains name_property/name_attribute true and any default value. These are wrapped in
40
+ # <> which means the order doesn't matter in the hash.
41
+ def_node_matcher :name_property_with_default?, <<-PATTERN
42
+ (send nil? {:property :attribute} (sym _) ... (hash <(pair (sym {:name_property :name_attribute}) (true)) $(pair (sym :default) ...) ...>))
43
+ PATTERN
44
+
34
45
  def on_send(node)
35
- if default_value?(node) && property_is_name_property?(node)
46
+ name_property_with_default?(node) do
36
47
  add_offense(node, location: :expression, message: MSG, severity: :refactor)
37
48
  end
38
49
  end
39
50
 
40
- private
41
-
42
- def property_is_name_property?(node)
43
- if node.method_name == :property
44
- node.arguments.each do |arg|
45
- if arg.type == :hash
46
- return true if arg.source.match?(/name_property:\s*true/)
47
- end
48
- end
49
- false # no required: true found
50
- end
51
- end
52
-
53
- def default_value?(node)
54
- if node.method_name == :property
55
- node.arguments.each do |arg|
56
- if arg.type == :hash
57
- return true if arg.source.match?(/default:\s/)
58
- end
51
+ def autocorrect(node)
52
+ lambda do |corrector|
53
+ name_property_with_default?(node) do |default|
54
+ range = range_with_surrounding_comma(range_with_surrounding_space(range: default.loc.expression, side: :left), :left)
55
+ corrector.remove(range)
59
56
  end
60
- false # no default: found
61
57
  end
62
58
  end
63
59
  end