From e5c82dd3d909a34cab88987f5ea4a32b784f32e2 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 17 Jan 2018 10:43:14 +0000 Subject: [PATCH] Deprecate requirements harder Remove more Requirement logic to enable future removal of default formula logic. Also, output deprecations, convert symbol requirement usage to deps and simplify the compatibility code for the direct Requirement usage. --- .../Homebrew/compat/dependency_collector.rb | 64 +++---- Library/Homebrew/compat/requirements.rb | 168 ++++++++++++------ .../compat/requirements/emacs_requirement.rb | 35 ---- .../requirements/fortran_requirement.rb | 13 -- .../compat/requirements/mpi_requirement.rb | 66 ------- .../compat/requirements/perl_requirement.rb | 36 ---- .../compat/requirements/python_requirement.rb | 68 ------- .../compat/requirements/ruby_requirement.rb | 56 ------ .../compat/requirements/tex_requirement.rb | 20 --- .../os/linux/requirements/java_requirement.rb | 2 - Library/Homebrew/formula.rb | 1 + .../test/dependency_collector_spec.rb | 5 - .../Homebrew/test/formula_installer_spec.rb | 60 ------- Library/Homebrew/test/mpi_requirement_spec.rb | 9 +- 14 files changed, 140 insertions(+), 463 deletions(-) delete mode 100644 Library/Homebrew/compat/requirements/emacs_requirement.rb delete mode 100644 Library/Homebrew/compat/requirements/fortran_requirement.rb delete mode 100644 Library/Homebrew/compat/requirements/mpi_requirement.rb delete mode 100644 Library/Homebrew/compat/requirements/perl_requirement.rb delete mode 100644 Library/Homebrew/compat/requirements/python_requirement.rb delete mode 100644 Library/Homebrew/compat/requirements/ruby_requirement.rb delete mode 100644 Library/Homebrew/compat/requirements/tex_requirement.rb diff --git a/Library/Homebrew/compat/dependency_collector.rb b/Library/Homebrew/compat/dependency_collector.rb index 652cf370b8..1c91f22830 100644 --- a/Library/Homebrew/compat/dependency_collector.rb +++ b/Library/Homebrew/compat/dependency_collector.rb @@ -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 diff --git a/Library/Homebrew/compat/requirements.rb b/Library/Homebrew/compat/requirements.rb index 304dd25049..bffc5f5f1d 100644 --- a/Library/Homebrew/compat/requirements.rb +++ b/Library/Homebrew/compat/requirements.rb @@ -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 diff --git a/Library/Homebrew/compat/requirements/emacs_requirement.rb b/Library/Homebrew/compat/requirements/emacs_requirement.rb deleted file mode 100644 index c8e2ec2746..0000000000 --- a/Library/Homebrew/compat/requirements/emacs_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/compat/requirements/fortran_requirement.rb b/Library/Homebrew/compat/requirements/fortran_requirement.rb deleted file mode 100644 index ba3fead6fb..0000000000 --- a/Library/Homebrew/compat/requirements/fortran_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/compat/requirements/mpi_requirement.rb b/Library/Homebrew/compat/requirements/mpi_requirement.rb deleted file mode 100644 index 065b56c8b2..0000000000 --- a/Library/Homebrew/compat/requirements/mpi_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/compat/requirements/perl_requirement.rb b/Library/Homebrew/compat/requirements/perl_requirement.rb deleted file mode 100644 index 70eb2a36c5..0000000000 --- a/Library/Homebrew/compat/requirements/perl_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/compat/requirements/python_requirement.rb b/Library/Homebrew/compat/requirements/python_requirement.rb deleted file mode 100644 index 3215d0a6c3..0000000000 --- a/Library/Homebrew/compat/requirements/python_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/compat/requirements/ruby_requirement.rb b/Library/Homebrew/compat/requirements/ruby_requirement.rb deleted file mode 100644 index a9ec8c42d2..0000000000 --- a/Library/Homebrew/compat/requirements/ruby_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/compat/requirements/tex_requirement.rb b/Library/Homebrew/compat/requirements/tex_requirement.rb deleted file mode 100644 index cb26a84779..0000000000 --- a/Library/Homebrew/compat/requirements/tex_requirement.rb +++ /dev/null @@ -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 diff --git a/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb b/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb index 7816f6b6f6..23a68743d0 100644 --- a/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb +++ b/Library/Homebrew/extend/os/linux/requirements/java_requirement.rb @@ -1,8 +1,6 @@ require "language/java" class JavaRequirement < Requirement - default_formula "jdk" - env do env_java_common env_oracle_jdk diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 7b1d94eb28..2b74604084 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -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}. diff --git a/Library/Homebrew/test/dependency_collector_spec.rb b/Library/Homebrew/test/dependency_collector_spec.rb index 216bbf316c..0f182a69e9 100644 --- a/Library/Homebrew/test/dependency_collector_spec.rb +++ b/Library/Homebrew/test/dependency_collector_spec.rb @@ -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 diff --git a/Library/Homebrew/test/formula_installer_spec.rb b/Library/Homebrew/test/formula_installer_spec.rb index d3710a4cbc..93f23b18ff 100644 --- a/Library/Homebrew/test/formula_installer_spec.rb +++ b/Library/Homebrew/test/formula_installer_spec.rb @@ -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 diff --git a/Library/Homebrew/test/mpi_requirement_spec.rb b/Library/Homebrew/test/mpi_requirement_spec.rb index 87f99eb3ac..aecdb1b66b 100644 --- a/Library/Homebrew/test/mpi_requirement_spec.rb +++ b/Library/Homebrew/test/mpi_requirement_spec.rb @@ -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