Merge pull request #19733 from Homebrew/improve_brew_bundle_env
Improve `brew bundle exec`/`env`/`sh` environment handling
This commit is contained in:
commit
1fb3bf8a14
@ -11,47 +11,9 @@ module Homebrew
|
|||||||
module Bundle
|
module Bundle
|
||||||
module Commands
|
module Commands
|
||||||
module Exec
|
module Exec
|
||||||
# Homebrew's global environment variables that we don't want to leak into
|
|
||||||
# the `brew bundle exec` environment.
|
|
||||||
HOMEBREW_ENV_CLEANUP = %w[
|
|
||||||
HOMEBREW_HELP_MESSAGE
|
|
||||||
HOMEBREW_API_DEFAULT_DOMAIN
|
|
||||||
HOMEBREW_BOTTLE_DEFAULT_DOMAIN
|
|
||||||
HOMEBREW_BREW_DEFAULT_GIT_REMOTE
|
|
||||||
HOMEBREW_CORE_DEFAULT_GIT_REMOTE
|
|
||||||
HOMEBREW_DEFAULT_CACHE
|
|
||||||
HOMEBREW_DEFAULT_LOGS
|
|
||||||
HOMEBREW_DEFAULT_TEMP
|
|
||||||
HOMEBREW_REQUIRED_RUBY_VERSION
|
|
||||||
HOMEBREW_PRODUCT
|
|
||||||
HOMEBREW_SYSTEM
|
|
||||||
HOMEBREW_PROCESSOR
|
|
||||||
HOMEBREW_PHYSICAL_PROCESSOR
|
|
||||||
HOMEBREW_BREWED_CURL_PATH
|
|
||||||
HOMEBREW_USER_AGENT_CURL
|
|
||||||
HOMEBREW_USER_AGENT
|
|
||||||
HOMEBREW_GENERIC_DEFAULT_PREFIX
|
|
||||||
HOMEBREW_GENERIC_DEFAULT_REPOSITORY
|
|
||||||
HOMEBREW_DEFAULT_PREFIX
|
|
||||||
HOMEBREW_DEFAULT_REPOSITORY
|
|
||||||
HOMEBREW_AUTO_UPDATE_COMMAND
|
|
||||||
HOMEBREW_BREW_GIT_REMOTE
|
|
||||||
HOMEBREW_COMMAND_DEPTH
|
|
||||||
HOMEBREW_CORE_GIT_REMOTE
|
|
||||||
HOMEBREW_MACOS_VERSION_NUMERIC
|
|
||||||
HOMEBREW_MINIMUM_GIT_VERSION
|
|
||||||
HOMEBREW_MACOS_NEWEST_UNSUPPORTED
|
|
||||||
HOMEBREW_MACOS_OLDEST_SUPPORTED
|
|
||||||
HOMEBREW_MACOS_OLDEST_ALLOWED
|
|
||||||
HOMEBREW_GITHUB_PACKAGES_AUTH
|
|
||||||
].freeze
|
|
||||||
|
|
||||||
PATH_LIKE_ENV_REGEX = /.+#{File::PATH_SEPARATOR}/
|
PATH_LIKE_ENV_REGEX = /.+#{File::PATH_SEPARATOR}/
|
||||||
|
|
||||||
def self.run(*args, global: false, file: nil, subcommand: "", services: false)
|
def self.run(*args, global: false, file: nil, subcommand: "", services: false)
|
||||||
# Cleanup Homebrew's global environment
|
|
||||||
HOMEBREW_ENV_CLEANUP.each { |key| ENV.delete(key) }
|
|
||||||
|
|
||||||
# Store the old environment so we can check if things were already set
|
# Store the old environment so we can check if things were already set
|
||||||
# before we start mutating it.
|
# before we start mutating it.
|
||||||
old_env = ENV.to_h
|
old_env = ENV.to_h
|
||||||
@ -149,15 +111,36 @@ module Homebrew
|
|||||||
# For commands which aren't either absolute or relative
|
# For commands which aren't either absolute or relative
|
||||||
raise "command was not found in your PATH: #{command}" if command.exclude?("/") && which(command).nil?
|
raise "command was not found in your PATH: #{command}" if command.exclude?("/") && which(command).nil?
|
||||||
|
|
||||||
|
# Don't need to export Homebrew internal variables that won't be used by other tools.
|
||||||
|
# Those Homebrew needs have already been set to global constants and/or are exported again later.
|
||||||
|
# Setting these globally can interfere with nested Homebrew invocations/environments.
|
||||||
|
ENV.delete_if { |key, _| key.start_with?("HOMEBREW_", "PORTABLE_RUBY_") }
|
||||||
|
|
||||||
if subcommand == "env"
|
if subcommand == "env"
|
||||||
ENV.sort.each do |key, value|
|
ENV.sort.each do |key, value|
|
||||||
# No need to export empty values.
|
# No need to export empty values.
|
||||||
next if value.blank?
|
next if value.blank?
|
||||||
|
|
||||||
# Skip exporting non-Homebrew things that were already set in the old environment.
|
# Skip exporting things that were the same in the old environment.
|
||||||
next if !key.start_with?("HOMEBREW_") && old_env.key?(key) && old_env[key] == value
|
old_value = old_env[key]
|
||||||
|
next if old_value == value
|
||||||
|
|
||||||
puts "export #{key}=\"#{Utils::Shell.sh_quote(value)}\""
|
# Look for PATH-like environment variables
|
||||||
|
if key.include?("PATH") && value.match?(PATH_LIKE_ENV_REGEX)
|
||||||
|
old_values = old_value.to_s.split(File::PATH_SEPARATOR)
|
||||||
|
path = PATH.new(value)
|
||||||
|
.reject do |path_value|
|
||||||
|
# Exclude Homebrew shims from the PATH as they don't work
|
||||||
|
# without all Homebrew environment variables.
|
||||||
|
# Exclude existing/old values as they've already been exported.
|
||||||
|
path_value.include?("/Homebrew/shims/") || old_values.include?(path_value)
|
||||||
|
end
|
||||||
|
next if path.blank?
|
||||||
|
|
||||||
|
puts "export #{key}=\"#{Utils::Shell.sh_quote(path.to_s)}:${#{key}:-}\""
|
||||||
|
else
|
||||||
|
puts "export #{key}=\"#{Utils::Shell.sh_quote(value)}\""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|||||||
@ -65,12 +65,10 @@ RSpec.describe Homebrew::Bundle::Commands::Exec do
|
|||||||
|
|
||||||
context "with env command" do
|
context "with env command" do
|
||||||
it "outputs the environment variables" do
|
it "outputs the environment variables" do
|
||||||
ENV["HOMEBREW_PREFIX"] = "/opt/homebrew"
|
|
||||||
ENV["HOMEBREW_PATH"] = "/usr/bin"
|
|
||||||
allow(OS).to receive(:linux?).and_return(true)
|
allow(OS).to receive(:linux?).and_return(true)
|
||||||
|
|
||||||
expect { described_class.run("env", subcommand: "env") }.to \
|
expect { described_class.run("env", subcommand: "env") }.to \
|
||||||
output(/HOMEBREW_PREFIX="#{ENV.fetch("HOMEBREW_PREFIX")}"/).to_stdout
|
output(/export PATH=".+:\${PATH:-}"/).to_stdout
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user