Class: RuboCop::Cop::Chef::RedundantCode::UseCreateIfMissing

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp, RuboCop::Chef::CookbookHelpers
Defined in:
lib/rubocop/cop/chef/redundant/use_create_if_missing.rb

Overview

Use the ‘:create_if_missing` action instead of `not_if` with a `::File.exist(FOO)` check.

Examples:


### incorrect
cookbook_file '/logs/foo/error.log' do
  source 'error.log'
  owner 'root'
  group 'root'
  mode '0644'
  not_if { ::File.exists?('/logs/foo/error.log') }
end

remote_file 'Download file' do
  path '/foo/bar'
  source 'https://foo.com/bar'
  owner 'root'
  group 'root'
  mode '0644'
  not_if { ::File.exist?('/foo/bar') }
end

### correct
cookbook_file '/logs/foo/error.log' do
  source 'error.log'
  owner 'root'
  group 'root'
  mode '0644'
  action :create_if_missing
end

remote_file 'Download file' do
  path '/foo/bar'
  source 'https://foo.com/bar'
  owner 'root'
  group 'root'
  mode '0644'
  action :create_if_missing
end

Constant Summary collapse

MSG =
'Use the :create_if_missing action instead of not_if with a ::File.exist(FOO) check.'
RESOURCES =
%i(cookbook_file file remote_directory cron_d remote_file template).freeze

Instance Method Summary collapse

Methods included from RuboCop::Chef::CookbookHelpers

#match_property_in_resource?, #match_resource_type?, #method_arg_ast_to_string, #resource_block_name_if_string

Methods inherited from Base

#target_chef_version

Instance Method Details

#on_block(node) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rubocop/cop/chef/redundant/use_create_if_missing.rb', line 80

def on_block(node)
  match_property_in_resource?(RESOURCES, :not_if, node) do |prop|
    # if it's not a block type then it's not a ruby block with a file.exist
    return unless prop.block_type?

    file_exist_value(prop.body) do |exists_content| # check the contents of the ruby block that's passed
      # not an offense if:
      #   - The resource block name (the last arg of the send) doesn't match the exists check content
      #   - If a path property is used it doesn't match the exists check content
      return unless exists_content == node.send_node.last_argument ||
                    exists_content == path_property_node(node)&.first&.first

      # we have an action so check if it is :create. If that's the case we can replace that value
      # and delete the not_if line. Otherwise it's an action like :remove and while the whole resource
      # no longer makes sense that's not our problem here.
      create_action(node) do |create_action|
        return unless create_action == s(:sym, :create)
        add_offense(prop, severity: :refactor) do |corrector|
          corrector.replace(create_action, ':create_if_missing')
          corrector.remove(range_by_whole_lines(prop.source_range, include_final_newline: true))
        end
        return
      end

      # if we got this far we didn't return above when we had an action
      # so we can just replace the not_if line with a new :create_if_missing action
      add_offense(prop, severity: :refactor) do |corrector|
        corrector.replace(prop, 'action :create_if_missing')
      end
    end
  end
end