cookstyle 5.15.7 → 5.16.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/cookstyle.yml +172 -4
- data/lib/cookstyle.rb +6 -0
- data/lib/cookstyle/version.rb +1 -1
- data/lib/rubocop/chef/cookbook_helpers.rb +12 -4
- data/lib/rubocop/cop/chef/correctness/dnf_package_allow_downgrades.rb +50 -0
- data/lib/rubocop/cop/chef/correctness/invalid_notification_timing.rb +53 -0
- data/lib/rubocop/cop/chef/correctness/malformed_value_for_platform.rb +67 -0
- data/lib/rubocop/cop/chef/correctness/notifies_action_not_symbol.rb +11 -3
- data/lib/rubocop/cop/chef/deprecation/chef_rewind.rb +6 -3
- data/lib/rubocop/cop/chef/deprecation/depends_compat_resource.rb +4 -0
- data/lib/rubocop/cop/chef/deprecation/deprecated_platform_methods.rb +56 -0
- data/lib/rubocop/cop/chef/deprecation/legacy_notify_syntax.rb +11 -3
- data/lib/rubocop/cop/chef/deprecation/name_property_and_default.rb +18 -22
- data/lib/rubocop/cop/chef/deprecation/ruby_block_create_action.rb +64 -0
- data/lib/rubocop/cop/chef/modernize/apt_default_recipe.rb +5 -2
- data/lib/rubocop/cop/chef/modernize/chef_14_resources.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/cron_manage_resource.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/depends_zypper_cookbook.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/execute_sc_exe.rb +66 -0
- data/lib/rubocop/cop/chef/modernize/execute_sleep.rb +77 -0
- data/lib/rubocop/cop/chef/modernize/execute_tzutil.rb +3 -0
- data/lib/rubocop/cop/chef/modernize/foodcritic_comments.rb +51 -0
- data/lib/rubocop/cop/chef/modernize/libarchive_file.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/macos_user_defaults.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/openssl_rsa_key_resource.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/openssl_x509_resource.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/powershell_expand_archive.rb +3 -0
- data/lib/rubocop/cop/chef/modernize/powershell_guard_interpreter.rb +3 -0
- data/lib/rubocop/cop/chef/modernize/powershell_install_package.rb +3 -0
- data/lib/rubocop/cop/chef/modernize/powershell_install_windowsfeature.rb +3 -0
- data/lib/rubocop/cop/chef/modernize/property_with_name_attribute.rb +13 -15
- data/lib/rubocop/cop/chef/modernize/respond_to_metadata.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/sc_windows_resource.rb +49 -0
- data/lib/rubocop/cop/chef/modernize/seven_zip_archive.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/systctl_param_resource.rb +4 -2
- data/lib/rubocop/cop/chef/modernize/whyrun_supported_true.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/windows_default_recipe.rb +1 -2
- data/lib/rubocop/cop/chef/modernize/windows_zipfile.rb +4 -0
- data/lib/rubocop/cop/chef/modernize/zipfile_resource.rb +3 -0
- data/lib/rubocop/cop/chef/modernize/zypper_repo.rb +4 -0
- data/lib/rubocop/cop/chef/redundant/custom_resource_with_allowed_actions.rb +1 -1
- data/lib/rubocop/cop/chef/redundant/long_description_metadata.rb +0 -1
- data/lib/rubocop/cop/chef/redundant/sensitive_property_in_resource.rb +48 -0
- data/lib/rubocop/cop/chef/redundant/unnecessary_desired_state.rb +57 -0
- data/lib/rubocop/cop/chef/redundant/unnecessary_name_property.rb +10 -7
- data/lib/rubocop/cop/chef/style/immediate_notification_timing.rb +59 -0
- data/lib/rubocop/cop/chef/style/true_false_resource_properties.rb +55 -0
- data/lib/rubocop/cop/chef/style/unnecessary_platform_case_statement.rb +90 -0
- data/lib/rubocop/cop/chef/style/use_platform_helpers.rb +21 -5
- data/lib/rubocop/cop/target_chef_version.rb +18 -0
- data/lib/rubocop/monkey_patches/commissioner.rb +26 -0
- data/lib/rubocop/monkey_patches/config.rb +15 -0
- data/lib/rubocop/monkey_patches/cop.rb +10 -0
- metadata +20 -2
@@ -34,6 +34,10 @@ module RuboCop
|
|
34
34
|
# chef_version '>= 13'
|
35
35
|
#
|
36
36
|
class RespondToInMetadata < Cop
|
37
|
+
extend TargetChefVersion
|
38
|
+
|
39
|
+
minimum_target_chef_version '12.15'
|
40
|
+
|
37
41
|
MSG = 'It is no longer necessary to use respond_to? or if_defined? in metadata.rb in Chef Infra Client 12.15 and later'.freeze
|
38
42
|
|
39
43
|
def on_if(node)
|
@@ -0,0 +1,49 @@
|
|
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 ChefModernize
|
21
|
+
# The sc_windows resource from the sc cookbook allowed for the creation of windows services on legacy Chef Infra Client releases. Chef Infra Client 14.0 and later includes :create, :delete, and :configure actions without the need for additional cookbook dependencies. See the windows_service documentation at https://docs.chef.io/resource_windows_service.html for additional details on creating services with the windows_service resource.
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# sc_windows 'chef-client' do
|
25
|
+
# path "C:\\opscode\\chef\\bin"
|
26
|
+
# action :create
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# windows_service 'chef-client' do
|
31
|
+
# action :create
|
32
|
+
# binary_path_name "C:\\opscode\\chef\\bin"
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
class WindowsScResource < Cop
|
36
|
+
extend TargetChefVersion
|
37
|
+
|
38
|
+
minimum_target_chef_version '14.0'
|
39
|
+
|
40
|
+
MSG = 'Chef Infra Client 14.0 and later includes :create, :delete, and :configure actions without the need for the sc cookbook dependency. See the windows_service documentation at https://docs.chef.io/resource_windows_service.html for additional details.'.freeze
|
41
|
+
|
42
|
+
def on_send(node)
|
43
|
+
add_offense(node, location: :expression, message: MSG, severity: :refactor) if node.method_name == :sc_windows
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -29,6 +29,10 @@ module RuboCop
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
class SevenZipArchiveResource < Cop
|
32
|
+
extend TargetChefVersion
|
33
|
+
|
34
|
+
minimum_target_chef_version '15.0'
|
35
|
+
|
32
36
|
MSG = 'Use the archive_file resource built into Chef Infra Client 15+ instead of the seven_zip_archive'.freeze
|
33
37
|
|
34
38
|
def on_send(node)
|
@@ -18,8 +18,7 @@ module RuboCop
|
|
18
18
|
module Cop
|
19
19
|
module Chef
|
20
20
|
module ChefModernize
|
21
|
-
# The sysctl_param resource was renamed to sysctl when it was added to Chef Infra Client
|
22
|
-
# 14.0. The new resource name should be used.
|
21
|
+
# The sysctl_param resource was renamed to sysctl when it was added to Chef Infra Client 14.0. The new resource name should be used.
|
23
22
|
#
|
24
23
|
# # bad
|
25
24
|
# sysctl_param 'fs.aio-max-nr' do
|
@@ -33,6 +32,9 @@ module RuboCop
|
|
33
32
|
#
|
34
33
|
class SysctlParamResource < Cop
|
35
34
|
include RuboCop::Chef::CookbookHelpers
|
35
|
+
extend TargetChefVersion
|
36
|
+
|
37
|
+
minimum_target_chef_version '14.0'
|
36
38
|
|
37
39
|
MSG = 'The sysctl_param resource was renamed to sysctl when it was added to Chef Infra Client 14.0. The new resource name should be used.'.freeze
|
38
40
|
|
@@ -28,6 +28,10 @@ module RuboCop
|
|
28
28
|
# end
|
29
29
|
#
|
30
30
|
class WhyRunSupportedTrue < Cop
|
31
|
+
extend TargetChefVersion
|
32
|
+
|
33
|
+
minimum_target_chef_version '13.0'
|
34
|
+
|
31
35
|
MSG = 'whyrun_supported? no longer needs to be set to true as it is the default in Chef Infra Client 13+'.freeze
|
32
36
|
|
33
37
|
def on_def(node)
|
@@ -18,8 +18,7 @@ module RuboCop
|
|
18
18
|
module Cop
|
19
19
|
module Chef
|
20
20
|
module ChefModernize
|
21
|
-
# Don't include the windows default recipe that is either full of gem install that are part
|
22
|
-
# of the Chef Infra Client, or empty (depends on version).
|
21
|
+
# Don't include the windows default recipe that is either full of gem install that are part of the Chef Infra Client, or empty (depends on version).
|
23
22
|
#
|
24
23
|
# @example
|
25
24
|
#
|
@@ -28,6 +28,10 @@ module RuboCop
|
|
28
28
|
# end
|
29
29
|
#
|
30
30
|
class WindowsZipfileUsage < Cop
|
31
|
+
extend TargetChefVersion
|
32
|
+
|
33
|
+
minimum_target_chef_version '15.0'
|
34
|
+
|
31
35
|
MSG = 'Use the archive_file resource built into Chef Infra Client 15+ instead of the windows_zipfile from the Windows cookbook'.freeze
|
32
36
|
|
33
37
|
def on_send(node)
|
@@ -30,6 +30,9 @@ module RuboCop
|
|
30
30
|
#
|
31
31
|
class ZipfileResource < Cop
|
32
32
|
include RuboCop::Chef::CookbookHelpers
|
33
|
+
extend TargetChefVersion
|
34
|
+
|
35
|
+
minimum_target_chef_version '15.0'
|
33
36
|
|
34
37
|
MSG = 'Use the archive_file resource built into Chef Infra Client 15+ instead of the zipfile resource from the zipfile cookbook.'.freeze
|
35
38
|
|
@@ -39,6 +39,10 @@ module RuboCop
|
|
39
39
|
# end
|
40
40
|
#
|
41
41
|
class UsesZypperRepo < Cop
|
42
|
+
extend TargetChefVersion
|
43
|
+
|
44
|
+
minimum_target_chef_version '13.3'
|
45
|
+
|
42
46
|
MSG = 'The zypper_repo resource was renamed zypper_repository when it was added to Chef Infra Client 13.3.'.freeze
|
43
47
|
|
44
48
|
def on_send(node)
|
@@ -18,7 +18,7 @@
|
|
18
18
|
module RuboCop
|
19
19
|
module Cop
|
20
20
|
module Chef
|
21
|
-
module
|
21
|
+
module ChefRedundantCode
|
22
22
|
# It is not necessary to set `actions` or `allowed_actions` in custom resources as Chef Infra Client determines these automatically from the set of all actions defined in the resource.
|
23
23
|
#
|
24
24
|
# @example
|
@@ -0,0 +1,48 @@
|
|
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 ChefRedundantCode
|
21
|
+
# Every Chef Infra resources already include a sensitive property with a default value of false.
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# property :sensitive, [true, false], default: false
|
25
|
+
#
|
26
|
+
class SensitivePropertyInResource < Cop
|
27
|
+
MSG = 'Every Chef Infra resources already include a sensitive property with a default value of false.'.freeze
|
28
|
+
|
29
|
+
def_node_matcher :sensitive_property?, <<-PATTERN
|
30
|
+
(send nil? {:property :attribute} (sym :sensitive) ... (hash (pair (sym :default) (false))))
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_send(node)
|
34
|
+
if sensitive_property?(node)
|
35
|
+
add_offense(node, location: :expression, message: MSG, severity: :refactor)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def autocorrect(node)
|
40
|
+
lambda do |corrector|
|
41
|
+
corrector.remove(node.source_range)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,57 @@
|
|
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 ChefRedundantCode
|
21
|
+
# There is no need to set a property to desired_state: true as all properties have a desired_state of true by default.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# property :foo, String, desired_state: true
|
27
|
+
#
|
28
|
+
class UnnecessaryDesiredState < Cop
|
29
|
+
include RangeHelp
|
30
|
+
|
31
|
+
MSG = 'There is no need to set a property to desired_state: true as all properties have a desired_state of true by default.'.freeze
|
32
|
+
|
33
|
+
def_node_matcher :property?, <<-PATTERN
|
34
|
+
(send nil? {:property :attribute} (sym _) ... $(hash ...))
|
35
|
+
PATTERN
|
36
|
+
|
37
|
+
def on_send(node)
|
38
|
+
property?(node) do |hash_vals|
|
39
|
+
hash_vals.each_pair do |k, v|
|
40
|
+
if k == s(:sym, :desired_state) && v == s(:true) # cookstyle: disable Lint/BooleanSymbol
|
41
|
+
add_offense(v.parent, location: :expression, message: MSG, severity: :refactor)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def autocorrect(node)
|
48
|
+
lambda do |corrector|
|
49
|
+
range = range_with_surrounding_comma(range_with_surrounding_space(range: node.loc.expression, side: :left), :left)
|
50
|
+
corrector.remove(range)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -18,26 +18,29 @@ module RuboCop
|
|
18
18
|
module Cop
|
19
19
|
module Chef
|
20
20
|
module ChefRedundantCode
|
21
|
-
# There is no need to define a property named :name in a resource as Chef Infra defines
|
21
|
+
# There is no need to define a property or attribute named :name in a resource as Chef Infra defines this on all resources by default.
|
22
22
|
#
|
23
23
|
# @example
|
24
24
|
#
|
25
25
|
# # bad
|
26
26
|
# property :name, String
|
27
27
|
# property :name, String, name_property: true
|
28
|
+
# attribute :name, String
|
29
|
+
# attribute :name, String, name_attribute: true
|
28
30
|
#
|
29
31
|
class UnnecessaryNameProperty < Cop
|
30
|
-
MSG = 'There is no need to define a property named :name in a resource as Chef Infra defines
|
32
|
+
MSG = 'There is no need to define a property or attribute named :name in a resource as Chef Infra defines this on all resources by default.'.freeze
|
31
33
|
|
34
|
+
# match on a property/attribute named :name that's a string. The property/attribute optionally
|
35
|
+
# set name_property/name_attribute true, but nothing else is allowed. If you're doing that it's
|
36
|
+
# no longer the default and your usage is fine.
|
32
37
|
def_node_matcher :name_property?, <<-PATTERN
|
33
|
-
(send nil? :property (sym :name) (const nil? :String)
|
38
|
+
(send nil? {:property :attribute} (sym :name) (const nil? :String) (hash (pair (sym {:name_attribute :name_property}) (true)))?)
|
34
39
|
PATTERN
|
35
40
|
|
36
41
|
def on_send(node)
|
37
|
-
name_property?(node) do
|
38
|
-
|
39
|
-
add_offense(node, location: :expression, message: MSG, severity: :refactor)
|
40
|
-
end
|
42
|
+
name_property?(node) do
|
43
|
+
add_offense(node, location: :expression, message: MSG, severity: :refactor)
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -0,0 +1,59 @@
|
|
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 ChefStyle
|
21
|
+
# Use :immediately instead of :immediate for resource notification timing
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
#
|
27
|
+
# template '/etc/www/configures-apache.conf' do
|
28
|
+
# notifies :restart, 'service[apache]', :immediate
|
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 ImmediateNotificationTiming < Cop
|
38
|
+
MSG = 'Use :immediately instead of :immediate for resource notification timing'.freeze
|
39
|
+
|
40
|
+
def_node_matcher :immediate_notify?, <<-PATTERN
|
41
|
+
(send nil? :notifies (sym _) (...) $(sym :immediate))
|
42
|
+
PATTERN
|
43
|
+
|
44
|
+
def on_send(node)
|
45
|
+
immediate_notify?(node) do |timing|
|
46
|
+
add_offense(timing, location: :expression, message: MSG, severity: :refactor)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def autocorrect(node)
|
51
|
+
lambda do |corrector|
|
52
|
+
corrector.replace(node.loc.expression, ':immediately')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,55 @@
|
|
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 ChefStyle
|
21
|
+
# When setting the allowed types for a resource to accept either true or false values it's much simpler to use true and false instead of TrueClass and FalseClass.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# property :foo, [TrueClass, FalseClass]
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# property :foo, [true, false]
|
30
|
+
#
|
31
|
+
class TrueClassFalseClassResourceProperties < Cop
|
32
|
+
MSG = "When setting the allowed types for a resource to accept either true or false values it's much simpler to use true and false instead of TrueClass and FalseClass.".freeze
|
33
|
+
|
34
|
+
def_node_matcher :trueclass_falseclass_property?, <<-PATTERN
|
35
|
+
(send nil? {:property :attribute} (sym _) $(array (const nil? :TrueClass) (const nil? :FalseClass)) ... )
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
def on_send(node)
|
39
|
+
trueclass_falseclass_property?(node) do
|
40
|
+
add_offense(node, location: :expression, message: MSG, severity: :refactor)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def autocorrect(node)
|
45
|
+
lambda do |corrector|
|
46
|
+
trueclass_falseclass_property?(node) do |types|
|
47
|
+
corrector.replace(types.loc.expression, '[true, false]')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,90 @@
|
|
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 ChefStyle
|
21
|
+
# Use the platform?() and platform_family?() helpers instead of a case statement that only includes a single when statement.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# case node['platform']
|
27
|
+
# when 'ubuntu'
|
28
|
+
# log "We're on Ubuntu"
|
29
|
+
# apt_update
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# case node['platform_family']
|
33
|
+
# when 'rhel'
|
34
|
+
# include_recipe 'yum'
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# if platform?('ubuntu')
|
39
|
+
# log "We're on Ubuntu"
|
40
|
+
# apt_update
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# include_recipe 'yum' if platform_family?('rhel')
|
44
|
+
#
|
45
|
+
class UnnecessaryPlatformCaseStatement < Cop
|
46
|
+
include RangeHelp
|
47
|
+
|
48
|
+
MSG = 'Use the platform?() and platform_family?() helpers instead of a case statement that only includes a single when statement.'.freeze
|
49
|
+
|
50
|
+
def_node_matcher :platform_case?, <<-PATTERN
|
51
|
+
( case $( send (send nil? :node) :[] $(str {"platform" "platform_family"})) ... )
|
52
|
+
PATTERN
|
53
|
+
|
54
|
+
def on_case(node)
|
55
|
+
platform_case?(node) do
|
56
|
+
add_offense(node, location: :expression, message: MSG, severity: :refactor) if node&.when_branches&.count == 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def autocorrect(node)
|
61
|
+
lambda do |corrector|
|
62
|
+
platform_case?(node) do |node_, type|
|
63
|
+
condition_string = node.when_branches.first.conditions.map(&:source).join(', ')
|
64
|
+
|
65
|
+
# single line bodies without an else statement should be transformed into `X if platform?('ubuntu')` style statements
|
66
|
+
# while multiline statements should just have the case and when bits replace with `if platform?('ubuntu')`
|
67
|
+
if !node.else? && !node.when_branches.first.body.multiline?
|
68
|
+
new_source = "#{node.when_branches.first.body.source} if #{type.value}?(#{condition_string})"
|
69
|
+
corrector.replace(node.loc.expression, new_source)
|
70
|
+
else
|
71
|
+
# find the range from the beginning of the case to the end of the node['platform'] or node['platform_family']
|
72
|
+
case_range = node.loc.keyword.join(node_.loc.expression.end)
|
73
|
+
|
74
|
+
# replace the complete conditional range with a new if statement
|
75
|
+
corrector.replace(case_range, "if #{type.value}?(#{condition_string})")
|
76
|
+
|
77
|
+
# find the range from the start of the when to the end of the last argument
|
78
|
+
conditional_range = node.when_branches.first.conditions[-1].source_range.join(node.when_branches.first.loc.keyword.begin)
|
79
|
+
|
80
|
+
# remove the when XYZ condition along with any leading spaces so that we remove the whole empty line
|
81
|
+
corrector.remove(range_with_surrounding_space(range: conditional_range, side: :left))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|