From ba3c46d24fe6423845cc5e827eb94b3427d75a10 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Sat, 22 Apr 2017 16:28:07 +0100 Subject: [PATCH] More deprecations. Deprecate more methods. Internal APIs have been verified to be unused elsewhere and removed. External APIs have had deprecation methods added. Existing deprecations have been either upgraded to produce warnings or no longer deprecated and the reasoning documented. --- Library/Homebrew/build_options.rb | 1 - Library/Homebrew/caveats.rb | 4 +- Library/Homebrew/cmd/--env.rb | 4 +- Library/Homebrew/cmd/link.rb | 4 +- Library/Homebrew/cmd/tap.rb | 13 --- Library/Homebrew/compat.rb | 1 + Library/Homebrew/compat/ARGV.rb | 2 +- Library/Homebrew/compat/build_options.rb | 7 +- .../Homebrew/compat/dependency_collector.rb | 1 - Library/Homebrew/compat/global.rb | 2 +- Library/Homebrew/compat/software_spec.rb | 2 - Library/Homebrew/compat/tab.rb | 2 +- Library/Homebrew/compat/tap.rb | 2 - Library/Homebrew/compat/utils.rb | 11 +- Library/Homebrew/compat/utils/shell.rb | 8 ++ Library/Homebrew/dev-cmd/create.rb | 9 -- Library/Homebrew/diagnostic.rb | 6 +- Library/Homebrew/extend/ENV/super.rb | 5 - Library/Homebrew/extend/os/mac/diagnostic.rb | 2 +- Library/Homebrew/extend/pathname.rb | 5 +- Library/Homebrew/formula.rb | 1 - Library/Homebrew/formula_cellar_checks.rb | 2 +- Library/Homebrew/language/python.rb | 23 ---- Library/Homebrew/os/mac/xcode.rb | 9 +- Library/Homebrew/requirement.rb | 4 +- Library/Homebrew/software_spec.rb | 4 +- .../Homebrew/test/compiler_selector_spec.rb | 12 +- Library/Homebrew/test/requirement_spec.rb | 10 +- Library/Homebrew/test/utils/shell_spec.rb | 56 ++++----- Library/Homebrew/utils/shell.rb | 106 +++++++++--------- 30 files changed, 124 insertions(+), 194 deletions(-) create mode 100644 Library/Homebrew/compat/utils/shell.rb diff --git a/Library/Homebrew/build_options.rb b/Library/Homebrew/build_options.rb index d9020ecbad..6c6952d710 100644 --- a/Library/Homebrew/build_options.rb +++ b/Library/Homebrew/build_options.rb @@ -47,7 +47,6 @@ class BuildOptions def bottle? include? "build-bottle" end - alias build_bottle? bottle? # True if a {Formula} is being built with {Formula.head} instead of {Formula.stable}. #
args << "--some-new-stuff" if build.head?
diff --git a/Library/Homebrew/caveats.rb b/Library/Homebrew/caveats.rb index 61b7034691..b7c0a60c92 100644 --- a/Library/Homebrew/caveats.rb +++ b/Library/Homebrew/caveats.rb @@ -49,10 +49,10 @@ class Caveats if f.bin.directory? || f.sbin.directory? s << "\nIf you need to have this software first in your PATH run:\n" if f.bin.directory? - s << " #{Utils::Shell.prepend_path_in_shell_profile(f.opt_bin.to_s)}\n" + s << " #{Utils::Shell.prepend_path_in_profile(f.opt_bin.to_s)}\n" end if f.sbin.directory? - s << " #{Utils::Shell.prepend_path_in_shell_profile(f.opt_sbin.to_s)}\n" + s << " #{Utils::Shell.prepend_path_in_profile(f.opt_sbin.to_s)}\n" end end diff --git a/Library/Homebrew/cmd/--env.rb b/Library/Homebrew/cmd/--env.rb index 323964dad0..90beee89cc 100644 --- a/Library/Homebrew/cmd/--env.rb +++ b/Library/Homebrew/cmd/--env.rb @@ -22,9 +22,9 @@ module Homebrew # legacy behavior shell = :bash unless $stdout.tty? elsif shell_value == "auto" - shell = Utils::Shell.parent_shell || Utils::Shell.preferred_shell + shell = Utils::Shell.parent || Utils::Shell.preferred elsif shell_value - shell = Utils::Shell.path_to_shell(shell_value) + shell = Utils::Shell.from_path(shell_value) end env_keys = build_env_keys(ENV) diff --git a/Library/Homebrew/cmd/link.rb b/Library/Homebrew/cmd/link.rb index 5ce6bea48e..b8bd135e0b 100644 --- a/Library/Homebrew/cmd/link.rb +++ b/Library/Homebrew/cmd/link.rb @@ -86,8 +86,8 @@ module Homebrew opt = HOMEBREW_PREFIX/"opt/#{keg.name}" puts "\nIf you need to have this software first in your PATH instead consider running:" - puts " #{Utils::Shell.prepend_path_in_shell_profile(opt/"bin")}" if bin.directory? - puts " #{Utils::Shell.prepend_path_in_shell_profile(opt/"sbin")}" if sbin.directory? + puts " #{Utils::Shell.prepend_path_in_profile(opt/"bin")}" if bin.directory? + puts " #{Utils::Shell.prepend_path_in_profile(opt/"sbin")}" if sbin.directory? end def keg_only?(rack) diff --git a/Library/Homebrew/cmd/tap.rb b/Library/Homebrew/cmd/tap.rb index 114c4a8b6f..2a07c1b2f3 100644 --- a/Library/Homebrew/cmd/tap.rb +++ b/Library/Homebrew/cmd/tap.rb @@ -63,17 +63,4 @@ module Homebrew def full_clone? ARGV.include?("--full") || ARGV.homebrew_developer? end - - # @deprecated this method will be removed in the future, if no external commands use it. - def install_tap(user, repo, clone_target = nil) - opoo "Homebrew.install_tap is deprecated, use Tap#install." - tap = Tap.fetch(user, repo) - begin - tap.install(clone_target: clone_target, full_clone: full_clone?) - rescue TapAlreadyTappedError - false - else - true - end - end end diff --git a/Library/Homebrew/compat.rb b/Library/Homebrew/compat.rb index 92b687725a..3c080f6168 100644 --- a/Library/Homebrew/compat.rb +++ b/Library/Homebrew/compat.rb @@ -25,3 +25,4 @@ require "compat/tab" require "compat/ENV/shared" require "compat/ENV/std" require "compat/ENV/super" +require "compat/utils/shell" diff --git a/Library/Homebrew/compat/ARGV.rb b/Library/Homebrew/compat/ARGV.rb index 23d02ce1a4..e5fa8188f8 100644 --- a/Library/Homebrew/compat/ARGV.rb +++ b/Library/Homebrew/compat/ARGV.rb @@ -1,6 +1,6 @@ module HomebrewArgvExtension def build_32_bit? - # odeprecated "ARGV.build_32_bit?" + odeprecated "ARGV.build_32_bit?" include? "--32-bit" end end diff --git a/Library/Homebrew/compat/build_options.rb b/Library/Homebrew/compat/build_options.rb index 52aa9b9516..73722dadb2 100644 --- a/Library/Homebrew/compat/build_options.rb +++ b/Library/Homebrew/compat/build_options.rb @@ -1,6 +1,11 @@ class BuildOptions def build_32_bit? - # odeprecated "build.build_32_bit?" + odeprecated "build.build_32_bit?" include?("32-bit") && option_defined?("32-bit") end + + def build_bottle? + odeprecated "build.build_bottle?", "build.bottle?" + bottle? + end end diff --git a/Library/Homebrew/compat/dependency_collector.rb b/Library/Homebrew/compat/dependency_collector.rb index bd72c55d4e..fbcf1c2a0f 100644 --- a/Library/Homebrew/compat/dependency_collector.rb +++ b/Library/Homebrew/compat/dependency_collector.rb @@ -14,7 +14,6 @@ class DependencyCollector output_deprecation(spec, tags) Dependency.new(spec.to_s, tags) when :apr - # TODO: reenable in future when we've fixed a few of the audits. # output_deprecation(spec, tags, "apr-util") Dependency.new("apr-util", tags) when :libltdl diff --git a/Library/Homebrew/compat/global.rb b/Library/Homebrew/compat/global.rb index 797e9ffe51..82c452cc0f 100644 --- a/Library/Homebrew/compat/global.rb +++ b/Library/Homebrew/compat/global.rb @@ -3,7 +3,7 @@ module Homebrew def method_missing(method, *args, &block) if instance_methods.include?(method) - # odeprecated "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method" + odeprecated "#{self}##{method}", "'module_function' or 'def self.#{method}' to convert it to a class method" return instance_method(method).bind(self).call(*args, &block) end super diff --git a/Library/Homebrew/compat/software_spec.rb b/Library/Homebrew/compat/software_spec.rb index 51b0f3a0bf..5efd2aeb41 100644 --- a/Library/Homebrew/compat/software_spec.rb +++ b/Library/Homebrew/compat/software_spec.rb @@ -1,7 +1,5 @@ class BottleSpecification def revision(*args) - # Don't announce deprecation yet as this is quite a big change - # to a public interface. # odeprecated "BottleSpecification.revision", "BottleSpecification.rebuild" rebuild(*args) end diff --git a/Library/Homebrew/compat/tab.rb b/Library/Homebrew/compat/tab.rb index 58fdc49137..2cf71c9231 100644 --- a/Library/Homebrew/compat/tab.rb +++ b/Library/Homebrew/compat/tab.rb @@ -1,6 +1,6 @@ class Tab < OpenStruct def build_32_bit? - # odeprecated "Tab.build_32_bit?" + odeprecated "Tab.build_32_bit?" include?("32-bit") end end diff --git a/Library/Homebrew/compat/tap.rb b/Library/Homebrew/compat/tap.rb index d1cf7f1d57..37b1eeac1f 100644 --- a/Library/Homebrew/compat/tap.rb +++ b/Library/Homebrew/compat/tap.rb @@ -6,5 +6,3 @@ class Tap core_tap? end end - -CoreFormulaRepository = CoreTap diff --git a/Library/Homebrew/compat/utils.rb b/Library/Homebrew/compat/utils.rb index 56b0824ba2..3842e8a830 100644 --- a/Library/Homebrew/compat/utils.rb +++ b/Library/Homebrew/compat/utils.rb @@ -1,18 +1,13 @@ -# return the shell profile file based on users' preference shell def shell_profile - opoo "shell_profile has been deprecated in favor of Utils::Shell.profile" - case ENV["SHELL"] - when %r{/(ba)?sh} then "~/.bash_profile" - when %r{/zsh} then "~/.zshrc" - when %r{/ksh} then "~/.kshrc" - else "~/.bash_profile" - end + # odeprecated "shell_profile", "Utils::Shell.profile" + Utils::Shell.profile end module Tty module_function def white + odeprecated "Tty.white", "Tty.reset.bold" reset.bold end end diff --git a/Library/Homebrew/compat/utils/shell.rb b/Library/Homebrew/compat/utils/shell.rb new file mode 100644 index 0000000000..161f10ebb6 --- /dev/null +++ b/Library/Homebrew/compat/utils/shell.rb @@ -0,0 +1,8 @@ +module Utils + module Shell + def self.shell_profile + odeprecated "Utils::Shell.shell_profile", "Utils::Shell.profile" + Utils::Shell.profile + end + end +end diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index 58a155b133..908f65f8f8 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -29,15 +29,6 @@ module Homebrew # Create a formula from a tarball URL def create - # Allow searching MacPorts or Fink. - if ARGV.include? "--macports" - opoo "`brew create --macports` is deprecated; use `brew search --macports` instead" - exec_browser "https://www.macports.org/ports.php?by=name&substr=#{ARGV.next}" - elsif ARGV.include? "--fink" - opoo "`brew create --fink` is deprecated; use `brew search --fink` instead" - exec_browser "http://pdb.finkproject.org/pdb/browse.php?summary=#{ARGV.next}" - end - raise UsageError if ARGV.named.empty? # Ensure that the cache exists so we can fetch the tarball diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 61cdf2f1ac..3002a0a679 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -460,7 +460,7 @@ module Homebrew Consider setting your PATH so that #{HOMEBREW_PREFIX}/bin occurs before /usr/bin. Here is a one-liner: - #{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin")} + #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")} EOS end end @@ -480,7 +480,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")} + #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")} EOS end @@ -495,7 +495,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")} + #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/sbin")} EOS end diff --git a/Library/Homebrew/extend/ENV/super.rb b/Library/Homebrew/extend/ENV/super.rb index 0935647f5a..07c03ec75b 100644 --- a/Library/Homebrew/extend/ENV/super.rb +++ b/Library/Homebrew/extend/ENV/super.rb @@ -325,11 +325,6 @@ module Superenv def set_x11_env_if_installed end - - # This method does nothing in superenv since there's no custom CFLAGS API - # @private - def set_cpu_flags(*_args) - end end class Array diff --git a/Library/Homebrew/extend/os/mac/diagnostic.rb b/Library/Homebrew/extend/os/mac/diagnostic.rb index fb6b30836e..ff936c75ad 100644 --- a/Library/Homebrew/extend/os/mac/diagnostic.rb +++ b/Library/Homebrew/extend/os/mac/diagnostic.rb @@ -263,7 +263,7 @@ module Homebrew SSL_CERT_DIR support was removed from Apple's curl. If fetching formulae fails you should: unset SSL_CERT_DIR - and remove it from #{Utils::Shell.shell_profile} if present. + and remove it from #{Utils::Shell.profile} if present. EOS end diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index eb254c6245..690979e4ed 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -365,9 +365,8 @@ class Pathname unless method_defined?(:/) def /(other) - unless other.respond_to?(:to_str) || other.respond_to?(:to_path) - opoo "Pathname#/ called on #{inspect} with #{other.inspect} as an argument" - puts "This behavior is deprecated, please pass either a String or a Pathname" + if !other.respond_to?(:to_str) && !other.respond_to?(:to_path) + odeprecated "Pathname#/ with #{other.class}", "a String or a Pathname" end self + other.to_s end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 523de244df..aec004b0b7 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -2396,7 +2396,6 @@ class Formula # version '4.8.1' # end def fails_with(compiler, &block) - # TODO: deprecate this in future. # odeprecated "fails_with :llvm" if compiler == :llvm specs.each { |spec| spec.fails_with(compiler, &block) } end diff --git a/Library/Homebrew/formula_cellar_checks.rb b/Library/Homebrew/formula_cellar_checks.rb index c4d5992967..7f7d77569e 100644 --- a/Library/Homebrew/formula_cellar_checks.rb +++ b/Library/Homebrew/formula_cellar_checks.rb @@ -14,7 +14,7 @@ module FormulaCellarChecks <<-EOS.undent #{prefix_bin} is not in your PATH - You can amend this by altering your #{Utils::Shell.shell_profile} file + You can amend this by altering your #{Utils::Shell.profile} file EOS end diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index 23c5246ba3..0f8e3a4e62 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -53,29 +53,6 @@ module Language quiet_system python, "-c", script end - # deprecated; use system "python", *setup_install_args(prefix) instead - def self.setup_install(python, prefix, *args) - opoo <<-EOS.undent - Language::Python.setup_install is deprecated. - If you are a formula author, please use - system "python", *Language::Python.setup_install_args(prefix) - instead. - EOS - - # force-import setuptools, which monkey-patches distutils, to make - # sure that we always call a setuptools setup.py. trick borrowed from pip: - # https://github.com/pypa/pip/blob/043af83/pip/req/req_install.py#L743-L780 - shim = <<-EOS.undent - import setuptools, tokenize - __file__ = 'setup.py' - exec(compile(getattr(tokenize, 'open', open)(__file__).read() - .replace('\\r\\n', '\\n'), __file__, 'exec')) - EOS - args += %w[--single-version-externally-managed --record=installed.txt] - args << "--prefix=#{prefix}" - system python, "-c", shim, "install", *args - end - def self.setup_install_args(prefix) shim = <<-EOS.undent import setuptools, tokenize diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index 8934697cb0..cac0dcc305 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -128,11 +128,10 @@ module OS end end - # The remaining logic provides a fake Xcode version for CLT-only - # systems. This behavior only exists because Homebrew used to assume - # Xcode.version would always be non-nil. This is deprecated, and will - # be removed in a future version. To remain compatible, guard usage of - # Xcode.version with an Xcode.installed? check. + # The remaining logic provides a fake Xcode version based on the + # installed CLT version. This is useful as they are packaged + # simultaneously so workarounds need to apply to both based on their + # comparable version. case (DevelopmentTools.clang_version.to_f * 10).to_i when 0 then "dunno" when 1..14 then "3.2.2" diff --git a/Library/Homebrew/requirement.rb b/Library/Homebrew/requirement.rb index bd8cf20c85..a4bdabdd19 100644 --- a/Library/Homebrew/requirement.rb +++ b/Library/Homebrew/requirement.rb @@ -161,11 +161,9 @@ class Requirement class << self include BuildEnvironmentDSL - attr_reader :env_proc + attr_reader :env_proc, :build attr_rw :fatal, :default_formula attr_rw :cask, :download - # build is deprecated, use `depends_on => :build` instead - attr_rw :build def satisfy(options = {}, &block) @satisfied ||= Requirement::Satisfier.new(options, &block) diff --git a/Library/Homebrew/software_spec.rb b/Library/Homebrew/software_spec.rb index fb07f6c550..1d2e4bf64c 100644 --- a/Library/Homebrew/software_spec.rb +++ b/Library/Homebrew/software_spec.rb @@ -117,8 +117,7 @@ class SoftwareSpec def option(name, description = "") opt = PREDEFINED_OPTIONS.fetch(name) do if name.is_a?(Symbol) - opoo "Passing arbitrary symbols to `option` is deprecated: #{name.inspect}" - puts "Symbols are reserved for future use, please pass a string instead" + odeprecated "passing arbitrary symbols (i.e. #{name.inspect}) to `option`" name = name.to_s end unless name.is_a?(String) @@ -172,7 +171,6 @@ class SoftwareSpec end def fails_with(compiler, &block) - # TODO: deprecate this in future. # odeprecated "fails_with :llvm" if compiler == :llvm compiler_failures << CompilerFailure.create(compiler, &block) end diff --git a/Library/Homebrew/test/compiler_selector_spec.rb b/Library/Homebrew/test/compiler_selector_spec.rb index 0f6f6b5f24..18efbfd424 100644 --- a/Library/Homebrew/test/compiler_selector_spec.rb +++ b/Library/Homebrew/test/compiler_selector_spec.rb @@ -3,7 +3,7 @@ require "software_spec" describe CompilerSelector do subject { described_class.new(software_spec, versions, compilers) } - let(:compilers) { [:clang, :gcc, :llvm, :gnu] } + let(:compilers) { [:clang, :gcc, :gnu] } let(:software_spec) { SoftwareSpec.new } let(:cc) { :clang } let(:versions) do @@ -28,7 +28,6 @@ describe CompilerSelector do describe "#compiler" do it "raises an error if no matching compiler can be found" do software_spec.fails_with(:clang) - software_spec.fails_with(:llvm) software_spec.fails_with(:gcc) software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.7") @@ -45,11 +44,6 @@ describe CompilerSelector do expect(subject.compiler).to eq(:gcc) end - it "returns clang if it fails with llvm" do - software_spec.fails_with(:llvm) - expect(subject.compiler).to eq(:clang) - end - it "returns clang if it fails with gcc" do software_spec.fails_with(:gcc) expect(subject.compiler).to eq(:clang) @@ -68,13 +62,11 @@ describe CompilerSelector do it "returns gcc if it fails with clang and llvm" do software_spec.fails_with(:clang) - software_spec.fails_with(:llvm) expect(subject.compiler).to eq(:gcc) end it "returns clang if it fails with gcc and llvm" do software_spec.fails_with(:gcc) - software_spec.fails_with(:llvm) expect(subject.compiler).to eq(:clang) end @@ -87,7 +79,6 @@ describe CompilerSelector do example "returns a lower version of gcc if it fails with the highest version" do software_spec.fails_with(:clang) software_spec.fails_with(:gcc) - software_spec.fails_with(:llvm) software_spec.fails_with(gcc: "4.8") expect(subject.compiler).to eq("gcc-4.7") end @@ -102,7 +93,6 @@ describe CompilerSelector do allow(versions).to receive(:gcc_build_version).and_return(Version::NULL) software_spec.fails_with(:clang) - software_spec.fails_with(:llvm) software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.7") diff --git a/Library/Homebrew/test/requirement_spec.rb b/Library/Homebrew/test/requirement_spec.rb index 110a7ac4fb..959041cf4b 100644 --- a/Library/Homebrew/test/requirement_spec.rb +++ b/Library/Homebrew/test/requirement_spec.rb @@ -146,17 +146,13 @@ describe Requirement do end describe "#build?" do - context "#build true is specified" do - let(:klass) do - Class.new(described_class) do - build true - end - end + context ":build tag is specified" do + subject { described_class.new([:build]) } it { is_expected.to be_a_build_requirement } end - context "#build ommitted" do + context "#build omitted" do it { is_expected.not_to be_a_build_requirement } end end diff --git a/Library/Homebrew/test/utils/shell_spec.rb b/Library/Homebrew/test/utils/shell_spec.rb index c44bd82533..d32f9928fd 100644 --- a/Library/Homebrew/test/utils/shell_spec.rb +++ b/Library/Homebrew/test/utils/shell_spec.rb @@ -1,92 +1,92 @@ require "utils/shell" describe Utils::Shell do - describe "::shell_profile" do + describe "::profile" do it "returns ~/.bash_profile by default" do ENV["SHELL"] = "/bin/another_shell" - expect(subject.shell_profile).to eq("~/.bash_profile") + expect(subject.profile).to eq("~/.bash_profile") end it "returns ~/.bash_profile for Sh" do ENV["SHELL"] = "/bin/another_shell" - expect(subject.shell_profile).to eq("~/.bash_profile") + expect(subject.profile).to eq("~/.bash_profile") end it "returns ~/.bash_profile for Bash" do ENV["SHELL"] = "/bin/bash" - expect(subject.shell_profile).to eq("~/.bash_profile") + expect(subject.profile).to eq("~/.bash_profile") end it "returns ~/.zshrc for Zsh" do ENV["SHELL"] = "/bin/zsh" - expect(subject.shell_profile).to eq("~/.zshrc") + expect(subject.profile).to eq("~/.zshrc") end it "returns ~/.kshrc for Ksh" do ENV["SHELL"] = "/bin/ksh" - expect(subject.shell_profile).to eq("~/.kshrc") + expect(subject.profile).to eq("~/.kshrc") end end - describe "::path_to_shell" do + describe "::from_path" do it "supports a raw command name" do - expect(subject.path_to_shell("bash")).to eq(:bash) + expect(subject.from_path("bash")).to eq(:bash) end it "supports full paths" do - expect(subject.path_to_shell("/bin/bash")).to eq(:bash) + expect(subject.from_path("/bin/bash")).to eq(:bash) end it "supports versions" do - expect(subject.path_to_shell("zsh-5.2")).to eq(:zsh) + expect(subject.from_path("zsh-5.2")).to eq(:zsh) end it "strips newlines" do - expect(subject.path_to_shell("zsh-5.2\n")).to eq(:zsh) + expect(subject.from_path("zsh-5.2\n")).to eq(:zsh) end it "returns nil when input is invalid" do - expect(subject.path_to_shell("")).to be nil - expect(subject.path_to_shell("@@@@@@")).to be nil - expect(subject.path_to_shell("invalid_shell-4.2")).to be nil + expect(subject.from_path("")).to be nil + expect(subject.from_path("@@@@@@")).to be nil + expect(subject.from_path("invalid_shell-4.2")).to be nil end end specify "::sh_quote" do - expect(subject.sh_quote("")).to eq("''") - expect(subject.sh_quote("\\")).to eq("\\\\") - expect(subject.sh_quote("\n")).to eq("'\n'") - expect(subject.sh_quote("$")).to eq("\\$") - expect(subject.sh_quote("word")).to eq("word") + expect(subject.send(:sh_quote, "")).to eq("''") + expect(subject.send(:sh_quote, "\\")).to eq("\\\\") + expect(subject.send(:sh_quote, "\n")).to eq("'\n'") + expect(subject.send(:sh_quote, "$")).to eq("\\$") + expect(subject.send(:sh_quote, "word")).to eq("word") end specify "::csh_quote" do - expect(subject.csh_quote("")).to eq("''") - expect(subject.csh_quote("\\")).to eq("\\\\") + expect(subject.send(:csh_quote, "")).to eq("''") + expect(subject.send(:csh_quote, "\\")).to eq("\\\\") # note this test is different than for sh - expect(subject.csh_quote("\n")).to eq("'\\\n'") - expect(subject.csh_quote("$")).to eq("\\$") - expect(subject.csh_quote("word")).to eq("word") + expect(subject.send(:csh_quote, "\n")).to eq("'\\\n'") + expect(subject.send(:csh_quote, "$")).to eq("\\$") + expect(subject.send(:csh_quote, "word")).to eq("word") end - describe "::prepend_path_in_shell_profile" do + describe "::prepend_path_in_profile" do let(:path) { "/my/path" } it "supports Tcsh" do ENV["SHELL"] = "/bin/tcsh" - expect(subject.prepend_path_in_shell_profile(path)) + expect(subject.prepend_path_in_profile(path)) .to start_with("echo 'setenv PATH #{path}:$") end it "supports Bash" do ENV["SHELL"] = "/bin/bash" - expect(subject.prepend_path_in_shell_profile(path)) + expect(subject.prepend_path_in_profile(path)) .to start_with("echo 'export PATH=\"#{path}:$") end it "supports Fish" do ENV["SHELL"] = "/usr/local/bin/fish" - expect(subject.prepend_path_in_shell_profile(path)) + expect(subject.prepend_path_in_profile(path)) .to start_with("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 302167d476..5327f6ecf6 100644 --- a/Library/Homebrew/utils/shell.rb +++ b/Library/Homebrew/utils/shell.rb @@ -1,62 +1,24 @@ 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 - UNSAFE_SHELL_CHAR = %r{([^A-Za-z0-9_\-.,:/@\n])} + module_function # take a path and heuristically convert it # to a shell name, return nil if there's no match - def path_to_shell(path) + def from_path(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 - module_function :path_to_shell - def preferred_shell - path_to_shell(ENV.fetch("SHELL", "")) + def preferred + from_path(ENV.fetch("SHELL", "")) end - module_function :preferred_shell - def parent_shell - path_to_shell(`ps -p #{Process.ppid} -o ucomm=`.strip) + def parent + from_path(`ps -p #{Process.ppid} -o ucomm=`.strip) end - module_function :parent_shell - - def 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!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") - # newlines have to be specially quoted in csh - str.gsub!(/\n/, "'\\\n'") - str - end - module_function :csh_quote - - def 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!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") - str.gsub!(/\n/, "'\n'") - str - end - module_function :sh_quote # quote values. quoting keys is overkill def export_value(shell, key, value) @@ -72,24 +34,60 @@ module Utils "setenv #{key} #{csh_quote(value)};" end end - module_function :export_value # return the shell profile file based on users' preferred shell - def shell_profile - SHELL_PROFILE_MAP.fetch(preferred_shell, "~/.bash_profile") + def profile + SHELL_PROFILE_MAP.fetch(preferred, "~/.bash_profile") end - module_function :shell_profile - def prepend_path_in_shell_profile(path) - case preferred_shell + def prepend_path_in_profile(path) + case preferred when :bash, :ksh, :sh, :zsh, nil - "echo 'export PATH=\"#{sh_quote(path)}:$PATH\"' >> #{shell_profile}" + "echo 'export PATH=\"#{sh_quote(path)}:$PATH\"' >> #{profile}" when :csh, :tcsh - "echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{shell_profile}" + "echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{profile}" when :fish - "echo 'set -g fish_user_paths \"#{sh_quote(path)}\" $fish_user_paths' >> #{shell_profile}" + "echo 'set -g fish_user_paths \"#{sh_quote(path)}\" $fish_user_paths' >> #{profile}" end end - module_function :prepend_path_in_shell_profile + + private + + SHELL_PROFILE_MAP = { + bash: "~/.bash_profile", + csh: "~/.cshrc", + fish: "~/.config/fish/config.fish", + ksh: "~/.kshrc", + sh: "~/.bash_profile", + tcsh: "~/.tcshrc", + zsh: "~/.zshrc", + }.freeze + + UNSAFE_SHELL_CHAR = %r{([^A-Za-z0-9_\-.,:/@\n])} + + module_function + + def 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!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") + # newlines have to be specially quoted in csh + str.gsub!(/\n/, "'\\\n'") + str + end + + def 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!(UNSAFE_SHELL_CHAR, "\\\\" + "\\1") + str.gsub!(/\n/, "'\n'") + str + end end end