diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 292bcf866d0fafa5730de9bee068950a30a16eb4..0feb338dc897108a3d0dcff99b2aa92f10155b12 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -13,9 +13,8 @@ module Homebrew ENV.universal_binary if ARGV.build_universal? shell_value = ARGV.value("shell") - has_plain = ARGV.include?("--plain") - if has_plain + if ARGV.include?("--plain") shell = nil elsif shell_value.nil? # legacy behavior diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index d032ecff5f5d2a781b900f364561670b4176e3ee..86593ff7b6c5ffefce9ab92b381edc7c4736622b 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -496,7 +496,7 @@ module Homebrew <<-EOS.undent Homebrew's bin was not found in your PATH. Consider setting the PATH for example like so - #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin:$PATH")} + #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin")} EOS end @@ -511,7 +511,7 @@ module Homebrew Homebrew's sbin was not found in your PATH but you have installed formulae that put executables in #{HOMEBREW_PREFIX}/sbin. Consider setting the PATH for example like so - #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/sbin:$PATH")} + #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/sbin")} EOS end diff --git a/Library/Homebrew/test/test_integration_cmds.rb b/Library/Homebrew/test/test_integration_cmds.rb index 1a5db6b6f359d7eacf6f642dcc8ced293d176f0c..8801071d2285346ec75fd9214c52f50ecff84264 100644 --- a/Library/Homebrew/test/test_integration_cmds.rb +++ b/Library/Homebrew/test/test_integration_cmds.rb @@ -238,7 +238,7 @@ class IntegrationCommandTests < Homebrew::TestCase end def test_env_csh - assert_match %r{setenv CMAKE_PREFIX_PATH #{Regexp.quote(HOMEBREW_PREFIX.to_s)}}, + assert_match %r{setenv CMAKE_PREFIX_PATH #{Regexp.quote(HOMEBREW_PREFIX.to_s)};}, cmd("--env", "--shell=tcsh") end diff --git a/Library/Homebrew/test/test_shell.rb b/Library/Homebrew/test/test_shell.rb index 5a105745794c62ced850af8a414c981d664861ea..5e054f9d9f1293c29684a94b8c348afe64ea2df7 100644 --- a/Library/Homebrew/test/test_shell.rb +++ b/Library/Homebrew/test/test_shell.rb @@ -35,4 +35,25 @@ class ShellSmokeTest < Homebrew::TestCase assert_equal "\\$", Utils::Shell.csh_quote("$") assert_equal "word", Utils::Shell.csh_quote("word") end + + def prepend_path_shell(shell, path, fragment) + original_shell = ENV["SHELL"] + ENV["SHELL"] = shell + + prepend_message = Utils::Shell.prepend_path_in_shell_profile(path) + assert( + prepend_message.start_with?(fragment), + "#{shell}: expected #{prepend_message} to match #{fragment}" + ) + + ENV["SHELL"] = original_shell + end + + def test_prepend_path_in_shell_profile() + prepend_path_shell "/bin/tcsh", "/path", "echo 'setenv PATH /path" + + prepend_path_shell "/bin/bash", "/path", "echo 'export PATH=\"/path" + + prepend_path_shell "/usr/local/bin/fish", "/path", "echo 'set -g fish_user_paths \"/path\" $fish_user_paths' >>" + end end diff --git a/Library/Homebrew/utils/shell.rb b/Library/Homebrew/utils/shell.rb index d2301345fa2a84ee2c5e342e9925b7292d558a98..19e696795f168a5b9131b5406a71d76e04b82798 100644 --- a/Library/Homebrew/utils/shell.rb +++ b/Library/Homebrew/utils/shell.rb @@ -10,8 +10,10 @@ module Utils }.freeze module Shell + UNSAFE_SHELL_CHAR = /([^A-Za-z0-9_\-.,:\/@\n])/ + # take a path and heuristically convert it - # to a shell, return nil if there's no match + # to a shell name, return nil if there's no match def self.path_to_shell(path) # we only care about the basename shell_name = File.basename(path) @@ -34,7 +36,8 @@ module Utils 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!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") + # newlines have to be specially quoted in csh str.gsub!(/\n/, "'\\\n'") str end @@ -45,7 +48,7 @@ module Utils 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!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") str.gsub!(/\n/, "'\n'") str end @@ -61,7 +64,7 @@ module Utils # and a literal \ can be included via \\ "set -gx #{key} \"#{sh_quote(value)}\"" when :csh, :tcsh - "setenv #{key} #{csh_quote(value)}" + "setenv #{key} #{csh_quote(value)};" end end @@ -72,12 +75,12 @@ module Utils def self.prepend_path_in_shell_profile(path) case preferred_shell - when :bash, :ksh, :sh, :zsh - "echo 'export PATH=\"#{sh_quote(path)}:$PATH >> #{shell_profile}" + when :bash, :ksh, :sh, :zsh, nil + "echo 'export PATH=\"#{sh_quote(path)}:$PATH'\" >> #{shell_profile}" when :csh, :tcsh "echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{shell_profile}" when :fish - "echo 'set -g fish_user_paths $fish_user_paths >> #{sh_quote(path)}' >> #{shell_profile}" + "echo 'set -g fish_user_paths \"#{sh_quote(path)}\" $fish_user_paths' >> #{shell_profile}" end end end