Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ChefModernize/DefaultActionFromInitialize and ChefModernize/ResourceNameFromInitialize: #348

Merged
merged 1 commit into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions config/cookstyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,24 @@ ChefModernize/PowerShellGuardInterpreter:
Exclude:
- '**/metadata.rb'

ChefModernize/DefaultActionFromInitialize:
Description: The default actions can now be specified using the `default_action` helper instead of using the @action variable in the resource provider initialize method.
Enabled: true
VersionAdded: '5.10.0'
Include:
- '**/resources/*.rb'
- '**/providers/*.rb'
- '**/libraries/*.rb'

ChefModernize/ResourceNameFromInitialize:
Description: The name of a resource can be set with the "resource_name" helper instead of using the initialize method.
Enabled: true
VersionAdded: '5.10.0'
Include:
- '**/resources/*.rb'
- '**/providers/*.rb'
- '**/libraries/*.rb'

###############################
# Migrating to new patterns
###############################
Expand Down
66 changes: 66 additions & 0 deletions lib/rubocop/cop/chef/modernize/default_action_initializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
# Copyright:: 2019, Chef Software Inc.
# Author:: Tim Smith (<tsmith@chef.io>)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module RuboCop
module Cop
module Chef
module ChefModernize
# The default actions can now be specified using the `default_action` helper instead of using the @action variable in the resource provider initialize method. In general we recommend against writing HWRPs, but if HWRPs are necessary you should utilize as much of the resource DSL as possible.
#
# @example
#
# # bad
# def initialize(*args)
# super
# @action = :create
# end
#
# # good
# default_action :create

class DefaultActionFromInitialize < Cop
include RangeHelp

MSG = 'The default action of a resource can be set with the "default_action" helper instead of using the initialize method.'.freeze

def on_def(node)
return unless node.method_name == :initialize
return if node.body.nil? # nil body is an empty initialize method

node.body.each_node do |x|
if x.assignment? && !x.node_parts.empty? && x.node_parts.first == :@action
add_offense(x, location: :expression, message: MSG, severity: :refactor)
end
end
end

def_node_search :intialize_method, '(def :initialize ... )'

def autocorrect(node)
lambda do |corrector|
# insert the new default_action call above the initialize method
initialize_node = intialize_method(processed_source.ast).first
corrector.insert_before(initialize_node.source_range, "default_action #{node.asgn_rhs.source}\n\n")

# remove the variable from the initialize method
corrector.remove(range_with_surrounding_space(range: node.loc.expression, side: :left))
end
end
end
end
end
end
end
66 changes: 66 additions & 0 deletions lib/rubocop/cop/chef/modernize/resource_name_initializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#
# Copyright:: 2019, Chef Software Inc.
# Author:: Tim Smith (<tsmith@chef.io>)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
module RuboCop
module Cop
module Chef
module ChefModernize
# The resource name can now be specified using the `resource_name` helper instead of using the @resource_name variable in the resource provider initialize method. In general we recommend against writing HWRPs, but if HWRPs are necessary you should utilize as much of the resource DSL as possible.
#
# @example
#
# # bad
# def initialize(*args)
# super
# @resource_name = :foo
# end
#
# # good
# resource_name :create

class ResourceNameFromInitialize < Cop
include RangeHelp

MSG = 'The name of a resource can be set with the "resource_name" helper instead of using the initialize method.'.freeze

def on_def(node)
return unless node.method_name == :initialize
return if node.body.nil? # nil body is an empty initialize method

node.body.each_node do |x|
if x.assignment? && !x.node_parts.empty? && x.node_parts.first == :@resource_name
add_offense(x, location: :expression, message: MSG, severity: :refactor)
end
end
end

def_node_search :intialize_method, '(def :initialize ... )'

def autocorrect(node)
lambda do |corrector|
# insert the new resource_name call above the initialize method
initialize_node = intialize_method(processed_source.ast).first
corrector.insert_before(initialize_node.source_range, "resource_name #{node.asgn_rhs.source}\n\n")

# remove the variable from the initialize method
corrector.remove(range_with_surrounding_space(range: node.loc.expression, side: :left))
end
end
end
end
end
end
end
47 changes: 47 additions & 0 deletions spec/rubocop/cop/chef/modernize/default_action_initializer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#
# Copyright:: 2019, Chef Software, Inc.
# Author:: Tim Smith (<tsmith@chef.io>)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require 'spec_helper'

describe RuboCop::Cop::Chef::ChefModernize::DefaultActionFromInitialize, :config do
subject(:cop) { described_class.new(config) }

it 'registers an offense with a HWRP specifies the default_action in the initializer' do
expect_offense(<<~RUBY)
def initialize(*args)
super
@action = :create
^^^^^^^^^^^^^^^^^ The default action of a resource can be set with the "default_action" helper instead of using the initialize method.
end
RUBY

expect_correction(<<~RUBY)
default_action :create
def initialize(*args)
super
end
RUBY
end

it 'does not register an offense with an empty initialize method' do
expect_no_offenses(<<~RUBY)
def initialize(*args)
end
RUBY
end
end
47 changes: 47 additions & 0 deletions spec/rubocop/cop/chef/modernize/resource_name_initializer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#
# Copyright:: 2019, Chef Software, Inc.
# Author:: Tim Smith (<tsmith@chef.io>)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require 'spec_helper'

describe RuboCop::Cop::Chef::ChefModernize::ResourceNameFromInitialize, :config do
subject(:cop) { described_class.new(config) }

it 'registers an offense with a HWRP specifies the resource_name in the initializer' do
expect_offense(<<~RUBY)
def initialize(*args)
super
@resource_name = :foo
^^^^^^^^^^^^^^^^^^^^^ The name of a resource can be set with the "resource_name" helper instead of using the initialize method.
end
RUBY

expect_correction(<<~RUBY)
resource_name :foo

def initialize(*args)
super
end
RUBY
end

it 'does not register an offense with an empty initialize method' do
expect_no_offenses(<<~RUBY)
def initialize(*args)
end
RUBY
end
end