class RuboCop::Cop::Style::CommandLiteral

‘echo `ls``
# good
@example AllowInnerBackticks: true
%x(echo `ls`)
# good
`echo `ls``
# bad
# backticks are found in the command string.
# If `false`, the cop will always recommend using `%x` if one or more
@example AllowInnerBackticks: false (default)
)
ln -s bar.example.yml bar.example
ln -s foo.example.yml foo.example
%x(
# good
folders = %x(find . -type d).split
# good
`
ln -s bar.example.yml bar.example
ln -s foo.example.yml foo.example
`
# bad
folders = `find . -type d`.split
# bad
@example EnforcedStyle: percent_x
)
ln -s bar.example.yml bar.example
ln -s foo.example.yml foo.example
%x(
# good
folders = `find . -type d`.split
# good
`
ln -s bar.example.yml bar.example
ln -s foo.example.yml foo.example
`
# bad
folders = %x(find . -type d).split
# bad
@example EnforcedStyle: mixed
`
ln -s bar.example.yml bar.example
ln -s foo.example.yml foo.example
`
# good
folders = `find . -type d`.split
# good
)
ln -s bar.example.yml bar.example
ln -s foo.example.yml foo.example
%x(
# bad
folders = %x(find . -type d).split
# bad
@example EnforcedStyle: backticks (default)
Enforces using “ or %x around command literals.

def allow_inner_backticks?

def allow_inner_backticks?
  cop_config['AllowInnerBackticks']
end

def allowed_backtick_literal?(node)

def allowed_backtick_literal?(node)
  case style
  when :backticks
    !contains_disallowed_backtick?(node)
  when :mixed
    node.single_line? && !contains_disallowed_backtick?(node)
  end
end

def allowed_percent_x_literal?(node)

def allowed_percent_x_literal?(node)
  case style
  when :backticks
    contains_disallowed_backtick?(node)
  when :mixed
    node.multiline? || contains_disallowed_backtick?(node)
  when :percent_x
    true
  end
end

def autocorrect(corrector, node)

def autocorrect(corrector, node)
  return if contains_backtick?(node)
  replacement = if backtick_literal?(node)
                  ['%x', ''].zip(preferred_delimiter).map(&:join)
                else
                  %w[` `]
                end
  corrector.replace(node.loc.begin, replacement.first)
  corrector.replace(node.loc.end, replacement.last)
end

def backtick_literal?(node)

def backtick_literal?(node)
  node.loc.begin.source == '`'
end

def check_backtick_literal(node, message)

def check_backtick_literal(node, message)
  return if allowed_backtick_literal?(node)
  add_offense(node, message: message) { |corrector| autocorrect(corrector, node) }
end

def check_percent_x_literal(node, message)

def check_percent_x_literal(node, message)
  return if allowed_percent_x_literal?(node)
  add_offense(node, message: message) { |corrector| autocorrect(corrector, node) }
end

def command_delimiter

def command_delimiter
  preferred_delimiters_config['%x']
end

def contains_backtick?(node)

def contains_backtick?(node)
  node_body(node).include?('`')
end

def contains_disallowed_backtick?(node)

def contains_disallowed_backtick?(node)
  !allow_inner_backticks? && contains_backtick?(node)
end

def default_delimiter

def default_delimiter
  preferred_delimiters_config['default']
end

def node_body(node)

def node_body(node)
  loc = node.loc
  loc.expression.source[loc.begin.length...-loc.end.length]
end

def on_xstr(node)

def on_xstr(node)
  return if node.heredoc?
  if backtick_literal?(node)
    check_backtick_literal(node, MSG_USE_PERCENT_X)
  else
    check_percent_x_literal(node, MSG_USE_BACKTICKS)
  end
end

def preferred_delimiter

def preferred_delimiter
  (command_delimiter || default_delimiter).chars
end

def preferred_delimiters_config

def preferred_delimiters_config
  config.for_cop('Style/PercentLiteralDelimiters') ['PreferredDelimiters']
end