Merge pull request #3659 from MikeMcQuaid/deprecated-requirements-harder

Deprecate requirements harder
This commit is contained in:
Mike McQuaid 2018-01-18 15:27:02 +00:00 committed by GitHub
commit e67b745b2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 140 additions and 463 deletions

View File

@ -27,57 +27,42 @@ class DependencyCollector
odeprecated "'depends_on :tex'"
TeXRequirement.new(tags)
when :autoconf, :automake, :bsdmake, :libtool
output_deprecation(spec, tags)
output_deprecation(spec)
autotools_dep(spec, tags)
when :cairo, :fontconfig, :freetype, :libpng, :pixman
output_deprecation(spec, tags)
output_deprecation(spec)
Dependency.new(spec.to_s, tags)
when :ant, :expat
# output_deprecation(spec, tags)
output_deprecation(spec)
Dependency.new(spec.to_s, tags)
when :libltdl
tags << :run
output_deprecation("libtool", tags)
output_deprecation("libtool")
Dependency.new("libtool", tags)
when :apr
output_deprecation(spec, tags, "apr-util")
output_deprecation(spec, "apr-util")
Dependency.new("apr-util", tags)
when :fortran
# output_deprecation(spec, tags, "gcc")
FortranRequirement.new(tags)
output_deprecation(spec, "gcc")
Dependency.new("gcc", tags)
when :gpg
# output_deprecation(spec, tags, "gnupg")
GPG2Requirement.new(tags)
output_deprecation(spec, "gnupg")
Dependency.new("gnupg", tags)
when :hg
# output_deprecation(spec, tags, "mercurial")
MercurialRequirement.new(tags)
output_deprecation(spec, "mercurial")
Dependency.new("mercurial", tags)
when :mpi
# output_deprecation(spec, tags, "open-mpi")
MPIRequirement.new(*tags)
when :emacs
# output_deprecation(spec, tags)
EmacsRequirement.new(tags)
when :mysql
# output_deprecation(spec, tags)
MysqlRequirement.new(tags)
when :perl
# output_deprecation(spec, tags)
PerlRequirement.new(tags)
when :postgresql
# output_deprecation(spec, tags)
PostgresqlRequirement.new(tags)
output_deprecation(spec, "open-mpi")
Dependency.new("open-mpi", tags)
when :python, :python2
# output_deprecation(spec, tags)
PythonRequirement.new(tags)
output_deprecation(spec, "python")
Dependency.new("python", tags)
when :python3
# output_deprecation(spec, tags)
Python3Requirement.new(tags)
when :rbenv
# output_deprecation(spec, tags)
RbenvRequirement.new(tags)
when :ruby
# output_deprecation(spec, tags)
RubyRequirement.new(tags)
output_deprecation(spec, "python3")
Dependency.new("python3", tags)
when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby
output_deprecation(spec)
Dependency.new(spec, tags)
else
_parse_symbol_spec(spec, tags)
end
@ -88,13 +73,8 @@ class DependencyCollector
Dependency.new(spec.to_s, tags)
end
def output_deprecation(dependency, tags, new_dependency = dependency)
tags_string = if tags.length > 1
" => [:#{tags.join ", :"}]"
elsif tags.length == 1
" => :#{tags.first}"
end
def output_deprecation(dependency, new_dependency = dependency)
odeprecated "'depends_on :#{dependency}'",
"'depends_on \"#{new_dependency}\"#{tags_string}'"
"'depends_on \"#{new_dependency}\"'"
end
end

View File

@ -1,76 +1,134 @@
require "requirements"
require "compat/requirements/emacs_requirement"
require "compat/requirements/fortran_requirement"
require "compat/requirements/language_module_requirement"
require "compat/requirements/mpi_requirement"
require "compat/requirements/perl_requirement"
require "compat/requirements/python_requirement"
require "compat/requirements/ruby_requirement"
require "compat/requirements/tex_requirement"
class MysqlRequirement < Requirement
fatal true
default_formula "mysql"
satisfy { which "mysql_config" }
end
class PostgresqlRequirement < Requirement
fatal true
default_formula "postgresql"
satisfy { which "pg_config" }
end
class RbenvRequirement < Requirement
fatal true
default_formula "rbenv"
satisfy { which "rbenv" }
end
class CVSRequirement < Requirement
fatal true
default_formula "cvs"
satisfy { which "cvs" }
satisfy do
odeprecated("CVSRequirement", "'depends_on \"cvs\"'")
which "cvs"
end
end
class MercurialRequirement < Requirement
class EmacsRequirement < Requirement
fatal true
default_formula "mercurial"
satisfy { which "hg" }
satisfy do
odeprecated("EmacsRequirement", "'depends_on \"cvs\"'")
which "emacs"
end
end
class GPG2Requirement < Requirement
class FortranRequirement < Requirement
fatal true
default_formula "gnupg"
satisfy { which "gpg" }
satisfy do
odeprecated("FortranRequirement", "'depends_on \"cvs\"'")
which "gfortran"
end
end
class GitRequirement < Requirement
fatal true
default_formula "git"
satisfy { Utils.git_available? }
satisfy do
odeprecated("GitRequirement", "'depends_on \"cvs\"'")
which "git"
end
end
class GPG2Requirement < Requirement
fatal true
satisfy do
odeprecated("GPG2Requirement", "'depends_on \"cvs\"'")
which "gpg"
end
end
class MercurialRequirement < Requirement
fatal true
satisfy do
odeprecated("MercurialRequirement", "'depends_on \"cvs\"'")
which "hg"
end
end
class MPIRequirement < Requirement
fatal true
satisfy do
odeprecated("MPIRequirement", "'depends_on \"cvs\"'")
which "mpicc"
end
end
class MysqlRequirement < Requirement
fatal true
satisfy do
odeprecated("MysqlRequirement", "'depends_on \"cvs\"'")
which "mysql_config"
end
end
class PerlRequirement < Requirement
fatal true
satisfy do
odeprecated("PerlRequirement", "'depends_on \"cvs\"'")
which "perl"
end
end
class PostgresqlRequirement < Requirement
fatal true
satisfy do
odeprecated("PostgresqlRequirement", "'depends_on \"cvs\"'")
which "pg_config"
end
end
class PythonRequirement < Requirement
fatal true
satisfy do
odeprecated("PythonRequirement", "'depends_on \"cvs\"'")
which "python"
end
end
class Python3Requirement < Requirement
fatal true
satisfy do
odeprecated("Python3Requirement", "'depends_on \"cvs\"'")
which "python3"
end
end
class RbenvRequirement < Requirement
fatal true
satisfy do
odeprecated("RbenvRequirement", "'depends_on \"cvs\"'")
which "rbenv"
end
end
class RubyRequirement < Requirement
fatal true
satisfy do
odeprecated("RubyRequirement", "'depends_on \"cvs\"'")
which "ruby"
end
end
class SubversionRequirement < Requirement
fatal true
default_formula "subversion"
satisfy { Utils.svn_available? }
satisfy do
odeprecated("SubversionRequirement", "'depends_on \"cvs\"'")
which "svn"
end
end
XcodeDependency = XcodeRequirement
MysqlDependency = MysqlRequirement
PostgresqlDependency = PostgresqlRequirement
GPGDependency = GPG2Requirement
GPGRequirement = GPG2Requirement
TeXDependency = TeXRequirement
MercurialDependency = MercurialRequirement
GitDependency = GitRequirement
FortranDependency = FortranRequirement
JavaDependency = JavaRequirement
LanguageModuleDependency = LanguageModuleRequirement
MPIDependency = MPIRequirement
OsxfuseDependency = OsxfuseRequirement
PythonDependency = PythonRequirement
TuntapDependency = TuntapRequirement
X11Dependency = X11Requirement
ConflictsWithBinaryOsxfuse = NonBinaryOsxfuseRequirement
MinimumMacOSRequirement = MacOSRequirement
class TeXRequirement < Requirement
fatal true
cask "mactex"
download "https://www.tug.org/mactex/"
satisfy do
odeprecated("TeXRequirement", "'depends_on \"cvs\"'")
which("tex") || which("latex")
end
end
MinimumMacOSRequirement = MacOSRequirement

View File

@ -1,35 +0,0 @@
class EmacsRequirement < Requirement
fatal true
default_formula "emacs"
def initialize(tags)
@version = tags.shift if /\d+\.*\d*/ =~ tags.first
super
end
satisfy build_env: false do
next false unless which "emacs"
next true unless @version
emacs_version = Utils.popen_read("emacs", "--batch", "--eval", "(princ emacs-version)")
Version.create(emacs_version) >= Version.create(@version)
end
env do
ENV.prepend_path "PATH", which("emacs").dirname
ENV["EMACS"] = "emacs"
end
def message
if @version
s = "Emacs #{@version} or later is required."
else
s = "Emacs is required."
end
s += super
s
end
def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>"
end
end

View File

@ -1,13 +0,0 @@
require "requirement"
class FortranRequirement < Requirement
fatal true
default_formula "gcc"
env { ENV.fortran }
satisfy build_env: false do
which(ENV["FC"] || "gfortran")
end
end

View File

@ -1,66 +0,0 @@
require "requirement"
# There are multiple implementations of MPI-2 available.
# http://www.mpi-forum.org/
# This requirement is used to find an appropriate one.
class MPIRequirement < Requirement
attr_reader :lang_list
fatal true
default_formula "open-mpi"
env :userpaths
# This method must accept varargs rather than an array for
# backwards compatibility with formulae that call it directly.
def initialize(*tags)
@non_functional = []
@unknown_langs = []
@lang_list = [:cc, :cxx, :f77, :f90] & tags
tags -= @lang_list
super(tags)
end
def mpi_wrapper_works?(compiler)
compiler = which compiler
return false if compiler.nil? || !compiler.executable?
# Some wrappers are non-functional and will return a non-zero exit code
# when invoked for version info.
#
# NOTE: A better test may be to do a small test compilation a la autotools.
quiet_system compiler, "--version"
end
def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} lang_list=#{@lang_list.inspect}>"
end
satisfy do
@lang_list.each do |lang|
case lang
when :cc, :cxx, :f90, :f77
compiler = "mpi" + lang.to_s
@non_functional << compiler unless mpi_wrapper_works? compiler
else
@unknown_langs << lang.to_s
end
end
@unknown_langs.empty? && @non_functional.empty?
end
env do
# Set environment variables to help configure scripts find MPI compilers.
# Variable names taken from:
# https://www.gnu.org/software/autoconf-archive/ax_mpi.html
@lang_list.each do |lang|
compiler = "mpi" + lang.to_s
mpi_path = which compiler
# Fortran 90 environment var has a different name
compiler = "MPIFC" if lang == :f90
ENV[compiler.upcase] = mpi_path
end
end
end

View File

@ -1,36 +0,0 @@
class PerlRequirement < Requirement
fatal true
default_formula "perl"
def initialize(tags)
@version = tags.shift if /^\d+\.\d+$/ =~ tags.first
raise "PerlRequirement requires a version!" unless @version
super
end
satisfy(build_env: false) do
which_all("perl").detect do |perl|
perl_version = Utils.popen_read(perl, "--version")[/v(\d+\.\d+)(?:\.\d+)?/, 1]
next unless perl_version
Version.create(perl_version.to_s) >= Version.create(@version)
end
end
def message
s = "Perl #{@version} is required to install this formula."
s += super
s
end
def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>"
end
def display_s
if @version
"#{name} >= #{@version}"
else
name
end
end
end

View File

@ -1,68 +0,0 @@
require "language/python"
class PythonRequirement < Requirement
fatal true
default_formula "python"
satisfy build_env: false do
python = which_python
next unless python
next unless short_version
# Always use Python 2.7 for consistency on older versions of Mac OS X.
short_version == Version.create("2.7")
end
env do
if !system_python? && short_version == Version.create("2.7")
ENV.prepend_path "PATH", which_python.dirname
end
# Homebrew Python should take precedence over other Pythons in the PATH
ENV.prepend_path "PATH", Formula["python"].opt_bin
ENV.prepend_path "PATH", Formula["python"].opt_libexec/"bin"
if system_python?
ENV["PYTHONPATH"] = "#{HOMEBREW_PREFIX}/lib/python#{short_version}/site-packages"
end
end
private
def short_version
@short_version ||= Language::Python.major_minor_version which_python
end
def which_python
python = which python_binary
return unless python
Pathname.new Utils.popen_read(python, "-c", "import sys; print(sys.executable)").strip
end
def system_python
"/usr/bin/#{python_binary}"
end
def system_python?
system_python == which_python.to_s
end
def python_binary
"python2.7"
end
# Deprecated
alias to_s python_binary
end
class Python3Requirement < PythonRequirement
fatal true
default_formula "python3"
satisfy(build_env: false) { which_python }
private
def python_binary
"python3"
end
end

View File

@ -1,56 +0,0 @@
class RubyRequirement < Requirement
fatal true
default_formula "ruby"
def initialize(tags)
@version = tags.shift if /(\d\.)+\d/ =~ tags.first
raise "RubyRequirement requires a version!" unless @version
super
end
satisfy(build_env: false) { new_enough_ruby }
env do
ENV.prepend_path "PATH", new_enough_ruby.dirname
end
def message
s = "Ruby >= #{@version} is required to install this formula."
s += super
s
end
def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect} version=#{@version.inspect}>"
end
def display_s
if @version
"#{name} >= #{@version}"
else
name
end
end
private
def new_enough_ruby
rubies.detect { |ruby| new_enough?(ruby) }
end
def rubies
rubies = which_all("ruby")
ruby_formula = Formula["ruby"]
rubies.unshift ruby_formula.bin/"ruby" if ruby_formula&.installed?
rubies.uniq
end
def new_enough?(ruby)
version = Utils.popen_read(ruby, "-e", "print RUBY_VERSION").strip
version =~ /^\d+\.\d+/ && Version.create(version) >= min_version
end
def min_version
@min_version ||= Version.create(@version)
end
end

View File

@ -1,20 +0,0 @@
require "requirement"
class TeXRequirement < Requirement
fatal true
cask "mactex"
download "https://www.tug.org/mactex/"
satisfy { which("tex") || which("latex") }
def message
s = <<~EOS
A LaTeX distribution is required for Homebrew to install this formula.
Make sure that "/usr/texbin", or the location you installed it to, is in
your PATH before proceeding.
EOS
s += super
s
end
end

View File

@ -1,8 +1,6 @@
require "language/java"
class JavaRequirement < Requirement
default_formula "jdk"
env do
env_java_common
env_oracle_jdk

View File

@ -14,6 +14,7 @@ require "tap"
require "keg"
require "migrator"
require "extend/ENV"
require "language/python"
# A formula provides instructions and metadata for Homebrew to install a piece
# of software. Every Homebrew formula is a {Formula}.

View File

@ -66,11 +66,6 @@ describe DependencyCollector do
expect(dep).to be_optional
end
specify "ant dependency", :needs_compat do
subject.add ant: :build
expect(find_dependency("ant")).to eq(Dependency.new("ant", [:build]))
end
it "doesn't mutate the dependency spec" do
spec = { "foo" => :optional }
copy = spec.dup

View File

@ -132,64 +132,4 @@ describe FormulaInstaller do
fi.check_install_sanity
}.to raise_error(CannotInstallFormulaError)
end
describe "#install_requirement_formula?", :needs_compat do
before do
@requirement = Python3Requirement.new
@requirement_dependency = @requirement.to_dependency
@install_bottle_for_dependent = false
allow(@requirement).to receive(:satisfied?).and_return(satisfied?)
allow(@requirement).to receive(:satisfied_by_formula?).and_return(satisfied_by_formula?)
allow(@requirement).to receive(:build?).and_return(build?)
@dependent = formula do
url "foo"
version "0.1"
depends_on :python3
end
allow(@dependent).to receive(:installed?).and_return(installed?)
@fi = FormulaInstaller.new(@dependent)
end
subject { @fi.install_requirement_formula?(@requirement_dependency, @requirement, @dependent, @install_bottle_for_dependent) }
context "it returns false when requirement is satisfied" do
let(:satisfied?) { true }
let(:satisfied_by_formula?) { false }
let(:build?) { false }
let(:installed?) { false }
it { is_expected.to be false }
end
context "it returns false when requirement is satisfied but default formula is installed" do
let(:satisfied?) { true }
let(:satisfied_by_formula?) { false }
let(:build?) { false }
let(:installed?) { false }
it { is_expected.to be false }
end
context "it returns false when requirement is :build and dependent is installed" do
let(:satisfied?) { false }
let(:satisfied_by_formula?) { false }
let(:build?) { true }
let(:installed?) { true }
it { is_expected.to be false }
end
context "it returns true when requirement isn't satisfied" do
let(:satisfied?) { false }
let(:satisfied_by_formula?) { false }
let(:build?) { false }
let(:installed?) { false }
it { is_expected.to be true }
end
context "it returns true when requirement is satisfied by a formula" do
let(:satisfied?) { true }
let(:satisfied_by_formula?) { true }
let(:build?) { false }
let(:installed?) { false }
it { is_expected.to be true }
end
end
end

View File

@ -1,14 +1,13 @@
require "compat/requirements/mpi_requirement"
require "compat/requirements"
describe MPIRequirement, :needs_compat do
describe "::new" do
subject { described_class.new(*(wrappers + tags)) }
subject { described_class.new(wrappers + tags) }
let(:wrappers) { [:cc, :cxx, :f77] }
let(:tags) { [:optional, "some-other-tag"] }
it "untangles wrappers and tags" do
expect(subject.lang_list).to eq(wrappers)
expect(subject.tags).to eq(tags)
it "stores wrappers as tags" do
expect(subject.tags).to eq(wrappers + tags)
end
end
end