2020-10-20 12:03:48 +02:00
|
|
|
# typed: true
|
2019-04-19 15:38:03 +09:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-02-20 12:28:59 +00:00
|
|
|
# Never `require` anything in this file (except English). It needs to be able to
|
|
|
|
# work as the first item in `brew.rb` so we can load gems with Bundler when
|
|
|
|
# needed before anything else is loaded (e.g. `json`).
|
|
|
|
|
|
|
|
require "English"
|
|
|
|
|
|
|
|
module Homebrew
|
2020-11-05 17:17:03 -05:00
|
|
|
# Keep in sync with the `Gemfile.lock`'s BUNDLED WITH.
|
2020-09-20 03:18:58 +02:00
|
|
|
HOMEBREW_BUNDLER_VERSION = "1.17.3"
|
2020-01-01 15:47:06 +00:00
|
|
|
|
2019-02-20 12:28:59 +00:00
|
|
|
module_function
|
|
|
|
|
|
|
|
def ruby_bindir
|
2019-04-19 15:38:03 +09:00
|
|
|
"#{RbConfig::CONFIG["prefix"]}/bin"
|
2019-02-20 12:28:59 +00:00
|
|
|
end
|
|
|
|
|
2020-11-29 16:09:10 +01:00
|
|
|
def gem_user_dir
|
|
|
|
ENV["HOMEBREW_TESTS_GEM_USER_DIR"] || Gem.user_dir
|
|
|
|
end
|
|
|
|
|
2019-02-26 22:13:00 +00:00
|
|
|
def gem_user_bindir
|
2020-11-29 16:09:10 +01:00
|
|
|
"#{gem_user_dir}/bin"
|
2019-02-26 22:13:00 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def ohai_if_defined(message)
|
|
|
|
if defined?(ohai)
|
2020-11-28 20:33:24 +01:00
|
|
|
$stderr.ohai message
|
2019-02-26 22:13:00 +00:00
|
|
|
else
|
2020-11-28 20:33:24 +01:00
|
|
|
$stderr.puts "==> #{message}"
|
2019-02-26 22:13:00 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-25 15:59:17 +00:00
|
|
|
def opoo_if_defined(message)
|
|
|
|
if defined?(opoo)
|
|
|
|
$stderr.opoo message
|
|
|
|
else
|
|
|
|
$stderr.puts "Warning: #{message}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-26 22:13:00 +00:00
|
|
|
def odie_if_defined(message)
|
|
|
|
if defined?(odie)
|
|
|
|
odie message
|
|
|
|
else
|
|
|
|
$stderr.puts "Error: #{message}"
|
|
|
|
exit 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-24 18:04:26 +00:00
|
|
|
def setup_gem_environment!(gem_home: nil, gem_bindir: nil, setup_path: true)
|
2019-02-20 12:28:59 +00:00
|
|
|
# Match where our bundler gems are.
|
2019-02-26 22:13:00 +00:00
|
|
|
gem_home ||= "#{ENV["HOMEBREW_LIBRARY"]}/Homebrew/vendor/bundle/ruby/#{RbConfig::CONFIG["ruby_version"]}"
|
2021-02-27 15:50:08 +00:00
|
|
|
Gem.paths = {
|
|
|
|
"GEM_HOME" => gem_home,
|
|
|
|
"GEM_PATH" => gem_home,
|
|
|
|
}
|
2019-02-20 12:28:59 +00:00
|
|
|
|
2020-04-05 15:30:50 +02:00
|
|
|
# Set TMPDIR so Xcode's `make` doesn't fall back to `/var/tmp/`,
|
|
|
|
# which may be not user-writable.
|
|
|
|
ENV["TMPDIR"] = ENV["HOMEBREW_TEMP"]
|
|
|
|
|
2021-02-24 18:04:26 +00:00
|
|
|
return unless setup_path
|
|
|
|
|
2020-11-29 16:09:10 +01:00
|
|
|
# Add necessary Ruby and Gem binary directories to `PATH`.
|
2019-02-26 22:13:00 +00:00
|
|
|
gem_bindir ||= Gem.bindir
|
2020-10-20 12:03:48 +02:00
|
|
|
paths = ENV.fetch("PATH").split(":")
|
2019-02-26 22:13:00 +00:00
|
|
|
paths.unshift(gem_bindir) unless paths.include?(gem_bindir)
|
2020-04-05 15:38:10 +01:00
|
|
|
paths.unshift(ruby_bindir) unless paths.include?(ruby_bindir)
|
2019-02-20 12:28:59 +00:00
|
|
|
ENV["PATH"] = paths.compact.join(":")
|
2021-02-28 01:26:08 +00:00
|
|
|
|
|
|
|
# Set envs so the above binaries can be invoked.
|
|
|
|
# We don't do this unless requested as some formulae may invoke system Ruby instead of ours.
|
|
|
|
ENV["GEM_HOME"] = gem_home
|
|
|
|
ENV["GEM_PATH"] = gem_home
|
2019-02-20 12:28:59 +00:00
|
|
|
end
|
|
|
|
|
2019-02-28 08:31:18 +00:00
|
|
|
def install_gem!(name, version: nil, setup_gem_environment: true)
|
2019-02-26 22:13:00 +00:00
|
|
|
setup_gem_environment! if setup_gem_environment
|
2019-02-20 12:28:59 +00:00
|
|
|
|
2021-02-28 01:26:08 +00:00
|
|
|
specs = Gem::Specification.find_all_by_name(name, version)
|
|
|
|
|
|
|
|
if specs.empty?
|
|
|
|
ohai_if_defined "Installing '#{name}' gem"
|
|
|
|
# document: [] , is equivalent to --no-document
|
|
|
|
specs = Gem.install name, version, document: []
|
|
|
|
end
|
|
|
|
|
2021-03-26 20:36:26 +00:00
|
|
|
specs += specs.flat_map(&:runtime_dependencies)
|
|
|
|
.flat_map(&:to_specs)
|
|
|
|
|
|
|
|
# Add the specs to the $LOAD_PATH.
|
2021-02-28 01:26:08 +00:00
|
|
|
specs.each do |spec|
|
|
|
|
spec.require_paths.each do |path|
|
|
|
|
full_path = File.join(spec.full_gem_path, path)
|
|
|
|
$LOAD_PATH.unshift full_path unless $LOAD_PATH.include?(full_path)
|
|
|
|
end
|
|
|
|
end
|
2020-06-04 11:36:58 +05:30
|
|
|
rescue Gem::UnsatisfiableDependencyError
|
2019-02-26 22:13:00 +00:00
|
|
|
odie_if_defined "failed to install the '#{name}' gem."
|
2019-02-20 12:28:59 +00:00
|
|
|
end
|
|
|
|
|
2019-02-28 08:31:18 +00:00
|
|
|
def install_gem_setup_path!(name, version: nil, executable: name, setup_gem_environment: true)
|
|
|
|
install_gem!(name, version: version, setup_gem_environment: setup_gem_environment)
|
2019-10-30 13:49:17 +00:00
|
|
|
return if find_in_path(executable)
|
2019-02-20 12:28:59 +00:00
|
|
|
|
2019-02-26 22:13:00 +00:00
|
|
|
odie_if_defined <<~EOS
|
|
|
|
the '#{name}' gem is installed but couldn't find '#{executable}' in the PATH:
|
2019-04-01 16:02:13 -04:00
|
|
|
#{ENV["PATH"]}
|
2019-02-20 12:28:59 +00:00
|
|
|
EOS
|
|
|
|
end
|
|
|
|
|
2019-10-30 13:49:17 +00:00
|
|
|
def find_in_path(executable)
|
2020-10-20 12:03:48 +02:00
|
|
|
ENV.fetch("PATH").split(":").find do |path|
|
|
|
|
File.executable?(File.join(path, executable))
|
2019-10-30 13:49:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-20 12:28:59 +00:00
|
|
|
def install_bundler!
|
2020-11-29 16:09:10 +01:00
|
|
|
setup_gem_environment!(gem_home: gem_user_dir, gem_bindir: gem_user_bindir)
|
2020-01-01 15:47:06 +00:00
|
|
|
install_gem_setup_path!(
|
|
|
|
"bundler",
|
|
|
|
version: HOMEBREW_BUNDLER_VERSION,
|
|
|
|
executable: "bundle",
|
|
|
|
setup_gem_environment: false,
|
|
|
|
)
|
2019-02-20 12:28:59 +00:00
|
|
|
end
|
|
|
|
|
2021-03-10 04:46:39 +00:00
|
|
|
def install_bundler_gems!(only_warn_on_failure: false, setup_path: true)
|
|
|
|
old_path = ENV["PATH"]
|
|
|
|
old_gem_path = ENV["GEM_PATH"]
|
|
|
|
old_gem_home = ENV["GEM_HOME"]
|
2021-03-27 02:15:56 +00:00
|
|
|
old_bundle_gemfile = ENV["BUNDLE_GEMFILE"]
|
2021-03-10 04:46:39 +00:00
|
|
|
|
2019-02-20 12:28:59 +00:00
|
|
|
install_bundler!
|
|
|
|
|
2020-10-20 12:03:48 +02:00
|
|
|
ENV["BUNDLE_GEMFILE"] = File.join(ENV.fetch("HOMEBREW_LIBRARY"), "Homebrew", "Gemfile")
|
2019-02-20 12:28:59 +00:00
|
|
|
@bundle_installed ||= begin
|
2020-10-20 12:03:48 +02:00
|
|
|
bundle = File.join(find_in_path("bundle"), "bundle")
|
2019-02-26 22:13:00 +00:00
|
|
|
bundle_check_output = `#{bundle} check 2>&1`
|
2019-10-04 09:19:02 +02:00
|
|
|
bundle_check_failed = !$CHILD_STATUS.success?
|
2019-02-20 12:28:59 +00:00
|
|
|
|
|
|
|
# for some reason sometimes the exit code lies so check the output too.
|
|
|
|
if bundle_check_failed || bundle_check_output.include?("Install missing gems")
|
2021-06-07 14:51:07 +01:00
|
|
|
unless system bundle, "install"
|
2021-02-25 15:59:17 +00:00
|
|
|
message = <<~EOS
|
2019-02-26 22:13:00 +00:00
|
|
|
failed to run `#{bundle} install`!
|
|
|
|
EOS
|
2021-02-25 15:59:17 +00:00
|
|
|
if only_warn_on_failure
|
|
|
|
opoo_if_defined message
|
|
|
|
else
|
|
|
|
odie_if_defined message
|
|
|
|
end
|
2019-02-26 22:13:00 +00:00
|
|
|
end
|
2019-02-20 12:28:59 +00:00
|
|
|
else
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
setup_gem_environment!
|
2021-03-10 04:46:39 +00:00
|
|
|
ensure
|
|
|
|
unless setup_path
|
|
|
|
# Reset the paths. We need to have at least temporarily changed them while invoking `bundle`.
|
|
|
|
ENV["PATH"] = old_path
|
|
|
|
ENV["GEM_PATH"] = old_gem_path
|
|
|
|
ENV["GEM_HOME"] = old_gem_home
|
2021-03-27 02:15:56 +00:00
|
|
|
ENV["BUNDLE_GEMFILE"] = old_bundle_gemfile
|
2021-03-10 04:46:39 +00:00
|
|
|
end
|
2019-02-20 12:28:59 +00:00
|
|
|
end
|
|
|
|
end
|