Module: RuboCop::Cop::OnSystemConditionalsHelper Private

Extended by:
NodePattern::Macros
Includes:
HelperFunctions
Included in:
Cask::OnSystemConditionals, FormulaAudit::MacOSOnLinux, FormulaAudit::OnSystemConditionals
Defined in:
rubocops/shared/on_system_conditionals_helper.rb,
sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi

Overview

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

This module performs common checks on on_{system} blocks in both formulae and casks.

Constant Summary collapse

ARCH_OPTIONS =

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.

[:arm, :intel].freeze
BASE_OS_OPTIONS =

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.

[:macos, :linux].freeze
MACOS_VERSION_OPTIONS =

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.

T.let(MacOSVersion::SYMBOLS.keys.freeze, T::Array[Symbol])
ON_SYSTEM_OPTIONS =

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.

T.let(
  [*ARCH_OPTIONS, *BASE_OS_OPTIONS, *MACOS_VERSION_OPTIONS, :system].freeze,
  T::Array[Symbol],
)
MACOS_MODULE_NAMES =

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.

["MacOS", "OS::Mac"].freeze
MACOS_VERSION_CONDITIONALS =

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.

T.let(
  {
    "==" => nil,
    "<=" => :or_older,
    ">=" => :or_newer,
  }.freeze,
  T::Hash[String, T.nilable(Symbol)],
)

Instance Method Summary collapse

Methods included from HelperFunctions

#block_method_called_in_block?, #check_precedence, #class_name, #component_precedes?, descendant_send_nodes, descendant_send_nodes_by_method_name, #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_name, #node_equals?, #offending_node, #parameters, #parameters_passed?, #problem, #regex_match_group, #source_buffer, #start_column, #string_content

Instance Method Details

#audit_arch_conditionals(body_node, allowed_methods: [], allowed_blocks: []) ⇒ void

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.

This method returns an undefined value.

Parameters:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'rubocops/shared/on_system_conditionals_helper.rb', line 95

def audit_arch_conditionals(body_node, allowed_methods: [], allowed_blocks: [])
  return unless body_node.source.include?("Hardware")

  ARCH_OPTIONS.each do |arch_option|
    else_method = (arch_option == :arm) ? :on_intel : :on_arm
    if_arch_node_search(body_node, arch: :"#{arch_option}?") do |if_node, else_node|
      next if node_is_allowed?(if_node, allowed_methods:, allowed_blocks:)

      if_statement_problem(if_node, "if Hardware::CPU.#{arch_option}?", "on_#{arch_option}",
                           else_method:, else_node:)
    end
  end

  [:arch, :arm?, :intel?].each do |method|
    hardware_cpu_search(body_node, method:) do |method_node|
      # These should already be caught by `if_arch_node_search`
      next if method_node.parent.source.start_with? "if #{method_node.source}"
      next if node_is_allowed?(method_node, allowed_methods:, allowed_blocks:)

      offending_node(method_node)
      problem "Instead of `#{method_node.source}`, use `on_arm` and `on_intel` blocks."
    end
  end
end

#audit_base_os_conditionals(body_node, allowed_methods: [], allowed_blocks: []) ⇒ void

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.

This method returns an undefined value.

Parameters:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'rubocops/shared/on_system_conditionals_helper.rb', line 126

def audit_base_os_conditionals(body_node, allowed_methods: [], allowed_blocks: [])
  return unless body_node.source.include?("OS")

  BASE_OS_OPTIONS.each do |base_os_option|
    os_method, else_method = if base_os_option == :macos
      [:mac?, :on_linux]
    else
      [:linux?, :on_macos]
    end
    if_base_os_node_search(body_node, base_os: os_method) do |if_node, else_node|
      next if node_is_allowed?(if_node, allowed_methods:, allowed_blocks:)

      if_statement_problem(if_node, "if OS.#{os_method}", "on_#{base_os_option}",
                           else_method:, else_node:)
    end
  end
end

#audit_macos_references(body_node, allowed_methods: [], allowed_blocks: []) ⇒ void

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.

This method returns an undefined value.

Parameters:



194
195
196
197
198
199
200
201
202
203
204
205
# File 'rubocops/shared/on_system_conditionals_helper.rb', line 194

def audit_macos_references(body_node, allowed_methods: [], allowed_blocks: [])
  return if !body_node.source.include?("MacOS") && !body_node.source.include?("OS")

  MACOS_MODULE_NAMES.each do |macos_module_name|
    find_const(body_node, macos_module_name) do |node|
      next if node_is_allowed?(node, allowed_methods:, allowed_blocks:)

      offending_node(node)
      problem "Don't use `#{macos_module_name}` where it could be called on Linux."
    end
  end
end

#audit_macos_version_conditionals(body_node, allowed_methods: [], allowed_blocks: [], recommend_on_system: true) ⇒ void

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.

This method returns an undefined value.

Parameters:



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'rubocops/shared/on_system_conditionals_helper.rb', line 152

def audit_macos_version_conditionals(body_node, allowed_methods: [], allowed_blocks: [],
                                     recommend_on_system: true)
  return unless body_node.source.include?("MacOS")

  MACOS_VERSION_OPTIONS.each do |macos_version_option|
    if_macos_version_node_search(body_node, os_version: macos_version_option) do |if_node, operator, else_node|
      next if node_is_allowed?(if_node, allowed_methods:, allowed_blocks:)

      else_node = T.let(else_node, T.nilable(RuboCop::AST::Node))
      autocorrect = else_node.blank? && MACOS_VERSION_CONDITIONALS.key?(operator.to_s)
      on_system_method_string = if recommend_on_system && operator == :<
        "on_system"
      elsif recommend_on_system && operator == :<=
        "on_system :linux, macos: :#{macos_version_option}_or_older"
      elsif operator != :== && MACOS_VERSION_CONDITIONALS.key?(operator.to_s)
        "on_#{macos_version_option} :#{MACOS_VERSION_CONDITIONALS[operator.to_s]}"
      else
        "on_#{macos_version_option}"
      end

      if_statement_problem(if_node, "if MacOS.version #{operator} :#{macos_version_option}",
                           on_system_method_string, autocorrect:)
    end

    macos_version_comparison_search(body_node, os_version: macos_version_option) do |method_node|
      # These should already be caught by `if_macos_version_node_search`
      next if method_node.parent.source.start_with? "if #{method_node.source}"
      next if node_is_allowed?(method_node, allowed_methods:, allowed_blocks:)

      offending_node(method_node)
      problem "Instead of `#{method_node.source}`, use `on_{macos_version}` blocks."
    end
  end
end

#audit_on_system_blocks(body_node, parent_name) ⇒ void

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.

This method returns an undefined value.

Parameters:



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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'rubocops/shared/on_system_conditionals_helper.rb', line 33

def audit_on_system_blocks(body_node, parent_name)
  return unless body_node.source.include?("on_")

  parent_string = if body_node.def_type?
    "def #{parent_name}"
  else
    "#{parent_name} do"
  end

  ON_SYSTEM_OPTIONS.each do |on_system_option|
    on_system_method = :"on_#{on_system_option}"
    if_statement_string = if ARCH_OPTIONS.include?(on_system_option)
      "if Hardware::CPU.#{on_system_option}?"
    elsif BASE_OS_OPTIONS.include?(on_system_option)
      "if OS.#{(on_system_option == :macos) ? "mac" : "linux"}?"
    elsif on_system_option == :system
      "if OS.linux? || MacOS.version"
    else
      "if MacOS.version"
    end

    find_every_method_call_by_name(body_node, on_system_method).each do |on_system_node|
      if_conditional = ""
      if MACOS_VERSION_OPTIONS.include? on_system_option
        on_macos_version_method_call(on_system_node, on_method: on_system_method) do |on_method_parameters|
          if on_method_parameters.empty?
            if_conditional = " == :#{on_system_option}"
          else
            if_condition_operator = MACOS_VERSION_CONDITIONALS.key(on_method_parameters.first)
            if_conditional = " #{if_condition_operator} :#{on_system_option}"
          end
        end
      elsif on_system_option == :system
        on_system_method_call(on_system_node) do |macos_symbol|
          base_os, condition = macos_symbol.to_s.split(/_(?=or_)/).map(&:to_sym)
          if_condition_operator = MACOS_VERSION_CONDITIONALS.key(condition)
          if_conditional = " #{if_condition_operator} :#{base_os}"
        end
      end

      @offensive_node = on_system_node
      problem "Instead of using `#{on_system_node.source}` in `#{parent_string}`, " \
              "use `#{if_statement_string}#{if_conditional}`." do |corrector|
        block_node = @offensive_node.parent
        next if block_node.type != :block

        # TODO: could fix corrector to handle this but punting for now.
        next if block_node.single_line?

        source_range = @offensive_node.source_range.join(@offensive_node.parent.loc.begin)
        corrector.replace(source_range, "#{if_statement_string}#{if_conditional}")
      end
    end
  end
end

#hardware_cpu_search(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


17
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 17

def hardware_cpu_search(node, *pattern, **kwargs, &block); end

#if_arch_node_search(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


27
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 27

def if_arch_node_search(node, *pattern, **kwargs, &block); end

#if_base_os_node_search(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


37
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 37

def if_base_os_node_search(node, *pattern, **kwargs, &block); end

#if_macos_version_node_search(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


47
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 47

def if_macos_version_node_search(node, *pattern, **kwargs, &block); end

#macos_version_comparison_search(node, *pattern, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


57
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 57

def macos_version_comparison_search(node, *pattern, **kwargs, &block); end

#on_macos_version_method_call(node, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


60
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 60

def on_macos_version_method_call(node, **kwargs, &block); end

#on_system_method_call(node, **kwargs, &block) ⇒ T.untyped

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.

Parameters:

Returns:

  • (T.untyped)


63
# File 'sorbet/rbi/dsl/rubo_cop/cop/on_system_conditionals_helper.rbi', line 63

def on_system_method_call(node, **kwargs, &block); end