Module: RuboCop::Cop::InstallStepsHelper Private

Included in:
Cask::InstallSteps, FormulaAudit::InstallSteps
Defined in:
rubocops/shared/install_steps_helper.rbi,
rubocops/shared/install_steps_helper.rb

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.

Defined Under Namespace

Classes: InstallStepPath

Constant Summary collapse

OFFICIAL_HOMEBREW_TAP_PATH_REGEX =

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.

%r{(?:\A|/)Taps/homebrew/homebrew-[\w-]+/}i
FILE_PREPARATION_STEP_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.

[:mkdir, :mkdir_p, :touch, :move, :mv, :move_children, :move_contents, :copy, :remove, :inreplace,
:symlink,
:ln_s, :ln_sf].freeze
[:link_dir, :link_children, :symlink_tree, :symlink_children].freeze
CONFIG_WRITE_STEP_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.

[:write, :write_file].freeze
SERVICE_DATA_STEP_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.

[:init_data_dir].freeze
REBUILD_ACTION_STEP_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.

[:compile_gsettings_schemas, :gio_querymodules, :update_gio_modules_cache, :gdk_pixbuf_query_loaders,
:update_gdk_pixbuf_loaders_cache, :gtk_update_icon_cache, :update_gtk_icon_cache,
:update_mime_database, :update_desktop_database].freeze
KEYCHAIN_STEP_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.

[:delete_keychain_certificate, :delete_keychain_certificates].freeze
PERMISSION_STEP_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.

[:set_permissions, :set_ownership].freeze
COMMAND_STEP_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.

[:run, :terminate_process].freeze
MACHO_STEP_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.

[:change_dylib_id].freeze
NOTICE_STEP_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.

[:warn].freeze
FORMULA_ACTION_STEP_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.

[:configure_gcc_runtime, :install_gzipped_executable, :configure_glibc_runtime,
:configure_clang_system, :configure_php, :bootstrap_cpython, :bootstrap_pypy].freeze
STEP_SCOPE_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.

[:if_path_exists, :unless_path_exists, :on_macos, :on_linux].freeze
COMPATIBILITY_STEP_METHOD_REPLACEMENTS =

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(
  {
    mkdir:                       :mkdir_p,
    mv:                          :move,
    move_children:               :move_contents,
    ln_s:                        :symlink,
    ln_sf:                       :symlink,
    link_dir:                    :symlink_tree,
    link_children:               :symlink_children,
    write:                       :write_file,
    gio_querymodules:            :update_gio_modules_cache,
    gdk_pixbuf_query_loaders:    :update_gdk_pixbuf_loaders_cache,
    gtk_update_icon_cache:       :update_gtk_icon_cache,
    delete_keychain_certificate: :delete_keychain_certificates,
  }.freeze,
  T::Hash[Symbol, Symbol],
)
COMPATIBILITY_STEP_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.

T.let(COMPATIBILITY_STEP_METHOD_REPLACEMENTS.keys.freeze, T::Array[Symbol])
COMPATIBILITY_STEP_KEYWORD_REPLACEMENTS =

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(
  {
    move:                         { force: :overwrite }.freeze,
    mv:                           { force: :overwrite }.freeze,
    symlink:                      { force: :overwrite, uninstall: :remove_on_uninstall }.freeze,
    ln_s:                         { force: :overwrite, uninstall: :remove_on_uninstall }.freeze,
    ln_sf:                        { uninstall: :remove_on_uninstall }.freeze,
    delete_keychain_certificate:  { matching_certificate: :fingerprint_of }.freeze,
    delete_keychain_certificates: { matching_certificate: :fingerprint_of }.freeze,
  }.freeze,
  T::Hash[Symbol, T::Hash[Symbol, Symbol]],
)
ALLOWED_STEP_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.

T.let(
  [*FILE_PREPARATION_STEP_METHODS, *LINK_STEP_METHODS, *CONFIG_WRITE_STEP_METHODS, *SERVICE_DATA_STEP_METHODS,
   *REBUILD_ACTION_STEP_METHODS, :set_permissions, *COMMAND_STEP_METHODS, *NOTICE_STEP_METHODS,
   *MACHO_STEP_METHODS, *FORMULA_ACTION_STEP_METHODS, *STEP_SCOPE_METHODS].freeze,
  T::Array[Symbol],
)
CASK_ALLOWED_STEP_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.

T.let(
  [*FILE_PREPARATION_STEP_METHODS, *CONFIG_WRITE_STEP_METHODS, *KEYCHAIN_STEP_METHODS,
   *PERMISSION_STEP_METHODS, *COMMAND_STEP_METHODS, *MACHO_STEP_METHODS, *STEP_SCOPE_METHODS].freeze,
  T::Array[Symbol],
)
ALLOWED_STEP_ARGUMENT_NODE_TYPES =

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.

dstr covers heredocs such as write content; interpolation is limited to known template values below.

[:array, :dstr, :hash, :int, :nil, :pair, :regexp, :regopt, :str,
:sym].freeze
STEP_BLOCK_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.

T.let(
  "Steps blocks may only contain install step DSL calls. Prefer canonical calls: " \
  "#{(ALLOWED_STEP_METHODS - COMPATIBILITY_STEP_METHODS).map { |method| "`#{method}`" }.join(", ")}.".freeze,
  String,
)
BREW_RUBY_STEP_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.

"Install steps must not use `brew ruby` because it enables developer mode."
LEGACY_STEP_METHOD_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.

"Use `%<replacement>s` instead of legacy install step `%<method>s`."
LEGACY_STEP_KEYWORD_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.

"Use `%<replacement>s:` instead of legacy install step keyword `%<keyword>s:`."
SIMPLE_STEP_CONVERSION_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.

"Use `%<steps_block>s` for simple file preparation."
REBUILD_ACTION_STEP_LINES =

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(
  T.let([
    [
      "system Formula[\"glib\"].opt_bin/\"glib-compile-schemas\", " \
      "HOMEBREW_PREFIX/\"share/glib-2.0/schemas\"",
      "compile_gsettings_schemas",
    ],
    [
      "system Formula[\"gdk-pixbuf\"].opt_bin/\"gdk-pixbuf-query-loaders\", " \
      "\"--update-cache\"",
      "update_gdk_pixbuf_loaders_cache",
    ],
    [
      "system Formula[\"gtk+3\"].opt_bin/\"gtk3-update-icon-cache\", " \
      "\"-q\", \"-t\", \"-f\", HOMEBREW_PREFIX/\"share/icons/hicolor\"",
      "update_gtk_icon_cache",
    ],
    [
      "system Formula[\"shared-mime-info\"].opt_bin/\"update-mime-database\", " \
      "HOMEBREW_PREFIX/\"share/mime\"",
      "update_mime_database",
    ],
    [
      "system Formula[\"desktop-file-utils\"].opt_bin/\"update-desktop-database\", " \
      "HOMEBREW_PREFIX/\"share/applications\"",
      "update_desktop_database",
    ],
  ], T::Array[[String, String]]).to_h.freeze,
  T::Hash[String, String],
)

Instance Method Summary collapse

Instance Method Details

#add_compatibility_step_offenses(block_node, allowed_methods: ALLOWED_STEP_METHODS) ⇒ 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:



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'rubocops/shared/install_steps_helper.rb', line 132

def add_compatibility_step_offenses(block_node, allowed_methods: ALLOWED_STEP_METHODS)
  block_node.each_descendant(:send) do |node|
    send_node = T.cast(node, RuboCop::AST::SendNode)
    method = send_node.method_name
    next if send_node.receiver || !allowed_methods.include?(method)

    if (replacement = COMPATIBILITY_STEP_METHOD_REPLACEMENTS[method])
      add_offense(send_node.loc.selector,
                  message: Kernel.format(LEGACY_STEP_METHOD_MSG, method:, replacement:)) do |corrector|
        corrector.replace(send_node.loc.selector, replacement.to_s)
        add_compatibility_step_method_corrections(corrector, send_node)
      end
    end
    add_compatibility_step_keyword_offenses(send_node)
  end
end

#append_install_step_lines(corrector, block_node, step_lines) ⇒ 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:



242
243
244
245
246
247
248
249
# File 'rubocops/shared/install_steps_helper.rb', line 242

def append_install_step_lines(corrector, block_node, step_lines)
  block_indent = block_node.source_range.column
  step_source = indented_install_step_lines(step_lines, block_indent + 2).join("\n")
  corrector.insert_before(
    block_node.loc.end,
    "#{step_source.delete_prefix(" " * block_indent)}\n#{" " * block_indent}",
  )
end

#brew_ruby_step_node(block_node) ⇒ RuboCop::AST::Node?

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:



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'rubocops/shared/install_steps_helper.rb', line 175

def brew_ruby_step_node(block_node)
  return if block_node.nil?

  block_node.each_descendant(:send).each do |node|
    send_node = T.cast(node, RuboCop::AST::SendNode)
    next if send_node.receiver.present? || send_node.method_name != :run

    command = send_node.first_argument
    next unless command&.str_type?
    next if command.str_content != "{{HOMEBREW_BREW_FILE}}"

    options = send_node.arguments.last
    next unless options&.hash_type?

    args = T.cast(options, RuboCop::AST::HashNode).pairs.find do |pair|
      pair.key.sym_type? && pair.key.value == :args
    end&.value
    next unless args&.array_type?

    first_arg = args.child_nodes.first
    return command if first_arg&.str_type? && first_arg.str_content == "ruby"
  end

  nil
end

#direct_install_step_nodes(body_node) ⇒ Array<RuboCop::AST::Node>

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:



252
253
254
255
256
# File 'rubocops/shared/install_steps_helper.rb', line 252

def direct_install_step_nodes(body_node)
  return [] if body_node.nil?

  body_node.begin_type? ? body_node.child_nodes : [body_node]
end

#install_step_block_offense_node(block_node, allowed_methods: ALLOWED_STEP_METHODS) ⇒ RuboCop::AST::Node?

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:



161
162
163
164
165
166
167
168
169
170
171
172
# File 'rubocops/shared/install_steps_helper.rb', line 161

def install_step_block_offense_node(block_node, allowed_methods: ALLOWED_STEP_METHODS)
  return if block_node.nil?
  return if (body = block_node.body).nil?

  direct_nodes = body.begin_type? ? body.child_nodes : [body]
  direct_nodes.each do |node|
    offense_node = install_step_offense_node(node, allowed_methods)
    return offense_node if offense_node
  end

  nil
end

#install_steps_block_source(block_name, step_lines, indent) ⇒ String

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:



226
227
228
229
230
231
232
233
# File 'rubocops/shared/install_steps_helper.rb', line 226

def install_steps_block_source(block_name, step_lines, indent)
  block_indent = " " * indent
  [
    "#{block_name} do",
    *indented_install_step_lines(step_lines, indent + 2),
    "#{block_indent}end",
  ].join("\n")
end

#normalised_install_step_source(node) ⇒ String

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:



259
260
261
# File 'rubocops/shared/install_steps_helper.rb', line 259

def normalised_install_step_source(node)
  node.source.lines.reject { |line| line.lstrip.start_with?("#") }.join.gsub(/\s+/, " ").strip
end

#official_homebrew_tap?(file_path) ⇒ Boolean

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:

  • (Boolean)


116
117
118
# File 'rubocops/shared/install_steps_helper.rb', line 116

def official_homebrew_tap?(file_path)
  file_path.match?(OFFICIAL_HOMEBREW_TAP_PATH_REGEX)
end

#simple_install_step_lines(body_node, default_base:, default_source_base:, default_target_base:, rebuild_actions: true, permission_actions: false) ⇒ Array<String>?

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:

  • body_node (RuboCop::AST::Node, nil)
  • default_base (Symbol)
  • default_source_base (Symbol)
  • default_target_base (Symbol)
  • rebuild_actions (Boolean) (defaults to: true)
  • permission_actions (Boolean) (defaults to: false)

Returns:



211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'rubocops/shared/install_steps_helper.rb', line 211

def simple_install_step_lines(body_node, default_base:, default_source_base:, default_target_base:,
                              rebuild_actions: true, permission_actions: false)
  return if body_node.nil?

  direct_nodes = body_node.begin_type? ? body_node.child_nodes : [body_node]
  step_lines = direct_nodes.map do |node|
    simple_install_step_line(node, default_base:, default_source_base:, default_target_base:, rebuild_actions:,
                             permission_actions:)
  end
  return if step_lines.any?(&:nil?)

  T.cast(step_lines, T::Array[String])
end

#step_block_msg(allowed_methods) ⇒ String

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:



121
122
123
124
# File 'rubocops/shared/install_steps_helper.rb', line 121

def step_block_msg(allowed_methods)
  "Steps blocks may only contain install step DSL calls. Prefer canonical calls: " \
    "#{(allowed_methods - COMPATIBILITY_STEP_METHODS).map { |method| "`#{method}`" }.join(", ")}."
end