resolve conflict in diagnostic.rb

This commit is contained in:
Greg Nisbet 2016-08-10 23:19:09 -07:00
parent 06fe347de9
commit 9a29a306cf
7 changed files with 160 additions and 13 deletions

View File

@ -3,6 +3,7 @@
require "extend/ENV" require "extend/ENV"
require "build_environment" require "build_environment"
require "utils/shell"
module Homebrew module Homebrew
def __env def __env
@ -11,12 +12,25 @@ module Homebrew
ENV.setup_build_environment ENV.setup_build_environment
ENV.universal_binary if ARGV.build_universal? ENV.universal_binary if ARGV.build_universal?
if $stdout.tty? shell_value = ARGV.value("shell")
has_plain = ARGV.include?("--plain")
if has_plain
shell = nil
elsif shell_value.nil?
# legacy behavior
shell = :bash unless $stdout.tty?
elsif shell_value == "auto"
shell = Utils::Shell.parent_shell || Utils::Shell.preferred_shell
elsif shell_value
shell = Utils::Shell.path_to_shell(shell_value)
end
env_keys = build_env_keys(ENV)
if shell.nil?
dump_build_env ENV dump_build_env ENV
else else
build_env_keys(ENV).each do |key| env_keys.each { |key| puts Utils::Shell.export_value(shell, key, ENV[key]) }
puts "export #{key}=\"#{ENV[key]}\""
end
end end
end end
end end

View File

@ -3,6 +3,7 @@ require "language/python"
require "formula" require "formula"
require "version" require "version"
require "development_tools" require "development_tools"
require "utils/shell"
module Homebrew module Homebrew
module Diagnostic module Diagnostic
@ -475,7 +476,7 @@ module Homebrew
Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin
occurs before /usr/bin. Here is a one-liner: occurs before /usr/bin. Here is a one-liner:
echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile} echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{Utils::Shell.shell_profile}
EOS EOS
end end
end end
@ -495,7 +496,7 @@ module Homebrew
<<-EOS.undent <<-EOS.undent
Homebrew's bin was not found in your PATH. Homebrew's bin was not found in your PATH.
Consider setting the PATH for example like so Consider setting the PATH for example like so
echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{shell_profile} echo 'export PATH="#{HOMEBREW_PREFIX}/bin:$PATH"' >> #{Utils::Shell.shell_profile}
EOS EOS
end end
@ -510,7 +511,7 @@ module Homebrew
Homebrew's sbin was not found in your PATH but you have installed Homebrew's sbin was not found in your PATH but you have installed
formulae that put executables in #{HOMEBREW_PREFIX}/sbin. formulae that put executables in #{HOMEBREW_PREFIX}/sbin.
Consider setting the PATH for example like so Consider setting the PATH for example like so
echo 'export PATH="#{HOMEBREW_PREFIX}/sbin:$PATH"' >> #{shell_profile} echo 'export PATH="#{HOMEBREW_PREFIX}/sbin:$PATH"' >> #{Utils::Shell.shell_profile}
EOS EOS
end end

View File

@ -202,7 +202,7 @@ module Homebrew
SSL_CERT_DIR support was removed from Apple's curl. SSL_CERT_DIR support was removed from Apple's curl.
If fetching formulae fails you should: If fetching formulae fails you should:
unset SSL_CERT_DIR unset SSL_CERT_DIR
and remove it from #{shell_profile} if present. and remove it from #{Utils::Shell.shell_profile} if present.
EOS EOS
end end

View File

@ -227,6 +227,26 @@ class IntegrationCommandTests < Homebrew::TestCase
cmd("--env")) cmd("--env"))
end end
def test_env_bash
assert_match %r{export CMAKE_PREFIX_PATH="#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"},
cmd("--env", "--shell=bash")
end
def test_env_fish
assert_match %r{set [-]gx CMAKE_PREFIX_PATH "#{Regexp.quote(HOMEBREW_PREFIX.to_s)}"},
cmd("--env", "--shell=fish")
end
def test_env_csh
assert_match %r{setenv CMAKE_PREFIX_PATH},
cmd("--env", "--shell=tcsh")
end
def test_env_plain
assert_match %r{CMAKE_PREFIX_PATH: #{Regexp.quote(HOMEBREW_PREFIX)}},
cmd("--env", "--plain")
end
def test_prefix_formula def test_prefix_formula
assert_match "#{HOMEBREW_CELLAR}/testball", assert_match "#{HOMEBREW_CELLAR}/testball",
cmd("--prefix", testball) cmd("--prefix", testball)

View File

@ -0,0 +1,38 @@
require "testing_env"
require "utils/shell"
class ShellSmokeTest < Homebrew::TestCase
def test_path_to_shell()
# raw command name
assert_equal :bash, Utils::Shell.path_to_shell("bash")
# full path
assert_equal :bash, Utils::Shell.path_to_shell("/bin/bash")
# versions
assert_equal :zsh, Utils::Shell.path_to_shell("zsh-5.2")
# strip newline too
assert_equal :zsh, Utils::Shell.path_to_shell("zsh-5.2\n")
end
def test_path_to_shell_failure()
assert_equal nil, Utils::Shell.path_to_shell("")
assert_equal nil, Utils::Shell.path_to_shell("@@@@@@")
assert_equal nil, Utils::Shell.path_to_shell("invalid_shell-4.2")
end
def test_sh_quote()
assert_equal "''", Utils::Shell.sh_quote("")
assert_equal "\\\\", Utils::Shell.sh_quote("\\")
assert_equal "'\n'", Utils::Shell.sh_quote("\n")
assert_equal "\\$", Utils::Shell.sh_quote("$")
assert_equal "word", Utils::Shell.sh_quote("word")
end
def test_csh_quote()
assert_equal "''", Utils::Shell.csh_quote("")
assert_equal "\\\\", Utils::Shell.csh_quote("\\")
# note this test is different
assert_equal "'\\\n'", Utils::Shell.csh_quote("\n")
assert_equal "\\$", Utils::Shell.csh_quote("$")
assert_equal "word", Utils::Shell.csh_quote("word")
end
end

View File

@ -1,6 +1,7 @@
require "testing_env" require "testing_env"
require "utils" require "utils"
require "tempfile" require "tempfile"
require "utils/shell"
class TtyTests < Homebrew::TestCase class TtyTests < Homebrew::TestCase
def test_strip_ansi def test_strip_ansi
@ -157,15 +158,15 @@ class UtilTests < Homebrew::TestCase
def test_shell_profile def test_shell_profile
ENV["SHELL"] = "/bin/sh" ENV["SHELL"] = "/bin/sh"
assert_equal "~/.bash_profile", shell_profile assert_equal "~/.bash_profile", Utils::Shell.shell_profile
ENV["SHELL"] = "/bin/bash" ENV["SHELL"] = "/bin/bash"
assert_equal "~/.bash_profile", shell_profile assert_equal "~/.bash_profile", Utils::Shell.shell_profile
ENV["SHELL"] = "/bin/another_shell" ENV["SHELL"] = "/bin/another_shell"
assert_equal "~/.bash_profile", shell_profile assert_equal "~/.bash_profile", Utils::Shell.shell_profile
ENV["SHELL"] = "/bin/zsh" ENV["SHELL"] = "/bin/zsh"
assert_equal "~/.zshrc", shell_profile assert_equal "~/.zshrc", Utils::Shell.shell_profile
ENV["SHELL"] = "/bin/ksh" ENV["SHELL"] = "/bin/ksh"
assert_equal "~/.kshrc", shell_profile assert_equal "~/.kshrc", Utils::Shell.shell_profile
end end
def test_popen_read def test_popen_read

View File

@ -0,0 +1,73 @@
module Utils
SHELL_PROFILE_MAP = {
:bash => "~/.bash_profile",
:csh => "~/.cshrc",
:fish => "~/.config/fish/config.fish",
:ksh => "~/.kshrc",
:sh => "~/.bash_profile",
:tcsh => "~/.tcshrc",
:zsh => "~/.zshrc",
}.freeze
module Shell
# take a path and heuristically convert it
# to a shell, return nil if there's no match
def self.path_to_shell(path)
# we only care about the basename
shell_name = File.basename(path)
# handle possible version suffix like `zsh-5.2`
shell_name.sub!(/-.*\z/m, "")
shell_name.to_sym if %w[bash csh fish ksh sh tcsh zsh].include?(shell_name)
end
def self.preferred_shell
path_to_shell(ENV.fetch("SHELL", ""))
end
def self.parent_shell
path_to_shell(`ps -p #{Process.ppid} -o ucomm=`.strip)
end
def self.csh_quote(str)
# ruby's implementation of shell_escape
str = str.to_s
return "''" if str.empty?
str = str.dup
# anything that isn't a known safe character is padded
str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\" + "\\1")
str.gsub!(/\n/, "'\\\n'")
str
end
def self.sh_quote(str)
# ruby's implementation of shell_escape
str = str.to_s
return "''" if str.empty?
str = str.dup
# anything that isn't a known safe character is padded
str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\" + "\\1")
str.gsub!(/\n/, "'\n'")
str
end
# quote values. quoting keys is overkill
def self.export_value(shell, key, value)
case shell
when :bash, :ksh, :sh, :zsh
"export #{key}=\"#{sh_quote(value)}\""
when :fish
# fish quoting is mostly Bourne compatible except that
# a single quote can be included in a single-quoted string via \'
# and a literal \ can be included via \\
"set -gx #{key} \"#{sh_quote(value)}\""
when :csh, :tcsh
"setenv #{key} #{csh_quote(value)}"
end
end
# return the shell profile file based on users' preferred shell
def self.shell_profile
SHELL_PROFILE_MAP.fetch(preferred_shell, "~/.bash_profile")
end
end
end