Module: Utils::Path Private

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.

Helpers for Homebrew path handling and package path validation.

Defined Under Namespace

Modules: FormulaHelpers, Helpers

Class Method Summary collapse

Methods included from Helpers

child_of?, cp_path_sub, ensure_child_of!, ensure_writable, resolved_path, resolved_path_exists?, rmdir_if_possible, text_executable?

Methods included from FormulaHelpers

formula_any_version_installed?, formula_opt_bin, formula_opt_include, formula_opt_lib, formula_opt_libexec, formula_opt_prefix

Class Method Details

.formula_installed_prefixes(formula_names) ⇒ Array<Pathname>

The installed prefix directories for one or more formula names.

Parameters:

Returns:



215
216
217
218
219
220
221
# File 'utils/path.rb', line 215

def self.formula_installed_prefixes(formula_names)
  Array(formula_names).map { |formula_name| HOMEBREW_CELLAR/Utils.name_from_full_name(formula_name) }
                      .select(&:directory?)
                      .uniq(&:realpath)
                      .flat_map(&:subdirs)
                      .sort_by(&:basename)
end

.formula_opt_bin_env(formula_name, *paths) ⇒ Hash{String => String}

An environment hash with PATH prepended by a formula's stable bin directory.

Parameters:

Returns:



235
236
237
# File 'utils/path.rb', line 235

def self.formula_opt_bin_env(formula_name, *paths)
  { "PATH" => formula_opt_bin_path(formula_name, *paths).to_s }
end

.formula_opt_bin_path(formula_name, *paths) ⇒ PATH

The current PATH with a formula's stable bin directory prepended.

Parameters:

Returns:



227
228
229
# File 'utils/path.rb', line 227

def self.formula_opt_bin_path(formula_name, *paths)
  PATH.new(formula_opt_bin(formula_name), *paths, ENV.fetch("PATH"))
end

.install_info(path, verbose: false) ⇒ 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:

  • path (Pathname)
  • verbose (Boolean) (defaults to: false)


135
136
137
138
# File 'utils/path.rb', line 135

def self.install_info(path, verbose: false)
  SystemCommand.quiet_system(install_info_executable, "--quiet", path.to_s, (path.dirname/"dir").to_s)
  puts "info #{path}" if verbose
end

.loadable_package_path?(path, package_type) ⇒ 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)


240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'utils/path.rb', line 240

def self.loadable_package_path?(path, package_type)
  return true unless Homebrew::EnvConfig.forbid_packages_from_paths?

  path_realpath = path.realpath.to_s
  path_string = path.to_s

  allowed_paths = [trusted_package_root("#{HOMEBREW_LIBRARY}/Taps/")]
  allowed_paths << if package_type == :formula
    trusted_package_root(HOMEBREW_CELLAR)
  else
    trusted_package_root(Cask::Caskroom.path)
  end

  # Casks can also be loaded from local JSON files, not just Ruby.
  package_extnames = (package_type == :cask) ? %w[.rb .json] : %w[.rb]
  return true if package_extnames.none? { |ext| path_realpath.end_with?(ext) || path_string.end_with?(ext) }

  # Compare path ancestry, not string prefixes, so `..` can't escape a trusted root.
  return true if allowed_paths.any? { |root| child_of?(root, path_realpath) }
  return true if allowed_paths.any? { |root| child_of?(root, path) }

  # Looks like a local path, Ruby file and not a tap.
  if path_string.include?("./") || path_string.end_with?(".rb") || path_string.count("/") != 2
    package_type_plural = Utils.pluralize(package_type.to_s, 2)
    path_realpath_if_different = " (#{path_realpath})" if path_realpath != path_string
    create_flag = " --cask" if package_type == :cask

    raise <<~WARNING
      Homebrew requires #{package_type_plural} to be in a tap, rejecting:
        #{path_string}#{path_realpath_if_different}

      To create a tap, run e.g.
        brew tap-new <user|org>/<repository>
      To create a #{package_type} in a tap run e.g.
        brew create#{create_flag} <url> --tap=<user|org>/<repository>
    WARNING
  else
    # Looks like a tap, let's quietly reject but not error.
    path_string.count("/") != 2
  end
end

.uninstall_info(path, verbose: false) ⇒ 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:

  • path (Pathname)
  • verbose (Boolean) (defaults to: false)


141
142
143
144
# File 'utils/path.rb', line 141

def self.uninstall_info(path, verbose: false)
  SystemCommand.quiet_system(install_info_executable, "--delete", "--quiet", path.to_s, (path.dirname/"dir").to_s)
  puts "uninfo #{path}" if verbose
end