Class: FormulaVersions

Inherits:
Object show all
Includes:
Context, Utils::Output::Mixin
Defined in:
formula_versions.rb

Overview

This class is part of an internal API. This class may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

Helper class for traversing a formula's previous versions.

Defined Under Namespace

Classes: LegacyBottleSpecification

Constant Summary collapse

IGNORED_EXCEPTIONS =

This constant is part of an internal API. This constant may only be used internally in repositories owned by Homebrew, except in casks or formulae. Third parties should avoid using this constant if possible, as it may be removed or changed without warning.

[
  ArgumentError, NameError, SyntaxError, TypeError, LegacyDSLError,
  FormulaSpecificationError, FormulaValidationError,
  ErrorDuringExecution, LoadError, MethodDeprecatedError
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils::Output::Mixin

#issue_reporting_message, #odebug, #odeprecated, #odie, #odisabled, #ofail, #oh1, #oh1_title, #ohai, #ohai_title, #onoe, #opoo, #opoo_outside_github_actions, #opoo_without_github_actions_annotation, #pretty_cannot_install, #pretty_deprecated, #pretty_disabled, #pretty_duration, #pretty_install_status, #pretty_installed, #pretty_uninstalled, #pretty_unmarked, #pretty_upgradable, #pretty_warning

Methods included from Context

current, current=, #debug?, #deferred_environment_expansion?, #quiet?, #verbose?, #with_context

Constructor Details

#initialize(formula) ⇒ 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.

Parameters:



64
65
66
67
68
69
70
71
72
73
74
# File 'formula_versions.rb', line 64

def initialize(formula)
  @name = T.let(formula.name, String)
  @path = T.let(formula.tap_path, Pathname)
  @repository = T.let(formula.tap!.path, Pathname)
  @relative_path = T.let(@path.relative_path_from(repository).to_s, String)
  # Also look at e.g. older homebrew-core paths before sharding.
  if (match = @relative_path.match(%r{^(HomebrewFormula|Formula)/(?:[a-z]|lib)/(.+)}))
    @old_relative_path = T.let("#{match[1]}/#{match[2]}", T.nilable(String))
  end
  @formula_at_revision = T.let({}, T::Hash[String, Formula])
end

Class Method Details

.legacy_formula_classT.class_of(Formula)

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.

Returns:



46
47
48
49
50
51
52
53
54
55
# File 'formula_versions.rb', line 46

def self.legacy_formula_class
  @legacy_formula_class ||= Class.new(Formula) do
    class << self
      define_method(:inherited) do |child|
        super(child)
        child.stable&.instance_variable_set(:@bottle_specification, LegacyBottleSpecification.new)
      end
    end
  end
end

Instance Method Details

#formula_at_revision(revision, formula_relative_path = relative_path, &_block) ⇒ T.type_parameter(:U)?

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:

  • revision (String)
  • formula_relative_path (String) (defaults to: relative_path)
  • _block (T.proc.params(arg0: Formula).returns(T.type_parameter(:U)))

Returns:

  • (T.type_parameter(:U), nil)


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'formula_versions.rb', line 96

def formula_at_revision(revision, formula_relative_path = relative_path, &_block)
  Homebrew.raise_deprecation_exceptions = true

  formula = @formula_at_revision[revision] || begin
    nostdout do
      Formulary.from_contents(
        name,
        path,
        file_contents_at_revision(revision, formula_relative_path)
          .sub(/\A(?:(?:[ \t]*#[^\n]*\n|[ \t]*\n)|(?:=begin[^\n]*(?:\n|\z).*?^=end[^\n]*(?:\n|\z)))*/m) do |header|
            "#{header}Formula = ::FormulaVersions.legacy_formula_class;"
          end,
        ignore_errors: true,
      )
    end
  rescue FormulaUnavailableError
    nil
  rescue Homebrew::UntrustedTapError, MacOSVersion::Error
    raise
  rescue StandardError, ScriptError => e
    raise if Homebrew::EnvConfig.disable_load_formula?

    require "utils/backtrace"

    # We rescue these so that we can skip bad versions and
    # continue walking the history
    odebug "#{e} in #{name} at revision #{revision}", Utils::Backtrace.clean(e)
    nil
  end

  return if formula.nil?

  @formula_at_revision[revision] = formula
  yield formula
ensure
  Homebrew.raise_deprecation_exceptions = false
end

#rev_list(branch, &_block) ⇒ 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:



77
78
79
80
81
82
83
84
85
86
# File 'formula_versions.rb', line 77

def rev_list(branch, &_block)
  repository.cd do
    rev_list_cmd = ["git", "rev-list", "--abbrev-commit", "--remove-empty"]
    [relative_path, old_relative_path].compact.each do |entry|
      Utils.popen_read(*rev_list_cmd, branch, "--", entry) do |io|
        yield io.readline.chomp, entry until io.eof?
      end
    end
  end
end