Class: RuboCop::Cop::Style::ShellCommands Private

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
HelperFunctions
Defined in:
rubocops/shell_commands.rb

Overview

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

This cop makes sure that shell command arguments are separated.

Constant Summary collapse

MSG =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

"Separate `%<method>s` commands into `%<good_args>s`"
TARGET_METHODS =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

[
  [nil, :system],
  [nil, :safe_system],
  [nil, :quiet_system],
  [:Utils, :popen_read],
  [:Utils, :safe_popen_read],
  [:Utils, :popen_write],
  [:Utils, :safe_popen_write],
].freeze
RESTRICT_ON_SEND =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

TARGET_METHODS.map(&:second).uniq.freeze
SHELL_METACHARACTERS =

This constant is part of a private API. This constant may only be used in the Homebrew/brew repository. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

%w[> < < | ; : & * $ ? : ~ + @ ! ` ( ) [ ]].freeze

Instance Method Summary collapse

Methods included from HelperFunctions

#block_size, #check_precedence, #class_name, #component_precedes?, #end_column, #expression_negated?, #find_all_blocks, #find_block, #find_blocks, #find_const, #find_every_func_call_by_name, #find_every_method_call_by_name, #find_instance_call, #find_instance_method_call, #find_method_calls_by_name, #find_method_def, #find_method_with_args, #find_node_method_by_name, #find_strings, #format_component, #line_number, #line_start_column, #method_called?, #method_called_ever?, #method_called_in_block?, #method_name, #node_equals?, #offending_node, #parameters, #parameters_passed?, #problem, #regex_match_group, #size, #source_buffer, #start_column, #string_content

Instance Method Details

#on_send(node) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'rubocops/shell_commands.rb', line 32

def on_send(node)
  TARGET_METHODS.each do |target_class, target_method|
    next unless node.method_name == target_method

    target_receivers = if target_class.nil?
      [nil, s(:const, nil, :Kernel), s(:const, nil, :Homebrew)]
    else
      [s(:const, nil, target_class)]
    end
    next unless target_receivers.include?(node.receiver)

    first_arg = node.arguments.first
    arg_count = node.arguments.count
    if first_arg&.hash_type? # popen methods allow env hash
      first_arg = node.arguments.second
      arg_count -= 1
    end
    next if first_arg.nil? || arg_count >= 2

    first_arg_str = string_content(first_arg)

    # Only separate when no shell metacharacters are present
    next if SHELL_METACHARACTERS.any? { |meta| first_arg_str.include?(meta) }

    split_args = first_arg_str.shellsplit
    next if split_args.count <= 1

    good_args = split_args.map { |arg| "\"#{arg}\"" }.join(", ")
    method_string = if target_class
      "#{target_class}.#{target_method}"
    else
      target_method.to_s
    end
    add_offense(first_arg, message: format(MSG, method: method_string, good_args: good_args)) do |corrector|
      corrector.replace(first_arg.source_range, good_args)
    end
  end
end