Module: Homebrew::Install Private

Included in:
Homebrew
Defined in:
install.rb,
extend/os/linux/install.rb

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.

Helper module for performing (pre-)install checks.

Class Method Summary collapse

Class Method Details

.check_prefixObject

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.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'install.rb', line 33

def check_prefix
  if (Hardware::CPU.intel? || Hardware::CPU.in_rosetta2?) &&
     HOMEBREW_PREFIX.to_s == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX
    if Hardware::CPU.in_rosetta2?
      odie <<~EOS
        Cannot install under Rosetta 2 in ARM default prefix (#{HOMEBREW_PREFIX})!
        To rerun under ARM use:
            arch -arm64 brew install ...
        To install under x86_64, install Homebrew into #{HOMEBREW_DEFAULT_PREFIX}.
      EOS
    else
      odie "Cannot install on Intel processor in ARM default prefix (#{HOMEBREW_PREFIX})!"
    end
  elsif Hardware::CPU.arm? && HOMEBREW_PREFIX.to_s == HOMEBREW_DEFAULT_PREFIX
    odie <<~EOS
      Cannot install in Homebrew on ARM processor in Intel default prefix (#{HOMEBREW_PREFIX})!
      Please create a new installation in #{HOMEBREW_MACOS_ARM_DEFAULT_PREFIX} using one of the
      "Alternative Installs" from:
        #{Formatter.url("https://docs.brew.sh/Installation")}
      You can migrate your previously installed formula list with:
        brew bundle dump
    EOS
  end
end

.install_formula(f, build_bottle: false, force_bottle: false, bottle_arch: nil, ignore_deps: false, only_deps: false, include_test_formulae: [], build_from_source_formulae: [], cc: nil, git: false, interactive: false, keep_tmp: false, force: false, debug: false, quiet: false, verbose: false) ⇒ 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.



232
233
234
235
236
237
238
239
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'install.rb', line 232

def install_formula(
  f,
  build_bottle: false,
  force_bottle: false,
  bottle_arch: nil,
  ignore_deps: false,
  only_deps: false,
  include_test_formulae: [],
  build_from_source_formulae: [],
  cc: nil,
  git: false,
  interactive: false,
  keep_tmp: false,
  force: false,
  debug: false,
  quiet: false,
  verbose: false
)
  f.print_tap_action
  build_options = f.build

  fi = FormulaInstaller.new(
    f,
    options:                    build_options.used_options,
    build_bottle:               build_bottle,
    force_bottle:               force_bottle,
    bottle_arch:                bottle_arch,
    ignore_deps:                ignore_deps,
    only_deps:                  only_deps,
    include_test_formulae:      include_test_formulae,
    build_from_source_formulae: build_from_source_formulae,
    cc:                         cc,
    git:                        git,
    interactive:                interactive,
    keep_tmp:                   keep_tmp,
    force:                      force,
    debug:                      debug,
    quiet:                      quiet,
    verbose:                    verbose,
  )

  if f.linked_keg.directory?
    if Homebrew::EnvConfig.no_install_upgrade?
      message = <<~EOS
        #{f.name} #{f.linked_version} is already installed
      EOS
      message += if f.outdated? && !f.head?
        <<~EOS
          To upgrade to #{f.pkg_version}, run:
            brew upgrade #{f.full_name}
        EOS
      else
        <<~EOS
          To install #{f.pkg_version}, first run:
            brew unlink #{f.name}
        EOS
      end
      raise CannotInstallFormulaError, message unless only_deps
    elsif f.outdated? && !f.head?
      puts "#{f.name} #{f.linked_version} is installed but outdated"
      kegs = Upgrade.outdated_kegs(f)
      linked_kegs = kegs.select(&:linked?)
      Upgrade.print_upgrade_message(f, fi.options)
    end
  end

  fi.prelude
  fi.fetch

  kegs.each(&:unlink) if kegs.present?

  fi.install
  fi.finish
rescue FormulaInstallationAlreadyAttemptedError
  # We already attempted to install f as part of the dependency tree of
  # another formula. In that case, don't generate an error, just move on.
  nil
rescue CannotInstallFormulaError => e
  ofail e.message
ensure
  # Re-link kegs if upgrade fails
  begin
    linked_kegs.each(&:link) if linked_kegs.present? && !f.latest_version_installed?
    rescue
      nil
  end
end

.install_formula?(f, head: false, fetch_head: false, only_dependencies: false, force: false, quiet: false) ⇒ 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.

Returns:

  • (Boolean)


95
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'install.rb', line 95

def install_formula?(
  f,
  head: false,
  fetch_head: false,
  only_dependencies: false,
  force: false,
  quiet: false
)
  # head-only without --HEAD is an error
  if !head && f.stable.nil?
    odie <<~EOS
      #{f.full_name} is a head-only formula.
      To install it, run:
        brew install --HEAD #{f.full_name}
    EOS
  end

  # --HEAD, fail with no head defined
  odie "No head is defined for #{f.full_name}" if head && f.head.nil?

  installed_head_version = f.latest_head_version
  if installed_head_version &&
     !f.head_version_outdated?(installed_head_version, fetch_head: fetch_head)
    new_head_installed = true
  end
  prefix_installed = f.prefix.exist? && !f.prefix.children.empty?

  if f.keg_only? && f.any_version_installed? && f.optlinked? && !force
    # keg-only install is only possible when no other version is
    # linked to opt, because installing without any warnings can break
    # dependencies. Therefore before performing other checks we need to be
    # sure --force flag is passed.
    if f.outdated?
      return true unless Homebrew::EnvConfig.no_install_upgrade?

      optlinked_version = Keg.for(f.opt_prefix).version
      onoe <<~EOS
        #{f.full_name} #{optlinked_version} is already installed.
        To upgrade to #{f.version}, run:
          brew upgrade #{f.full_name}
      EOS
    elsif only_dependencies
      return true
    elsif !quiet
      opoo <<~EOS
        #{f.full_name} #{f.pkg_version} is already installed and up-to-date.
        To reinstall #{f.pkg_version}, run:
          brew reinstall #{f.name}
      EOS
    end
  elsif (head && new_head_installed) || prefix_installed
    # After we're sure that --force flag is passed for linked to opt
    # keg-only we need to be sure that the version we're attempting to
    # install is not already installed.

    installed_version = if head
      f.latest_head_version
    else
      f.pkg_version
    end

    msg = "#{f.full_name} #{installed_version} is already installed"
    linked_not_equals_installed = f.linked_version != installed_version
    if f.linked? && linked_not_equals_installed
      msg = if quiet
        nil
      else
        <<~EOS
          #{msg}.
          The currently linked version is: #{f.linked_version}
        EOS
      end
    elsif !f.linked? || f.keg_only?
      msg = <<~EOS
        #{msg}, it's just not linked.
        To link this version, run:
          brew link #{f}
      EOS
    elsif only_dependencies
      msg = nil
      return true
    else
      msg = if quiet
        nil
      else
        <<~EOS
          #{msg} and up-to-date.
          To reinstall #{f.pkg_version}, run:
            brew reinstall #{f.name}
        EOS
      end
    end
    opoo msg if msg
  elsif !f.any_version_installed? && (old_formula = f.old_installed_formulae.first)
    msg = "#{old_formula.full_name} #{old_formula.any_installed_version} already installed"
    msg = if !old_formula.linked? && !old_formula.keg_only?
      <<~EOS
        #{msg}, it's just not linked.
        To link this version, run:
          brew link #{old_formula.full_name}
      EOS
    elsif quiet
      nil
    else
      "#{msg}."
    end
    opoo msg if msg
  elsif f.migration_needed? && !force
    # Check if the formula we try to install is the same as installed
    # but not migrated one. If --force is passed then install anyway.
    opoo <<~EOS
      #{f.oldname} is already installed, it's just not migrated.
      To migrate this formula, run:
        brew migrate #{f}
      Or to force-install it, run:
        brew install #{f} --force
    EOS
  else
    # If none of the above is true and the formula is linked, then
    # FormulaInstaller will handle this case.
    return true
  end

  # Even if we don't install this formula mark it as no longer just
  # installed as a dependency.
  return false unless f.opt_prefix.directory?

  keg = Keg.new(f.opt_prefix.resolved_path)
  tab = Tab.for_keg(keg)
  unless tab.installed_on_request
    tab.installed_on_request = true
    tab.write
  end

  false
end

.perform_build_from_source_checks(all_fatal: false) ⇒ 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.



28
29
30
31
# File 'install.rb', line 28

def perform_build_from_source_checks(all_fatal: false)
  Diagnostic.checks(:fatal_build_from_source_checks)
  Diagnostic.checks(:build_from_source_checks, fatal: all_fatal)
end

.perform_preinstall_checks(all_fatal: false, cc: nil) ⇒ Object Also known as: generic_perform_preinstall_checks

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.



20
21
22
23
# File 'extend/os/linux/install.rb', line 20

def perform_preinstall_checks(all_fatal: false, cc: nil)
  generic_perform_preinstall_checks(all_fatal: all_fatal, cc: cc)
  symlink_ld_so
end