From 8386e6a8c18f5dee30f17386cab652b653b1b860 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sun, 11 Feb 2018 13:25:30 +0000 Subject: [PATCH 01/17] Undeclared dependencies in runtime_dependencies Fixes https://github.com/Homebrew/brew/issues/2173. --- Library/Homebrew/formula.rb | 22 +++++++++++--- Library/Homebrew/test/formula_spec.rb | 44 +++++++++++++++++++-------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 1355e5945c..b226963eaf 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1487,10 +1487,7 @@ class Formula # Returns a list of Dependency objects that are required at runtime. # @private def runtime_dependencies - recursive_dependencies do |_, dependency| - Dependency.prune if dependency.build? - Dependency.prune if !dependency.required? && build.without?(dependency) - end + declared_runtime_dependencies | undeclared_runtime_dependencies end # Returns a list of formulae depended on by this formula that aren't @@ -1835,6 +1832,23 @@ class Formula private + def declared_runtime_dependencies + recursive_dependencies do |_, dependency| + Dependency.prune if dependency.build? + Dependency.prune if !dependency.required? && build.without?(dependency) + end + end + + def undeclared_runtime_dependencies + return [] unless optlinked? + + keg = Keg.new(opt_prefix) + linkage_checker = LinkageChecker.new(keg, self) + dylib_formula_names = linkage_checker.brewed_dylibs.keys + linked_formulae_names = dylib_formula_names - [name] + linked_formulae_names.map { |n| Dependency.new(n) } + end + # Returns the prefix for a given formula version number. # @private def versioned_prefix(v) diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index a9d09cb00b..865ea38361 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -685,26 +685,44 @@ describe Formula do expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"]) end - specify "runtime dependencies with optional deps from tap" do - tap_loader = double + describe "#runtime_dependencies" do + specify "runtime dependencies with optional deps from tap" do + tap_loader = double - allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") - allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) - stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") + allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") + allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) + stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") - f3 = formula "f3" do - url "f3-1.0" + f3 = formula "f3" do + url "f3-1.0" - depends_on "foo/bar/f1" => :optional - depends_on "baz/qux/f2" + depends_on "foo/bar/f1" => :optional + depends_on "baz/qux/f2" + end + + expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) + + stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") + f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) + + expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) end - expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) + it "includes non-declared direct dependencies" do + formula = Class.new(Testball).new + dependency = formula("dependency") { url "f-1.0" } - stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") - f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) + formula.brew { formula.install } + keg = Keg.for(formula.prefix) + keg.link - expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) + brewed_dylibs = { dependency.name => Set["some.dylib"] } + linkage_checker = double("linkage checker", brewed_dylibs: brewed_dylibs) + allow(LinkageChecker).to receive(:new).with(keg, any_args) + .and_return(linkage_checker) + + expect(formula.runtime_dependencies).to include an_object_having_attributes(name: dependency.name) + end end specify "requirements" do From 40ca03e975041b4fce9a3097fed5739653c039f3 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sun, 11 Feb 2018 16:23:22 +0000 Subject: [PATCH 02/17] Add undeclared dependencies to Tab when installing An installed formula doesn't get optlinked until _after_ it's installed, meaning that we can't rely on `opt_prefix` to get the right keg. So, if not optlinked, fall back to the formula's prefix, which will be that of the current installation. --- Library/Homebrew/formula.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index b226963eaf..a6e7750c6c 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -13,6 +13,7 @@ require "pkg_version" require "tap" require "keg" require "migrator" +require "os/mac/linkage_checker" require "extend/ENV" require "language/python" @@ -1840,9 +1841,14 @@ class Formula end def undeclared_runtime_dependencies - return [] unless optlinked? + if optlinked? + keg = Keg.new(opt_prefix) + elsif prefix.directory? + keg = Keg.new(prefix) + else + return [] + end - keg = Keg.new(opt_prefix) linkage_checker = LinkageChecker.new(keg, self) dylib_formula_names = linkage_checker.brewed_dylibs.keys linked_formulae_names = dylib_formula_names - [name] From 10ec789660edb7f727f11989cff003bf2f7275e7 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sun, 11 Feb 2018 16:30:58 +0000 Subject: [PATCH 03/17] Don't include declared dependencies in undeclared oops --- Library/Homebrew/formula.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index a6e7750c6c..f6fa558b99 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1850,9 +1850,7 @@ class Formula end linkage_checker = LinkageChecker.new(keg, self) - dylib_formula_names = linkage_checker.brewed_dylibs.keys - linked_formulae_names = dylib_formula_names - [name] - linked_formulae_names.map { |n| Dependency.new(n) } + linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } end # Returns the prefix for a given formula version number. From fa5245f7adf38833b03e92e42aa5217ac5157773 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Thu, 15 Feb 2018 18:41:45 +0000 Subject: [PATCH 04/17] Only check undeclared dependencies on macOS We don't currently have a LinkageChecker on Linux, so can't do this. --- Library/Homebrew/extend/os/mac/formula.rb | 16 +++++++ Library/Homebrew/formula.rb | 12 +----- Library/Homebrew/test/formula_spec.rb | 44 ++++++-------------- Library/Homebrew/test/os/mac/formula_spec.rb | 19 +++++++++ 4 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 Library/Homebrew/extend/os/mac/formula.rb create mode 100644 Library/Homebrew/test/os/mac/formula_spec.rb diff --git a/Library/Homebrew/extend/os/mac/formula.rb b/Library/Homebrew/extend/os/mac/formula.rb new file mode 100644 index 0000000000..0954e85872 --- /dev/null +++ b/Library/Homebrew/extend/os/mac/formula.rb @@ -0,0 +1,16 @@ +require "os/mac/linkage_checker" + +class Formula + def undeclared_runtime_dependencies + if optlinked? + keg = Keg.new(opt_prefix) + elsif prefix.directory? + keg = Keg.new(prefix) + else + return [] + end + + linkage_checker = LinkageChecker.new(keg, self) + linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } + end +end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index f6fa558b99..72d9b14e5f 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -13,7 +13,6 @@ require "pkg_version" require "tap" require "keg" require "migrator" -require "os/mac/linkage_checker" require "extend/ENV" require "language/python" @@ -1841,16 +1840,7 @@ class Formula end def undeclared_runtime_dependencies - if optlinked? - keg = Keg.new(opt_prefix) - elsif prefix.directory? - keg = Keg.new(prefix) - else - return [] - end - - linkage_checker = LinkageChecker.new(keg, self) - linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } + [] end # Returns the prefix for a given formula version number. diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 865ea38361..a9d09cb00b 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -685,44 +685,26 @@ describe Formula do expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"]) end - describe "#runtime_dependencies" do - specify "runtime dependencies with optional deps from tap" do - tap_loader = double + specify "runtime dependencies with optional deps from tap" do + tap_loader = double - allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") - allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) - stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") + allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") + allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) + stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") - f3 = formula "f3" do - url "f3-1.0" + f3 = formula "f3" do + url "f3-1.0" - depends_on "foo/bar/f1" => :optional - depends_on "baz/qux/f2" - end - - expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) - - stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") - f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) - - expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) + depends_on "foo/bar/f1" => :optional + depends_on "baz/qux/f2" end - it "includes non-declared direct dependencies" do - formula = Class.new(Testball).new - dependency = formula("dependency") { url "f-1.0" } + expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) - formula.brew { formula.install } - keg = Keg.for(formula.prefix) - keg.link + stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") + f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) - brewed_dylibs = { dependency.name => Set["some.dylib"] } - linkage_checker = double("linkage checker", brewed_dylibs: brewed_dylibs) - allow(LinkageChecker).to receive(:new).with(keg, any_args) - .and_return(linkage_checker) - - expect(formula.runtime_dependencies).to include an_object_having_attributes(name: dependency.name) - end + expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) end specify "requirements" do diff --git a/Library/Homebrew/test/os/mac/formula_spec.rb b/Library/Homebrew/test/os/mac/formula_spec.rb new file mode 100644 index 0000000000..21920238b4 --- /dev/null +++ b/Library/Homebrew/test/os/mac/formula_spec.rb @@ -0,0 +1,19 @@ +RSpec.describe Formula do + describe "#runtime_dependencies" do + it "includes non-declared direct dependencies" do + formula = Class.new(Testball).new + dependency = formula("dependency") { url "f-1.0" } + + formula.brew { formula.install } + keg = Keg.for(formula.prefix) + keg.link + + brewed_dylibs = { dependency.name => Set["some.dylib"] } + linkage_checker = double("linkage checker", brewed_dylibs: brewed_dylibs) + allow(LinkageChecker).to receive(:new).with(keg, any_args) + .and_return(linkage_checker) + + expect(formula.runtime_dependencies).to include an_object_having_attributes(name: dependency.name) + end + end +end From 51b27039be6dc4d856f86b542a12d29e28fb86d1 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Thu, 1 Mar 2018 17:30:42 +0000 Subject: [PATCH 05/17] Revert "Only check undeclared dependencies on macOS" This reverts commit fa5245f7adf38833b03e92e42aa5217ac5157773. --- Library/Homebrew/extend/os/mac/formula.rb | 16 ------- Library/Homebrew/formula.rb | 12 +++++- Library/Homebrew/test/formula_spec.rb | 44 ++++++++++++++------ Library/Homebrew/test/os/mac/formula_spec.rb | 19 --------- 4 files changed, 42 insertions(+), 49 deletions(-) delete mode 100644 Library/Homebrew/extend/os/mac/formula.rb delete mode 100644 Library/Homebrew/test/os/mac/formula_spec.rb diff --git a/Library/Homebrew/extend/os/mac/formula.rb b/Library/Homebrew/extend/os/mac/formula.rb deleted file mode 100644 index 0954e85872..0000000000 --- a/Library/Homebrew/extend/os/mac/formula.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "os/mac/linkage_checker" - -class Formula - def undeclared_runtime_dependencies - if optlinked? - keg = Keg.new(opt_prefix) - elsif prefix.directory? - keg = Keg.new(prefix) - else - return [] - end - - linkage_checker = LinkageChecker.new(keg, self) - linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } - end -end diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 72d9b14e5f..f6fa558b99 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -13,6 +13,7 @@ require "pkg_version" require "tap" require "keg" require "migrator" +require "os/mac/linkage_checker" require "extend/ENV" require "language/python" @@ -1840,7 +1841,16 @@ class Formula end def undeclared_runtime_dependencies - [] + if optlinked? + keg = Keg.new(opt_prefix) + elsif prefix.directory? + keg = Keg.new(prefix) + else + return [] + end + + linkage_checker = LinkageChecker.new(keg, self) + linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } end # Returns the prefix for a given formula version number. diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index a9d09cb00b..865ea38361 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -685,26 +685,44 @@ describe Formula do expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"]) end - specify "runtime dependencies with optional deps from tap" do - tap_loader = double + describe "#runtime_dependencies" do + specify "runtime dependencies with optional deps from tap" do + tap_loader = double - allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") - allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) - stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") + allow(tap_loader).to receive(:get_formula).and_raise(RuntimeError, "tried resolving tap formula") + allow(Formulary).to receive(:loader_for).with("foo/bar/f1", from: nil).and_return(tap_loader) + stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2") - f3 = formula "f3" do - url "f3-1.0" + f3 = formula "f3" do + url "f3-1.0" - depends_on "foo/bar/f1" => :optional - depends_on "baz/qux/f2" + depends_on "foo/bar/f1" => :optional + depends_on "baz/qux/f2" + end + + expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) + + stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") + f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) + + expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) end - expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"]) + it "includes non-declared direct dependencies" do + formula = Class.new(Testball).new + dependency = formula("dependency") { url "f-1.0" } - stub_formula_loader(formula("f1") { url("f1-1.0") }, "foo/bar/f1") - f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options) + formula.brew { formula.install } + keg = Keg.for(formula.prefix) + keg.link - expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) + brewed_dylibs = { dependency.name => Set["some.dylib"] } + linkage_checker = double("linkage checker", brewed_dylibs: brewed_dylibs) + allow(LinkageChecker).to receive(:new).with(keg, any_args) + .and_return(linkage_checker) + + expect(formula.runtime_dependencies).to include an_object_having_attributes(name: dependency.name) + end end specify "requirements" do diff --git a/Library/Homebrew/test/os/mac/formula_spec.rb b/Library/Homebrew/test/os/mac/formula_spec.rb deleted file mode 100644 index 21920238b4..0000000000 --- a/Library/Homebrew/test/os/mac/formula_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -RSpec.describe Formula do - describe "#runtime_dependencies" do - it "includes non-declared direct dependencies" do - formula = Class.new(Testball).new - dependency = formula("dependency") { url "f-1.0" } - - formula.brew { formula.install } - keg = Keg.for(formula.prefix) - keg.link - - brewed_dylibs = { dependency.name => Set["some.dylib"] } - linkage_checker = double("linkage checker", brewed_dylibs: brewed_dylibs) - allow(LinkageChecker).to receive(:new).with(keg, any_args) - .and_return(linkage_checker) - - expect(formula.runtime_dependencies).to include an_object_having_attributes(name: dependency.name) - end - end -end From 0a2f0ab4563f4d438aac9137deae2b1cf15366c5 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Mon, 12 Mar 2018 09:20:24 +0000 Subject: [PATCH 06/17] Fix formula/linkage_checker infinite recursion --- Library/Homebrew/formula.rb | 40 ++++++++++++++--------------- Library/Homebrew/linkage_checker.rb | 3 ++- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index dbe74b5848..29f6c728da 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1491,6 +1491,26 @@ class Formula declared_runtime_dependencies | undeclared_runtime_dependencies end + def declared_runtime_dependencies + recursive_dependencies do |_, dependency| + Dependency.prune if dependency.build? + Dependency.prune if !dependency.required? && build.without?(dependency) + end + end + + def undeclared_runtime_dependencies + if optlinked? + keg = Keg.new(opt_prefix) + elsif prefix.directory? + keg = Keg.new(prefix) + else + return [] + end + + linkage_checker = LinkageChecker.new(keg, self) + linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } + end + # Returns a list of formulae depended on by this formula that aren't # installed def missing_dependencies(hide: nil) @@ -1833,26 +1853,6 @@ class Formula private - def declared_runtime_dependencies - recursive_dependencies do |_, dependency| - Dependency.prune if dependency.build? - Dependency.prune if !dependency.required? && build.without?(dependency) - end - end - - def undeclared_runtime_dependencies - if optlinked? - keg = Keg.new(opt_prefix) - elsif prefix.directory? - keg = Keg.new(prefix) - else - return [] - end - - linkage_checker = LinkageChecker.new(keg, self) - linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } - end - # Returns the prefix for a given formula version number. # @private def versioned_prefix(v) diff --git a/Library/Homebrew/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb index cf6c12f22c..345fde47e6 100644 --- a/Library/Homebrew/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -63,7 +63,8 @@ class LinkageChecker formula.build.without?(dep) end declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name) - recursive_deps = keg.to_formula.runtime_dependencies.map { |dep| dep.to_formula.full_name } + recursive_deps = keg.to_formula.declared_runtime_dependencies + .map { |dep| dep.to_formula.full_name } declared_dep_names = declared_deps.map { |dep| dep.split("/").last } indirect_deps = [] undeclared_deps = [] From 264acb22f4443ecd6c9133e7700ac06b63a3012b Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 7 Apr 2018 12:16:10 +0100 Subject: [PATCH 07/17] Restore Formula#declared_runtime_dependencies This got lost in a merge. --- Library/Homebrew/formula.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 75cb846103..c6af96f6d0 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1498,6 +1498,13 @@ class Formula declared_runtime_dependencies | undeclared_runtime_dependencies end + def declared_runtime_dependencies + recursive_dependencies do |_, dependency| + Dependency.prune if dependency.build? + Dependency.prune if !dependency.required? && build.without?(dependency) + end + end + def undeclared_runtime_dependencies if optlinked? keg = Keg.new(opt_prefix) From 3c0443123f3ba86c8dffe087253b73e2e328bfeb Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 7 Apr 2018 12:17:12 +0100 Subject: [PATCH 08/17] Test Formula with undeclared_deps Changed in 10ec789660edb7f727f11989cff003bf2f7275e7. --- Library/Homebrew/test/formula_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index 0680644c88..bb0d1d2ba7 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -716,8 +716,7 @@ describe Formula do keg = Keg.for(formula.prefix) keg.link - brewed_dylibs = { dependency.name => Set["some.dylib"] } - linkage_checker = double("linkage checker", brewed_dylibs: brewed_dylibs) + linkage_checker = double("linkage checker", undeclared_deps: [dependency.name]) allow(LinkageChecker).to receive(:new).with(keg, any_args) .and_return(linkage_checker) From 1d3ed256a06477bd688da7f908f7aaa14d24e896 Mon Sep 17 00:00:00 2001 From: commitay Date: Tue, 24 Apr 2018 18:27:37 +1000 Subject: [PATCH 09/17] components_order_cop: make non-strict --- Library/Homebrew/rubocops/components_order_cop.rb | 8 +++++++- .../Homebrew/test/rubocops/components_order_cop_spec.rb | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/rubocops/components_order_cop.rb b/Library/Homebrew/rubocops/components_order_cop.rb index a1a576177b..912f4d3804 100644 --- a/Library/Homebrew/rubocops/components_order_cop.rb +++ b/Library/Homebrew/rubocops/components_order_cop.rb @@ -2,7 +2,7 @@ require_relative "./extend/formula_cop" module RuboCop module Cop - module FormulaAuditStrict + module FormulaAudit # This cop checks for correct order of components in a Formula # # - component_precedence_list has component hierarchy in a nested list @@ -62,8 +62,14 @@ module RuboCop end end + # `aspell`: options and resources should be grouped by language + WHITELIST = %w[ + aspell + ].freeze + # Method to format message for reporting component precedence violations def component_problem(c1, c2) + return if WHITELIST.include?(@formula_name) problem "`#{format_component(c1)}` (line #{line_number(c1)}) should be put before `#{format_component(c2)}` (line #{line_number(c2)})" end diff --git a/Library/Homebrew/test/rubocops/components_order_cop_spec.rb b/Library/Homebrew/test/rubocops/components_order_cop_spec.rb index cd7cc5893a..7466f2d6b6 100644 --- a/Library/Homebrew/test/rubocops/components_order_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/components_order_cop_spec.rb @@ -1,6 +1,6 @@ require_relative "../../rubocops/components_order_cop" -describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do +describe RuboCop::Cop::FormulaAudit::ComponentsOrder do subject(:cop) { described_class.new } context "When auditing formula components order" do From 9e24cb9c62a42e8a74bd67291d0f97a3ce343fa3 Mon Sep 17 00:00:00 2001 From: commitay Date: Wed, 25 Apr 2018 07:58:01 +1000 Subject: [PATCH 10/17] components_redundancy_cop: make non-strict --- Library/Homebrew/rubocops/components_redundancy_cop.rb | 2 +- .../Homebrew/test/rubocops/components_redundancy_cop_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/rubocops/components_redundancy_cop.rb b/Library/Homebrew/rubocops/components_redundancy_cop.rb index 7495b986b7..e22ec6a910 100644 --- a/Library/Homebrew/rubocops/components_redundancy_cop.rb +++ b/Library/Homebrew/rubocops/components_redundancy_cop.rb @@ -2,7 +2,7 @@ require_relative "./extend/formula_cop" module RuboCop module Cop - module FormulaAuditStrict + module FormulaAudit # This cop checks if redundant components are present and other component errors # # - `url|checksum|mirror` should be inside `stable` block diff --git a/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb b/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb index d8878ae797..fd325e5846 100644 --- a/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/components_redundancy_cop_spec.rb @@ -1,6 +1,6 @@ require_relative "../../rubocops/components_redundancy_cop" -describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do +describe RuboCop::Cop::FormulaAudit::ComponentsRedundancy do subject(:cop) { described_class.new } context "When auditing formula components common errors" do From aad17dac3580e80b9f4c915c9e7d9feac4e8eabd Mon Sep 17 00:00:00 2001 From: Maxim Belkin Date: Tue, 24 Apr 2018 17:02:39 -0500 Subject: [PATCH 11/17] Shorten some links in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 240774ed2e..d9bc5dc48c 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshootin [![Travis](https://img.shields.io/travis/Homebrew/brew.svg)](https://travis-ci.org/Homebrew/brew) [![Codecov](https://img.shields.io/codecov/c/github/Homebrew/brew.svg)](https://codecov.io/gh/Homebrew/brew) -We'd love you to contribute to Homebrew. First, please read our [Contribution Guide](https://github.com/Homebrew/brew/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Homebrew/brew/blob/master/CODE_OF_CONDUCT.md#code-of-conduct). +We'd love you to contribute to Homebrew. First, please read our [Contribution Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md#code-of-conduct). We explicitly welcome contributions from people who have never contributed to open-source before: we were all beginners once! We can help build on a partially working pull request with the aim of getting it merged. We are also actively seeking to diversify our contributors and especially welcome contributions from women from all backgrounds and people of colour. @@ -52,7 +52,7 @@ Former maintainers with significant contributions include [Tim Smith](https://gi - [@MacHomebrew (Twitter)](https://twitter.com/MacHomebrew) ## License -Code is under the [BSD 2-clause "Simplified" License](https://github.com/Homebrew/brew/tree/master/LICENSE.txt). +Code is under the [BSD 2-clause "Simplified" License](LICENSE.txt). Documentation is under the [Creative Commons Attribution license](https://creativecommons.org/licenses/by/4.0/). ## Donations From 1b7e6f7eb2c74df354afc327f8877a45f0786068 Mon Sep 17 00:00:00 2001 From: commitay Date: Wed, 25 Apr 2018 07:35:26 +1000 Subject: [PATCH 12/17] urls_cop pypiurls: make non-strict --- Library/Homebrew/rubocops/urls_cop.rb | 3 +-- Library/Homebrew/test/rubocops/urls_cop_spec.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Library/Homebrew/rubocops/urls_cop.rb b/Library/Homebrew/rubocops/urls_cop.rb index 0ffa19bdf2..30420a793a 100644 --- a/Library/Homebrew/rubocops/urls_cop.rb +++ b/Library/Homebrew/rubocops/urls_cop.rb @@ -191,8 +191,7 @@ module RuboCop end end end - end - module FormulaAuditStrict + class PyPiUrls < FormulaCop def audit_formula(_node, _class_node, _parent_class_node, body_node) urls = find_every_func_call_by_name(body_node, :url) diff --git a/Library/Homebrew/test/rubocops/urls_cop_spec.rb b/Library/Homebrew/test/rubocops/urls_cop_spec.rb index 494028bd50..9f9f6ded1e 100644 --- a/Library/Homebrew/test/rubocops/urls_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/urls_cop_spec.rb @@ -164,7 +164,7 @@ describe RuboCop::Cop::FormulaAudit::Urls do end end -describe RuboCop::Cop::FormulaAuditStrict::PyPiUrls do +describe RuboCop::Cop::FormulaAudit::PyPiUrls do subject(:cop) { described_class.new } context "when a pypi.python.org URL is used" do From 156451bd4bb7002f11c94e27123dc685cf09d0e4 Mon Sep 17 00:00:00 2001 From: commitay Date: Wed, 25 Apr 2018 07:48:21 +1000 Subject: [PATCH 13/17] formula_desc_cop desclength: make non-strict --- Library/Homebrew/rubocops/formula_desc_cop.rb | 4 +++- Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/rubocops/formula_desc_cop.rb b/Library/Homebrew/rubocops/formula_desc_cop.rb index 240a280723..faffd42f6c 100644 --- a/Library/Homebrew/rubocops/formula_desc_cop.rb +++ b/Library/Homebrew/rubocops/formula_desc_cop.rb @@ -3,7 +3,7 @@ require_relative "../extend/string" module RuboCop module Cop - module FormulaAuditStrict + module FormulaAudit # This cop audits `desc` in Formulae # # - Checks for existence of `desc` @@ -33,7 +33,9 @@ module RuboCop "Length is calculated as #{@formula_name} + desc. (currently #{desc_length})" end end + end + module FormulaAuditStrict # This cop audits `desc` in Formulae # # - Checks if `desc` begins with an article diff --git a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb index aacb52ebb4..20600f071d 100644 --- a/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb +++ b/Library/Homebrew/test/rubocops/formula_desc_cop_spec.rb @@ -1,6 +1,6 @@ require_relative "../../rubocops/formula_desc_cop" -describe RuboCop::Cop::FormulaAuditStrict::DescLength do +describe RuboCop::Cop::FormulaAudit::DescLength do subject(:cop) { described_class.new } context "When auditing formula desc" do From 71f4f522d7b9d8f3d4996feb6cc36003d3a4246e Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 25 Apr 2018 10:16:22 +0100 Subject: [PATCH 14/17] missing_formula: improve migration messaging. Particularly in the cask case we can do a better job of communicating how the new formula can be installed. Fixes #4089. --- Library/Homebrew/missing_formula.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb index 8a80e90d57..3b4682d668 100644 --- a/Library/Homebrew/missing_formula.rb +++ b/Library/Homebrew/missing_formula.rb @@ -93,7 +93,7 @@ module Homebrew new_tap = old_tap.tap_migrations[name] next unless new_tap - new_tap_user, new_tap_repo, = new_tap.split("/") + new_tap_user, new_tap_repo, new_tap_new_name = new_tap.split("/") new_tap_name = "#{new_tap_user}/#{new_tap_repo}" message = <<~EOS @@ -101,9 +101,18 @@ module Homebrew EOS break if new_tap_name == CoreTap.instance.name + install_cmd = if new_tap_user == "caskroom" + "cask install" + else + "install" + end + new_tap_new_name ||= name + message += <<~EOS You can access it again by running: brew tap #{new_tap_name} + And then you can install it by running: + brew #{install_cmd} #{new_tap_new_name} EOS break end From c167614797f324f5d0fb7d2d5f77ced27a697d61 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 25 Apr 2018 10:26:02 +0100 Subject: [PATCH 15/17] linkage_checker: handle missing formulae. --- Library/Homebrew/linkage_checker.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Library/Homebrew/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb index 45812e31df..f60cca98c1 100644 --- a/Library/Homebrew/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -62,10 +62,17 @@ class LinkageChecker next false unless dep.optional? || dep.recommended? formula.build.without?(dep) end + declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name) - runtime_deps = keg.to_formula.declared_runtime_dependencies - recursive_deps = runtime_deps.map { |dep| dep.to_formula.name } declared_dep_names = declared_deps.map { |dep| dep.split("/").last } + recursive_deps = formula.declared_runtime_dependencies.map do |dep| + begin + dep.to_formula.name + rescue FormulaUnavailableError + nil + end + end.compact + indirect_deps = [] undeclared_deps = [] @brewed_dylibs.each_key do |full_name| @@ -77,13 +84,16 @@ class LinkageChecker undeclared_deps << full_name end end + sort_by_formula_full_name!(indirect_deps) sort_by_formula_full_name!(undeclared_deps) + unnecessary_deps = declared_dep_names.reject do |full_name| name = full_name.split("/").last next true if Formula[name].bin.directory? @brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name) end + [indirect_deps, undeclared_deps, unnecessary_deps] end From 3454d6a96199cc4f405a52d1525d0cc760a0ebf8 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 25 Apr 2018 11:44:29 +0100 Subject: [PATCH 16/17] runtime_deps: improve documentation and consistency. --- Library/Homebrew/formula.rb | 27 +++++++++++++++++++-------- Library/Homebrew/linkage_checker.rb | 4 +++- Library/Homebrew/test/formula_spec.rb | 9 ++++----- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 69c60a3d28..5a146d4bcc 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -1487,12 +1487,23 @@ class Formula Requirement.expand(self, &block) end + # Returns a Keg for the opt_prefix or installed_prefix if they exist. + # If not, return nil. + # @private + def opt_or_installed_prefix_keg + if optlinked? && opt_prefix.exist? + Keg.new(opt_prefix) + elsif installed_prefix.directory? + Keg.new(installed_prefix) + end + end + # Returns a list of Dependency objects that are required at runtime. # @private def runtime_dependencies(read_from_tab: true) if read_from_tab && installed_prefix.directory? && - (keg = Keg.new(installed_prefix)) && + (keg = opt_or_installed_prefix_keg) && (tab_deps = keg.runtime_dependencies) return tab_deps.map { |d| Dependency.new d["full_name"] }.compact end @@ -1500,6 +1511,8 @@ class Formula declared_runtime_dependencies | undeclared_runtime_dependencies end + # Returns a list of Dependency objects that are declared in the formula. + # @private def declared_runtime_dependencies recursive_dependencies do |_, dependency| Dependency.prune if dependency.build? @@ -1507,14 +1520,12 @@ class Formula end end + # Returns a list of Dependency objects that are not declared in the formula + # but the formula links to. + # @private def undeclared_runtime_dependencies - if optlinked? - keg = Keg.new(opt_prefix) - elsif prefix.directory? - keg = Keg.new(prefix) - else - return [] - end + keg = opt_or_installed_prefix_keg + return [] unless keg linkage_checker = LinkageChecker.new(keg, self) linkage_checker.undeclared_deps.map { |n| Dependency.new(n) } diff --git a/Library/Homebrew/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb index 6984397435..85bb003a3f 100644 --- a/Library/Homebrew/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -2,6 +2,8 @@ require "keg" require "formula" class LinkageChecker + attr_reader :undeclared_deps + def initialize(keg, formula = nil) @keg = keg @formula = formula || resolve_formula(keg) @@ -142,7 +144,7 @@ class LinkageChecker missing_deps = @broken_deps.values.flatten.map { |d| dylib_to_dep(d) } unnecessary_deps -= missing_deps - + [indirect_deps, undeclared_deps, unnecessary_deps] end diff --git a/Library/Homebrew/test/formula_spec.rb b/Library/Homebrew/test/formula_spec.rb index bb0d1d2ba7..6ad102756e 100644 --- a/Library/Homebrew/test/formula_spec.rb +++ b/Library/Homebrew/test/formula_spec.rb @@ -708,19 +708,18 @@ describe Formula do expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"]) end - it "includes non-declared direct dependencies" do + it "includes non-declared direct dependencies", :focus do formula = Class.new(Testball).new dependency = formula("dependency") { url "f-1.0" } formula.brew { formula.install } - keg = Keg.for(formula.prefix) + keg = Keg.for(formula.installed_prefix) keg.link linkage_checker = double("linkage checker", undeclared_deps: [dependency.name]) - allow(LinkageChecker).to receive(:new).with(keg, any_args) - .and_return(linkage_checker) + allow(LinkageChecker).to receive(:new).and_return(linkage_checker) - expect(formula.runtime_dependencies).to include an_object_having_attributes(name: dependency.name) + expect(formula.runtime_dependencies.map(&:name)).to eq [dependency.name] end end From 8035afcc36ac45ebd127f670b13ab32414c310fa Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Wed, 25 Apr 2018 12:08:33 +0100 Subject: [PATCH 17/17] linkage_checker: fix generic pathname calls. --- Library/Homebrew/extend/pathname.rb | 8 ++++++++ Library/Homebrew/linkage_checker.rb | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Library/Homebrew/extend/pathname.rb b/Library/Homebrew/extend/pathname.rb index ec7293496e..dfe24b7886 100644 --- a/Library/Homebrew/extend/pathname.rb +++ b/Library/Homebrew/extend/pathname.rb @@ -472,9 +472,17 @@ class Pathname } end + def binary_executable? + false + end + def mach_o_bundle? false end + + def dylib? + false + end end require "extend/os/pathname" diff --git a/Library/Homebrew/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb index 85bb003a3f..bf390c4270 100644 --- a/Library/Homebrew/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -66,7 +66,7 @@ class LinkageChecker checked_dylibs = Set.new @keg.find do |file| next if file.symlink? || file.directory? - next unless file.dylib? || file.binary_executable? || file.mach_o_bundle? + next if !file.dylib? && !file.binary_executable? && !file.mach_o_bundle? # weakly loaded dylibs may not actually exist on disk, so skip them # when checking for broken linkage