Class: RuboCop::Cop::Chef::Style::UnnecessaryPlatformCaseStatement

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
RangeHelp
Defined in:
lib/rubocop/cop/chef/style/unnecessary_platform_case_statement.rb

Overview

Use the platform?() and platform_family?() helpers instead of a case statement that only includes a single when statement.

Examples:


### incorrect
case node['platform']
when 'ubuntu'
  log "We're on Ubuntu"
  apt_update
end

case node['platform_family']
when 'rhel'
  include_recipe 'yum'
end

### correct
if platform?('ubuntu')
  log "We're on Ubuntu"
  apt_update
end

include_recipe 'yum' if platform_family?('rhel')

Constant Summary collapse

MSG =
'Use the platform?() and platform_family?() helpers instead of a case statement that only includes a single when statement.'

Instance Method Summary collapse

Methods inherited from Base

#target_chef_version

Instance Method Details

#on_case(node) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rubocop/cop/chef/style/unnecessary_platform_case_statement.rb', line 56

def on_case(node)
  platform_case?(node) do |node_, type|
    return unless node&.when_branches&.count == 1
    add_offense(node, severity: :refactor) do |corrector|
      # we have at least one supermarket cookbook with an entirely empty platform case statement
      # we can't actually fix that so let's do nothing here.
      unless empty_case_statement?(node)
        condition_string = node.when_branches.first.conditions.map(&:source).join(', ')

        # single line bodies without an else statement should be transformed into `X if platform?('ubuntu')` style statements
        # while multi-line statements should just have the case and when bits replace with `if platform?('ubuntu')`
        if !node.else? && !node.when_branches.first.body.multiline?
          new_source = "#{node.when_branches.first.body.source} if #{type.value}?(#{condition_string})"
          corrector.replace(node, new_source)
        else
          # find the range from the beginning of the case to the end of the node['platform'] or node['platform_family']
          case_range = node.loc.keyword.join(node_.loc.expression.end)

          # replace the complete conditional range with a new if statement
          corrector.replace(case_range, "if #{type.value}?(#{condition_string})")

          # find the range from the start of the when to the end of the last argument
          conditional_range = node.when_branches.first.conditions[-1].source_range.join(node.when_branches.first.loc.keyword.begin)

          # remove the when XYZ condition along with any leading spaces so that we remove the whole empty line
          corrector.remove(range_with_surrounding_space(range: conditional_range, side: :left))
        end
      end
    end
  end
end