cookstyle 5.4.13 → 5.5.7
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 +231 -129
- data/lib/cookstyle.rb +1 -0
- data/lib/cookstyle/version.rb +1 -1
- data/lib/rubocop/chef/cookbook_helpers.rb +67 -0
- data/lib/rubocop/cop/chef/correctness/block_guard_clause_string_only.rb +34 -31
- data/lib/rubocop/cop/chef/correctness/cb_depends_on_self.rb +16 -14
- data/lib/rubocop/cop/chef/correctness/default_maintainer_metadata.rb +22 -20
- data/lib/rubocop/cop/chef/correctness/insecure_cookbook_url.rb +32 -30
- data/lib/rubocop/cop/chef/correctness/invalid_license_string.rb +454 -453
- data/lib/rubocop/cop/chef/correctness/invalid_platform_metadata.rb +57 -57
- data/lib/rubocop/cop/chef/correctness/metadata_missing_name.rb +18 -16
- data/lib/rubocop/cop/chef/correctness/name_property_and_required.rb +61 -59
- data/lib/rubocop/cop/chef/correctness/node_normal.rb +29 -27
- data/lib/rubocop/cop/chef/correctness/node_normal_unless.rb +29 -27
- data/lib/rubocop/cop/chef/correctness/node_save.rb +46 -0
- data/lib/rubocop/cop/chef/correctness/ohai_default_recipe.rb +47 -0
- data/lib/rubocop/cop/chef/correctness/property_with_default_and_required.rb +35 -33
- data/lib/rubocop/cop/chef/correctness/property_with_name_attribute.rb +29 -27
- data/lib/rubocop/cop/chef/correctness/resource_sets_internal_properties.rb +52 -0
- data/lib/rubocop/cop/chef/correctness/resource_sets_name_property.rb +51 -0
- data/lib/rubocop/cop/chef/correctness/resource_with_none_action.rb +52 -0
- data/lib/rubocop/cop/chef/correctness/service_resource.rb +26 -24
- data/lib/rubocop/cop/chef/correctness/tmp_path.rb +30 -28
- data/lib/rubocop/cop/chef/deprecation/attribute_metadata.rb +22 -21
- data/lib/rubocop/cop/chef/deprecation/chef_rest.rb +56 -0
- data/lib/rubocop/cop/chef/deprecation/chocolatey_package_uninstall_action.rb +58 -0
- data/lib/rubocop/cop/chef/deprecation/conflicts_metadata.rb +18 -16
- data/lib/rubocop/cop/chef/deprecation/depends_compat_resource.rb +21 -19
- data/lib/rubocop/cop/chef/deprecation/depends_partial_search.rb +17 -15
- data/lib/rubocop/cop/chef/deprecation/depends_poise.rb +17 -15
- data/lib/rubocop/cop/chef/deprecation/deprecated_mixins.rb +39 -37
- data/lib/rubocop/cop/chef/deprecation/easy_install.rb +15 -13
- data/lib/rubocop/cop/chef/deprecation/epic_fail.rb +24 -22
- data/lib/rubocop/cop/chef/deprecation/erl_call.rb +15 -13
- data/lib/rubocop/cop/chef/deprecation/launchd_deprecated_hash_property.rb +55 -0
- data/lib/rubocop/cop/chef/deprecation/legacy_yum_cookbook_recipes.rb +24 -22
- data/lib/rubocop/cop/chef/deprecation/locale_lc_all_property.rb +45 -0
- data/lib/rubocop/cop/chef/deprecation/long_description_metadata.rb +21 -19
- data/lib/rubocop/cop/chef/deprecation/node_methods_not_attributes.rb +55 -53
- data/lib/rubocop/cop/chef/deprecation/node_set.rb +27 -25
- data/lib/rubocop/cop/chef/deprecation/node_set_unless.rb +27 -25
- data/lib/rubocop/cop/chef/deprecation/provides_metadata.rb +18 -16
- data/lib/rubocop/cop/chef/deprecation/replaces_metadata.rb +18 -16
- data/lib/rubocop/cop/chef/deprecation/require_recipe.rb +23 -21
- data/lib/rubocop/cop/chef/deprecation/suggests_metadata.rb +18 -16
- data/lib/rubocop/cop/chef/deprecation/use_inline_resources.rb +56 -0
- data/lib/rubocop/cop/chef/deprecation/user_supports_property.rb +53 -0
- data/lib/rubocop/cop/chef/deprecation/xml_ruby_recipe.rb +51 -0
- data/lib/rubocop/cop/chef/deprecation/yum_dnf_compat_recipe.rb +51 -0
- data/lib/rubocop/cop/chef/effortless/data_bags.rb +13 -11
- data/lib/rubocop/cop/chef/effortless/search_used.rb +13 -11
- data/lib/rubocop/cop/chef/modernize/apt_default_recipe.rb +22 -20
- data/lib/rubocop/cop/chef/modernize/berksfile_source.rb +31 -29
- data/lib/rubocop/cop/chef/modernize/build_essential.rb +25 -23
- data/lib/rubocop/cop/chef/modernize/chef_14_resources.rb +27 -25
- data/lib/rubocop/cop/chef/modernize/defines_chefspec_matchers.rb +25 -23
- data/lib/rubocop/cop/chef/modernize/execute_apt_update.rb +19 -17
- data/lib/rubocop/cop/chef/modernize/includes_mixin_shellout.rb +27 -25
- data/lib/rubocop/cop/chef/modernize/libarchive_file.rb +41 -0
- data/lib/rubocop/cop/chef/modernize/minitest_handler_usage.rb +21 -19
- data/lib/rubocop/cop/chef/modernize/powershell_expand_archive.rb +48 -0
- data/lib/rubocop/cop/chef/modernize/powershell_install_package.rb +51 -0
- data/lib/rubocop/cop/chef/modernize/powershell_install_windowsfeature.rb +54 -0
- data/lib/rubocop/cop/chef/modernize/resource_set_or_return.rb +25 -23
- data/lib/rubocop/cop/chef/modernize/resource_with_allowed_actions.rb +77 -0
- data/lib/rubocop/cop/chef/modernize/resource_with_attributes.rb +37 -35
- data/lib/rubocop/cop/chef/modernize/respond_to_metadata.rb +54 -0
- data/lib/rubocop/cop/chef/modernize/respond_to_provides.rb +25 -23
- data/lib/rubocop/cop/chef/modernize/respond_to_resource_name.rb +26 -24
- data/lib/rubocop/cop/chef/{effortless/node_save.rb → modernize/seven_zip_archive.rb} +16 -16
- data/lib/rubocop/cop/chef/modernize/shellouts_to_chocolatey.rb +59 -0
- data/lib/rubocop/cop/chef/modernize/whyrun_supported_true.rb +20 -18
- data/lib/rubocop/cop/chef/modernize/windows_default_recipe.rb +23 -21
- data/lib/rubocop/cop/chef/modernize/windows_version_helper.rb +20 -18
- data/lib/rubocop/cop/chef/modernize/windows_zipfile.rb +15 -13
- data/lib/rubocop/cop/chef/style/attribute_keys.rb +59 -57
- data/lib/rubocop/cop/chef/style/comment_sentence_spacing.rb +14 -12
- data/lib/rubocop/cop/chef/style/comments_copyright_format.rb +65 -63
- data/lib/rubocop/cop/chef/style/comments_format.rb +48 -45
- data/lib/rubocop/cop/chef/style/file_mode.rb +32 -30
- metadata +24 -9
- data/lib/rubocop/cop/chef/deprecation/respond_to_metadata.rb +0 -53
- data/lib/rubocop/cop/chef/modernize/ohai_default_recipe.rb +0 -45
- data/lib/rubocop/cop/chef/modernize/resource_with_allowed_action.rb +0 -75
- data/lib/rubocop/cop/chef/modernize/use_inline_resources.rb +0 -54
- data/lib/rubocop/cop/chef/modernize/xml_ruby_recipe.rb +0 -49
- data/lib/rubocop/cop/chef/modernize/yum_dnf_compat_recipe.rb +0 -49
@@ -17,73 +17,75 @@
|
|
17
17
|
module RuboCop
|
18
18
|
module Cop
|
19
19
|
module Chef
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
20
|
+
module ChefStyle
|
21
|
+
# Check which style of keys are used to access node attributes.
|
22
|
+
#
|
23
|
+
# There are two supported styles: "symbols" and "strings".
|
24
|
+
#
|
25
|
+
# @example when configuration is `EnforcedStyle: symbols`
|
26
|
+
#
|
27
|
+
# # bad
|
28
|
+
# node['foo']
|
29
|
+
# node["foo"]
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# node[:foo]
|
33
|
+
#
|
34
|
+
# @example when configuration is `EnforcedStyle: strings`
|
35
|
+
#
|
36
|
+
# # bad
|
37
|
+
# node[:foo]
|
38
|
+
#
|
39
|
+
# # good
|
40
|
+
# node['foo']
|
41
|
+
# node["foo"]
|
42
|
+
#
|
43
|
+
class AttributeKeys < Cop
|
44
|
+
include RuboCop::Cop::ConfigurableEnforcedStyle
|
44
45
|
|
45
|
-
|
46
|
+
MSG = 'Use %s to access node attributes'.freeze
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
def_node_matcher :node_attribute_access?, <<-PATTERN
|
49
|
+
(send (send _ :node) :[] _)
|
50
|
+
PATTERN
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
def_node_matcher :node_level_attribute_access?, <<-PATTERN
|
53
|
+
(send (send {(send _ :node) nil} {:default :role_default :env_default :normal :override :role_override :env_override :force_override :automatic}) :[] _)
|
54
|
+
PATTERN
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
def on_send(node)
|
57
|
+
if node_attribute_access?(node) || node_level_attribute_access?(node)
|
58
|
+
# node is first child for #[], need to look for the outermost parent too.
|
59
|
+
outer_node = node
|
60
|
+
while outer_node.parent && outer_node.parent.type == :send && outer_node.parent.children[1] == :[]
|
61
|
+
on_node_attribute_access(outer_node.children[2])
|
62
|
+
outer_node = outer_node.parent
|
63
|
+
end
|
64
|
+
# One last time for the outer-most access.
|
60
65
|
on_node_attribute_access(outer_node.children[2])
|
61
|
-
outer_node = outer_node.parent
|
62
66
|
end
|
63
|
-
# One last time for the outer-most access.
|
64
|
-
on_node_attribute_access(outer_node.children[2])
|
65
67
|
end
|
66
|
-
end
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
69
|
+
def on_node_attribute_access(node)
|
70
|
+
if node.type == :str
|
71
|
+
style_detected(:strings)
|
72
|
+
add_offense(node, location: :expression, message: MSG % style, severity: :refactor) if style == :symbols
|
73
|
+
elsif node.type == :sym
|
74
|
+
style_detected(:symbols)
|
75
|
+
add_offense(node, location: :expression, message: MSG % style, severity: :refactor) if style == :strings
|
76
|
+
end
|
75
77
|
end
|
76
|
-
end
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
79
|
+
def autocorrect(node)
|
80
|
+
lambda do |corrector|
|
81
|
+
key_string = node.children.first.to_s
|
82
|
+
key_replacement = if style == :symbols
|
83
|
+
key_string.to_sym.inspect
|
84
|
+
else # strings
|
85
|
+
key_string.inspect
|
86
|
+
end
|
87
|
+
corrector.replace(node.loc.expression, key_replacement)
|
88
|
+
end
|
87
89
|
end
|
88
90
|
end
|
89
91
|
end
|
@@ -18,23 +18,25 @@
|
|
18
18
|
module RuboCop
|
19
19
|
module Cop
|
20
20
|
module Chef
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
module ChefStyle
|
22
|
+
# Replaces double spaces between sentences with a single space.
|
23
|
+
# Note: This is DISABLED by default.
|
24
|
+
class CommentSentenceSpacing < Cop
|
25
|
+
MSG = 'Use a single space after sentences in comments'.freeze
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
def investigate(processed_source)
|
28
|
+
return unless processed_source.ast
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
processed_source.comments.each do |comment|
|
31
|
+
if comment.text.match?(/(.|\?)\s{2}/) # https://rubular.com/r/8o3SiDrQMJSzuU
|
32
|
+
add_offense(comment, location: comment.loc.expression, message: MSG, severity: :refactor)
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
|
-
end
|
35
36
|
|
36
|
-
|
37
|
-
|
37
|
+
def autocorrect(comment)
|
38
|
+
->(corrector) { corrector.replace(comment.loc.expression, comment.text.gsub('. ', '. ').gsub('? ', '? ')) }
|
39
|
+
end
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
@@ -18,83 +18,85 @@
|
|
18
18
|
module RuboCop
|
19
19
|
module Cop
|
20
20
|
module Chef
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
21
|
+
module ChefStyle
|
22
|
+
# Checks for incorrectly formatted copyright comments.
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
#
|
26
|
+
# # bad (assuming current year is 2019)
|
27
|
+
# Copyright:: 2013-2019 Opscode, Inc.
|
28
|
+
# Copyright:: 2013-2019 Chef Inc.
|
29
|
+
# Copyright:: 2013-2019 Chef Software Inc.
|
30
|
+
# Copyright:: 2009-2010 2013-2019 Chef Software Inc.
|
31
|
+
# Copyright:: Chef Software Inc.
|
32
|
+
# Copyright:: Tim Smith
|
33
|
+
# Copyright:: Copyright (c) 2015-2019 Chef Software, Inc.
|
34
|
+
#
|
35
|
+
# # good (assuming current year is 2019)
|
36
|
+
# Copyright:: 2013-2019 Chef Software, Inc.
|
37
|
+
# Copyright:: 2013-2019 Tim Smith
|
38
|
+
# Copyright:: 2019 37Signals, Inc.
|
39
|
+
#
|
40
|
+
class CopyrightCommentFormat < Cop
|
41
|
+
require 'date'
|
42
|
+
|
43
|
+
MSG = 'Properly format copyrights header comments'.freeze
|
44
|
+
|
45
|
+
def investigate(processed_source)
|
46
|
+
return unless processed_source.ast
|
47
|
+
|
48
|
+
processed_source.comments.each do |comment|
|
49
|
+
next unless comment.inline? # headers aren't in blocks
|
50
|
+
|
51
|
+
if invalid_copyright_comment?(comment)
|
52
|
+
add_offense(comment, location: comment.loc.expression, message: MSG, severity: :refactor)
|
53
|
+
end
|
52
54
|
end
|
53
55
|
end
|
54
|
-
end
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
def autocorrect(comment)
|
58
|
+
correct_comment = "# Copyright:: #{copyright_date_range(comment)}, #{copyright_holder(comment)}"
|
59
|
+
->(corrector) { corrector.replace(comment.loc.expression, correct_comment) }
|
60
|
+
end
|
60
61
|
|
61
|
-
|
62
|
+
private
|
62
63
|
|
63
|
-
|
64
|
-
|
64
|
+
def copyright_date_range(comment)
|
65
|
+
dates = comment.text.scan(/([0-9]{4})/)
|
65
66
|
|
66
|
-
|
67
|
-
|
67
|
+
# no copyright year present so return this year
|
68
|
+
return Time.new.year if dates.empty?
|
68
69
|
|
69
|
-
|
70
|
+
oldest_date = dates.min[0].to_i
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
# Avoid returning THIS_YEAR - THIS_YEAR
|
73
|
+
if oldest_date == Time.new.year
|
74
|
+
oldest_date
|
75
|
+
else
|
76
|
+
"#{oldest_date}-#{Time.new.year}"
|
77
|
+
end
|
76
78
|
end
|
77
|
-
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
def copyright_holder(comment)
|
81
|
+
# Grab just the company / individual name w/o :: or dates
|
82
|
+
match = /(?:.*[0-9]{4}|Copyright\W*)(?:,)?(?:\s)?(.*)/.match(comment.text)
|
83
|
+
marketing_sanitizer(match.captures[0])
|
84
|
+
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
86
|
+
# Flush Opscode down the memory hole and Chef Inc is not a company
|
87
|
+
def marketing_sanitizer(name)
|
88
|
+
name.gsub('Opscode', 'Chef Software').gsub(/Chef(?:,)? Inc.*/, 'Chef Software, Inc.')
|
89
|
+
end
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
|
91
|
+
def invalid_copyright_comment?(comment)
|
92
|
+
match = /# (?:Copyright\W*)(.*)/.match(comment.text)
|
93
|
+
return false unless match # it's not even a copyright
|
93
94
|
|
94
|
-
|
95
|
-
|
95
|
+
current_text = match.captures[0]
|
96
|
+
desired_text = "#{copyright_date_range(comment)}, #{copyright_holder(comment)}"
|
96
97
|
|
97
|
-
|
98
|
+
return true unless current_text == desired_text
|
99
|
+
end
|
98
100
|
end
|
99
101
|
end
|
100
102
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#
|
2
|
-
# Copyright:: 2016,
|
2
|
+
# Copyright:: 2016-2019, Chef Software, Inc.
|
3
|
+
# Author:: Tim Smith (<tsmith@chef.io>)
|
3
4
|
#
|
4
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
6
|
# you may not use this file except in compliance with the License.
|
@@ -17,59 +18,61 @@
|
|
17
18
|
module RuboCop
|
18
19
|
module Cop
|
19
20
|
module Chef
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
21
|
+
module ChefStyle
|
22
|
+
# Checks for incorrectly formatted headers
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
#
|
26
|
+
# # bad
|
27
|
+
# Copyright 2013-2016 Chef Software, Inc.
|
28
|
+
# Recipe default.rb
|
29
|
+
# Attributes default.rb
|
30
|
+
# License Apache2
|
31
|
+
# Cookbook tomcat
|
32
|
+
# Cookbook Name:: Tomcat
|
33
|
+
# Attributes File:: default
|
34
|
+
#
|
35
|
+
# # good
|
36
|
+
# Copyright:: 2013-2016 Chef Software, Inc.
|
37
|
+
# Recipe:: default.rb
|
38
|
+
# Attributes:: default.rb
|
39
|
+
# License:: Apache License, Version 2.0
|
40
|
+
# Cookbook:: Tomcat
|
41
|
+
#
|
42
|
+
class CommentFormat < Cop
|
43
|
+
MSG = 'Properly format header comments'.freeze
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
+
def investigate(processed_source)
|
46
|
+
return unless processed_source.ast
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
processed_source.comments.each do |comment|
|
49
|
+
next if comment.loc.first_line > 10 # avoid false positives when we were checking further down the file
|
50
|
+
next unless comment.inline? # headers aren't in blocks
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
+
if invalid_comment?(comment)
|
53
|
+
add_offense(comment, location: comment.loc.expression, message: MSG, severity: :refactor)
|
54
|
+
end
|
52
55
|
end
|
53
56
|
end
|
54
|
-
end
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
def autocorrect(comment)
|
59
|
+
# Extract the type and the actual value. Strip out "Name" or "File"
|
60
|
+
# 'Cookbook Name' should be 'Cookbook'. Also skip a :: if present
|
61
|
+
# https://rubular.com/r/Do9fpLWXlCmvdJ
|
62
|
+
match = /^#\s*([A-Za-z]+)\s?(?:Name|File)?(?:::)?\s(.*)/.match(comment.text)
|
63
|
+
comment_type, value = match.captures
|
64
|
+
correct_comment = "# #{comment_type}:: #{value}"
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
+
->(corrector) { corrector.replace(comment.loc.expression, correct_comment) }
|
67
|
+
end
|
66
68
|
|
67
|
-
|
69
|
+
private
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
def invalid_comment?(comment)
|
72
|
+
comment_types = %w(Author Cookbook Library Attribute Copyright Recipe Resource Definition License)
|
73
|
+
comment_types.any? do |comment_type|
|
74
|
+
/^#\s*#{comment_type}\s+/.match(comment.text)
|
75
|
+
end
|
73
76
|
end
|
74
77
|
end
|
75
78
|
end
|
@@ -17,43 +17,45 @@
|
|
17
17
|
module RuboCop
|
18
18
|
module Cop
|
19
19
|
module Chef
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
20
|
+
module ChefStyle
|
21
|
+
# Check the file modes are given as strings instead of integers.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# mode 644
|
27
|
+
# mode 0644
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# mode '644'
|
31
|
+
#
|
32
|
+
class FileMode < Cop
|
33
|
+
MSG = 'Use strings for file modes'.freeze
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
def_node_matcher :resource_mode?, <<-PATTERN
|
36
|
+
(send nil? :mode $int)
|
37
|
+
PATTERN
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
def on_send(node)
|
40
|
+
resource_mode?(node) do |mode_int|
|
41
|
+
add_offense(mode_int, location: :expression, message: MSG, severity: :refactor)
|
42
|
+
end
|
41
43
|
end
|
42
|
-
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def autocorrect(node)
|
46
|
+
lambda do |corrector|
|
47
|
+
# If it was an octal literal, make sure we write out the right number.
|
48
|
+
replacement_base = octal?(node) ? 8 : 10
|
49
|
+
replacement_mode = node.children.first.to_s(replacement_base)
|
50
|
+
corrector.replace(node.loc.expression, replacement_mode.inspect)
|
51
|
+
end
|
50
52
|
end
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
+
private
|
54
55
|
|
55
|
-
|
56
|
-
|
56
|
+
def octal?(node)
|
57
|
+
node.source =~ /^0o?\d+/i
|
58
|
+
end
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|