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.
This commit is contained in:
Mike McQuaid 2017-04-22 16:28:07 +01:00
parent 206d6de845
commit ba3c46d24f
30 changed files with 124 additions and 194 deletions

View File

@ -47,7 +47,6 @@ class BuildOptions
def bottle? def bottle?
include? "build-bottle" include? "build-bottle"
end end
alias build_bottle? bottle?
# True if a {Formula} is being built with {Formula.head} instead of {Formula.stable}. # True if a {Formula} is being built with {Formula.head} instead of {Formula.stable}.
# <pre>args << "--some-new-stuff" if build.head?</pre> # <pre>args << "--some-new-stuff" if build.head?</pre>

View File

@ -49,10 +49,10 @@ class Caveats
if f.bin.directory? || f.sbin.directory? if f.bin.directory? || f.sbin.directory?
s << "\nIf you need to have this software first in your PATH run:\n" s << "\nIf you need to have this software first in your PATH run:\n"
if f.bin.directory? 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 end
if f.sbin.directory? 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
end end

View File

@ -22,9 +22,9 @@ module Homebrew
# legacy behavior # legacy behavior
shell = :bash unless $stdout.tty? shell = :bash unless $stdout.tty?
elsif shell_value == "auto" elsif shell_value == "auto"
shell = Utils::Shell.parent_shell || Utils::Shell.preferred_shell shell = Utils::Shell.parent || Utils::Shell.preferred
elsif shell_value elsif shell_value
shell = Utils::Shell.path_to_shell(shell_value) shell = Utils::Shell.from_path(shell_value)
end end
env_keys = build_env_keys(ENV) env_keys = build_env_keys(ENV)

View File

@ -86,8 +86,8 @@ module Homebrew
opt = HOMEBREW_PREFIX/"opt/#{keg.name}" opt = HOMEBREW_PREFIX/"opt/#{keg.name}"
puts "\nIf you need to have this software first in your PATH instead consider running:" 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_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/"sbin")}" if sbin.directory?
end end
def keg_only?(rack) def keg_only?(rack)

View File

@ -63,17 +63,4 @@ module Homebrew
def full_clone? def full_clone?
ARGV.include?("--full") || ARGV.homebrew_developer? ARGV.include?("--full") || ARGV.homebrew_developer?
end 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 end

View File

@ -25,3 +25,4 @@ require "compat/tab"
require "compat/ENV/shared" require "compat/ENV/shared"
require "compat/ENV/std" require "compat/ENV/std"
require "compat/ENV/super" require "compat/ENV/super"
require "compat/utils/shell"

View File

@ -1,6 +1,6 @@
module HomebrewArgvExtension module HomebrewArgvExtension
def build_32_bit? def build_32_bit?
# odeprecated "ARGV.build_32_bit?" odeprecated "ARGV.build_32_bit?"
include? "--32-bit" include? "--32-bit"
end end
end end

View File

@ -1,6 +1,11 @@
class BuildOptions class BuildOptions
def build_32_bit? def build_32_bit?
# odeprecated "build.build_32_bit?" odeprecated "build.build_32_bit?"
include?("32-bit") && option_defined?("32-bit") include?("32-bit") && option_defined?("32-bit")
end end
def build_bottle?
odeprecated "build.build_bottle?", "build.bottle?"
bottle?
end
end end

View File

@ -14,7 +14,6 @@ class DependencyCollector
output_deprecation(spec, tags) output_deprecation(spec, tags)
Dependency.new(spec.to_s, tags) Dependency.new(spec.to_s, tags)
when :apr when :apr
# TODO: reenable in future when we've fixed a few of the audits.
# output_deprecation(spec, tags, "apr-util") # output_deprecation(spec, tags, "apr-util")
Dependency.new("apr-util", tags) Dependency.new("apr-util", tags)
when :libltdl when :libltdl

View File

@ -3,7 +3,7 @@ module Homebrew
def method_missing(method, *args, &block) def method_missing(method, *args, &block)
if instance_methods.include?(method) 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) return instance_method(method).bind(self).call(*args, &block)
end end
super super

View File

@ -1,7 +1,5 @@
class BottleSpecification class BottleSpecification
def revision(*args) def revision(*args)
# Don't announce deprecation yet as this is quite a big change
# to a public interface.
# odeprecated "BottleSpecification.revision", "BottleSpecification.rebuild" # odeprecated "BottleSpecification.revision", "BottleSpecification.rebuild"
rebuild(*args) rebuild(*args)
end end

View File

@ -1,6 +1,6 @@
class Tab < OpenStruct class Tab < OpenStruct
def build_32_bit? def build_32_bit?
# odeprecated "Tab.build_32_bit?" odeprecated "Tab.build_32_bit?"
include?("32-bit") include?("32-bit")
end end
end end

View File

@ -6,5 +6,3 @@ class Tap
core_tap? core_tap?
end end
end end
CoreFormulaRepository = CoreTap

View File

@ -1,18 +1,13 @@
# return the shell profile file based on users' preference shell
def shell_profile def shell_profile
opoo "shell_profile has been deprecated in favor of Utils::Shell.profile" # odeprecated "shell_profile", "Utils::Shell.profile"
case ENV["SHELL"] Utils::Shell.profile
when %r{/(ba)?sh} then "~/.bash_profile"
when %r{/zsh} then "~/.zshrc"
when %r{/ksh} then "~/.kshrc"
else "~/.bash_profile"
end
end end
module Tty module Tty
module_function module_function
def white def white
odeprecated "Tty.white", "Tty.reset.bold"
reset.bold reset.bold
end end
end end

View File

@ -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

View File

@ -29,15 +29,6 @@ module Homebrew
# Create a formula from a tarball URL # Create a formula from a tarball URL
def create 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? raise UsageError if ARGV.named.empty?
# Ensure that the cache exists so we can fetch the tarball # Ensure that the cache exists so we can fetch the tarball

View File

@ -460,7 +460,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:
#{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin")} #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")}
EOS EOS
end end
end end
@ -480,7 +480,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
#{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/bin")} #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/bin")}
EOS EOS
end end
@ -495,7 +495,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
#{Utils::Shell.prepend_path_in_shell_profile("#{HOMEBREW_PREFIX}/sbin")} #{Utils::Shell.prepend_path_in_profile("#{HOMEBREW_PREFIX}/sbin")}
EOS EOS
end end

View File

@ -325,11 +325,6 @@ module Superenv
def set_x11_env_if_installed def set_x11_env_if_installed
end end
# This method does nothing in superenv since there's no custom CFLAGS API
# @private
def set_cpu_flags(*_args)
end
end end
class Array class Array

View File

@ -263,7 +263,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 #{Utils::Shell.shell_profile} if present. and remove it from #{Utils::Shell.profile} if present.
EOS EOS
end end

View File

@ -365,9 +365,8 @@ class Pathname
unless method_defined?(:/) unless method_defined?(:/)
def /(other) def /(other)
unless other.respond_to?(:to_str) || other.respond_to?(:to_path) if !other.respond_to?(:to_str) && !other.respond_to?(:to_path)
opoo "Pathname#/ called on #{inspect} with #{other.inspect} as an argument" odeprecated "Pathname#/ with #{other.class}", "a String or a Pathname"
puts "This behavior is deprecated, please pass either a String or a Pathname"
end end
self + other.to_s self + other.to_s
end end

View File

@ -2396,7 +2396,6 @@ class Formula
# version '4.8.1' # version '4.8.1'
# end</pre> # end</pre>
def fails_with(compiler, &block) def fails_with(compiler, &block)
# TODO: deprecate this in future.
# odeprecated "fails_with :llvm" if compiler == :llvm # odeprecated "fails_with :llvm" if compiler == :llvm
specs.each { |spec| spec.fails_with(compiler, &block) } specs.each { |spec| spec.fails_with(compiler, &block) }
end end

View File

@ -14,7 +14,7 @@ module FormulaCellarChecks
<<-EOS.undent <<-EOS.undent
#{prefix_bin} is not in your PATH #{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 EOS
end end

View File

@ -53,29 +53,6 @@ module Language
quiet_system python, "-c", script quiet_system python, "-c", script
end 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) def self.setup_install_args(prefix)
shim = <<-EOS.undent shim = <<-EOS.undent
import setuptools, tokenize import setuptools, tokenize

View File

@ -128,11 +128,10 @@ module OS
end end
end end
# The remaining logic provides a fake Xcode version for CLT-only # The remaining logic provides a fake Xcode version based on the
# systems. This behavior only exists because Homebrew used to assume # installed CLT version. This is useful as they are packaged
# Xcode.version would always be non-nil. This is deprecated, and will # simultaneously so workarounds need to apply to both based on their
# be removed in a future version. To remain compatible, guard usage of # comparable version.
# Xcode.version with an Xcode.installed? check.
case (DevelopmentTools.clang_version.to_f * 10).to_i case (DevelopmentTools.clang_version.to_f * 10).to_i
when 0 then "dunno" when 0 then "dunno"
when 1..14 then "3.2.2" when 1..14 then "3.2.2"

View File

@ -161,11 +161,9 @@ class Requirement
class << self class << self
include BuildEnvironmentDSL include BuildEnvironmentDSL
attr_reader :env_proc attr_reader :env_proc, :build
attr_rw :fatal, :default_formula attr_rw :fatal, :default_formula
attr_rw :cask, :download attr_rw :cask, :download
# build is deprecated, use `depends_on <requirement> => :build` instead
attr_rw :build
def satisfy(options = {}, &block) def satisfy(options = {}, &block)
@satisfied ||= Requirement::Satisfier.new(options, &block) @satisfied ||= Requirement::Satisfier.new(options, &block)

View File

@ -117,8 +117,7 @@ class SoftwareSpec
def option(name, description = "") def option(name, description = "")
opt = PREDEFINED_OPTIONS.fetch(name) do opt = PREDEFINED_OPTIONS.fetch(name) do
if name.is_a?(Symbol) if name.is_a?(Symbol)
opoo "Passing arbitrary symbols to `option` is deprecated: #{name.inspect}" odeprecated "passing arbitrary symbols (i.e. #{name.inspect}) to `option`"
puts "Symbols are reserved for future use, please pass a string instead"
name = name.to_s name = name.to_s
end end
unless name.is_a?(String) unless name.is_a?(String)
@ -172,7 +171,6 @@ class SoftwareSpec
end end
def fails_with(compiler, &block) def fails_with(compiler, &block)
# TODO: deprecate this in future.
# odeprecated "fails_with :llvm" if compiler == :llvm # odeprecated "fails_with :llvm" if compiler == :llvm
compiler_failures << CompilerFailure.create(compiler, &block) compiler_failures << CompilerFailure.create(compiler, &block)
end end

View File

@ -3,7 +3,7 @@ require "software_spec"
describe CompilerSelector do describe CompilerSelector do
subject { described_class.new(software_spec, versions, compilers) } 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(:software_spec) { SoftwareSpec.new }
let(:cc) { :clang } let(:cc) { :clang }
let(:versions) do let(:versions) do
@ -28,7 +28,6 @@ describe CompilerSelector do
describe "#compiler" do describe "#compiler" do
it "raises an error if no matching compiler can be found" do it "raises an error if no matching compiler can be found" do
software_spec.fails_with(:clang) software_spec.fails_with(:clang)
software_spec.fails_with(:llvm)
software_spec.fails_with(:gcc) software_spec.fails_with(:gcc)
software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7") software_spec.fails_with(gcc: "4.7")
@ -45,11 +44,6 @@ describe CompilerSelector do
expect(subject.compiler).to eq(:gcc) expect(subject.compiler).to eq(:gcc)
end 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 it "returns clang if it fails with gcc" do
software_spec.fails_with(:gcc) software_spec.fails_with(:gcc)
expect(subject.compiler).to eq(:clang) expect(subject.compiler).to eq(:clang)
@ -68,13 +62,11 @@ describe CompilerSelector do
it "returns gcc if it fails with clang and llvm" do it "returns gcc if it fails with clang and llvm" do
software_spec.fails_with(:clang) software_spec.fails_with(:clang)
software_spec.fails_with(:llvm)
expect(subject.compiler).to eq(:gcc) expect(subject.compiler).to eq(:gcc)
end end
it "returns clang if it fails with gcc and llvm" do it "returns clang if it fails with gcc and llvm" do
software_spec.fails_with(:gcc) software_spec.fails_with(:gcc)
software_spec.fails_with(:llvm)
expect(subject.compiler).to eq(:clang) expect(subject.compiler).to eq(:clang)
end end
@ -87,7 +79,6 @@ describe CompilerSelector do
example "returns a lower version of gcc if it fails with the highest version" 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(:clang)
software_spec.fails_with(:gcc) software_spec.fails_with(:gcc)
software_spec.fails_with(:llvm)
software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.8")
expect(subject.compiler).to eq("gcc-4.7") expect(subject.compiler).to eq("gcc-4.7")
end end
@ -102,7 +93,6 @@ describe CompilerSelector do
allow(versions).to receive(:gcc_build_version).and_return(Version::NULL) allow(versions).to receive(:gcc_build_version).and_return(Version::NULL)
software_spec.fails_with(:clang) software_spec.fails_with(:clang)
software_spec.fails_with(:llvm)
software_spec.fails_with(gcc: "4.8") software_spec.fails_with(gcc: "4.8")
software_spec.fails_with(gcc: "4.7") software_spec.fails_with(gcc: "4.7")

View File

@ -146,17 +146,13 @@ describe Requirement do
end end
describe "#build?" do describe "#build?" do
context "#build true is specified" do context ":build tag is specified" do
let(:klass) do subject { described_class.new([:build]) }
Class.new(described_class) do
build true
end
end
it { is_expected.to be_a_build_requirement } it { is_expected.to be_a_build_requirement }
end end
context "#build ommitted" do context "#build omitted" do
it { is_expected.not_to be_a_build_requirement } it { is_expected.not_to be_a_build_requirement }
end end
end end

View File

@ -1,92 +1,92 @@
require "utils/shell" require "utils/shell"
describe Utils::Shell do describe Utils::Shell do
describe "::shell_profile" do describe "::profile" do
it "returns ~/.bash_profile by default" do it "returns ~/.bash_profile by default" do
ENV["SHELL"] = "/bin/another_shell" ENV["SHELL"] = "/bin/another_shell"
expect(subject.shell_profile).to eq("~/.bash_profile") expect(subject.profile).to eq("~/.bash_profile")
end end
it "returns ~/.bash_profile for Sh" do it "returns ~/.bash_profile for Sh" do
ENV["SHELL"] = "/bin/another_shell" ENV["SHELL"] = "/bin/another_shell"
expect(subject.shell_profile).to eq("~/.bash_profile") expect(subject.profile).to eq("~/.bash_profile")
end end
it "returns ~/.bash_profile for Bash" do it "returns ~/.bash_profile for Bash" do
ENV["SHELL"] = "/bin/bash" ENV["SHELL"] = "/bin/bash"
expect(subject.shell_profile).to eq("~/.bash_profile") expect(subject.profile).to eq("~/.bash_profile")
end end
it "returns ~/.zshrc for Zsh" do it "returns ~/.zshrc for Zsh" do
ENV["SHELL"] = "/bin/zsh" ENV["SHELL"] = "/bin/zsh"
expect(subject.shell_profile).to eq("~/.zshrc") expect(subject.profile).to eq("~/.zshrc")
end end
it "returns ~/.kshrc for Ksh" do it "returns ~/.kshrc for Ksh" do
ENV["SHELL"] = "/bin/ksh" ENV["SHELL"] = "/bin/ksh"
expect(subject.shell_profile).to eq("~/.kshrc") expect(subject.profile).to eq("~/.kshrc")
end end
end end
describe "::path_to_shell" do describe "::from_path" do
it "supports a raw command name" 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 end
it "supports full paths" do 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 end
it "supports versions" do 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 end
it "strips newlines" do 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 end
it "returns nil when input is invalid" do it "returns nil when input is invalid" do
expect(subject.path_to_shell("")).to be nil expect(subject.from_path("")).to be nil
expect(subject.path_to_shell("@@@@@@")).to be nil expect(subject.from_path("@@@@@@")).to be nil
expect(subject.path_to_shell("invalid_shell-4.2")).to be nil expect(subject.from_path("invalid_shell-4.2")).to be nil
end end
end end
specify "::sh_quote" do specify "::sh_quote" do
expect(subject.sh_quote("")).to eq("''") expect(subject.send(:sh_quote, "")).to eq("''")
expect(subject.sh_quote("\\")).to eq("\\\\") expect(subject.send(:sh_quote, "\\")).to eq("\\\\")
expect(subject.sh_quote("\n")).to eq("'\n'") expect(subject.send(:sh_quote, "\n")).to eq("'\n'")
expect(subject.sh_quote("$")).to eq("\\$") expect(subject.send(:sh_quote, "$")).to eq("\\$")
expect(subject.sh_quote("word")).to eq("word") expect(subject.send(:sh_quote, "word")).to eq("word")
end end
specify "::csh_quote" do specify "::csh_quote" do
expect(subject.csh_quote("")).to eq("''") expect(subject.send(:csh_quote, "")).to eq("''")
expect(subject.csh_quote("\\")).to eq("\\\\") expect(subject.send(:csh_quote, "\\")).to eq("\\\\")
# note this test is different than for sh # note this test is different than for sh
expect(subject.csh_quote("\n")).to eq("'\\\n'") expect(subject.send(:csh_quote, "\n")).to eq("'\\\n'")
expect(subject.csh_quote("$")).to eq("\\$") expect(subject.send(:csh_quote, "$")).to eq("\\$")
expect(subject.csh_quote("word")).to eq("word") expect(subject.send(:csh_quote, "word")).to eq("word")
end end
describe "::prepend_path_in_shell_profile" do describe "::prepend_path_in_profile" do
let(:path) { "/my/path" } let(:path) { "/my/path" }
it "supports Tcsh" do it "supports Tcsh" do
ENV["SHELL"] = "/bin/tcsh" 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}:$") .to start_with("echo 'setenv PATH #{path}:$")
end end
it "supports Bash" do it "supports Bash" do
ENV["SHELL"] = "/bin/bash" 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}:$") .to start_with("echo 'export PATH=\"#{path}:$")
end end
it "supports Fish" do it "supports Fish" do
ENV["SHELL"] = "/usr/local/bin/fish" 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' >>") .to start_with("echo 'set -g fish_user_paths \"#{path}\" $fish_user_paths' >>")
end end
end end

View File

@ -1,62 +1,24 @@
module Utils 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 module Shell
UNSAFE_SHELL_CHAR = %r{([^A-Za-z0-9_\-.,:/@\n])} module_function
# take a path and heuristically convert it # take a path and heuristically convert it
# to a shell name, return nil if there's no match # 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 # we only care about the basename
shell_name = File.basename(path) shell_name = File.basename(path)
# handle possible version suffix like `zsh-5.2` # handle possible version suffix like `zsh-5.2`
shell_name.sub!(/-.*\z/m, "") shell_name.sub!(/-.*\z/m, "")
shell_name.to_sym if %w[bash csh fish ksh sh tcsh zsh].include?(shell_name) shell_name.to_sym if %w[bash csh fish ksh sh tcsh zsh].include?(shell_name)
end end
module_function :path_to_shell
def preferred_shell def preferred
path_to_shell(ENV.fetch("SHELL", "")) from_path(ENV.fetch("SHELL", ""))
end end
module_function :preferred_shell
def parent_shell def parent
path_to_shell(`ps -p #{Process.ppid} -o ucomm=`.strip) from_path(`ps -p #{Process.ppid} -o ucomm=`.strip)
end 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 # quote values. quoting keys is overkill
def export_value(shell, key, value) def export_value(shell, key, value)
@ -72,24 +34,60 @@ module Utils
"setenv #{key} #{csh_quote(value)};" "setenv #{key} #{csh_quote(value)};"
end end
end end
module_function :export_value
# return the shell profile file based on users' preferred shell # return the shell profile file based on users' preferred shell
def shell_profile def profile
SHELL_PROFILE_MAP.fetch(preferred_shell, "~/.bash_profile") SHELL_PROFILE_MAP.fetch(preferred, "~/.bash_profile")
end end
module_function :shell_profile
def prepend_path_in_shell_profile(path) def prepend_path_in_profile(path)
case preferred_shell case preferred
when :bash, :ksh, :sh, :zsh, nil 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 when :csh, :tcsh
"echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{shell_profile}" "echo 'setenv PATH #{csh_quote(path)}:$PATH' >> #{profile}"
when :fish 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
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
end end