Merge remote-tracking branch 'origin/master' into cache-optimization
This commit is contained in:
commit
27e5d1aee5
@ -472,9 +472,17 @@ class Pathname
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def binary_executable?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def mach_o_bundle?
|
def mach_o_bundle?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dylib?
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "extend/os/pathname"
|
require "extend/os/pathname"
|
||||||
|
|||||||
@ -12,6 +12,7 @@ require "install_renamed"
|
|||||||
require "pkg_version"
|
require "pkg_version"
|
||||||
require "keg"
|
require "keg"
|
||||||
require "migrator"
|
require "migrator"
|
||||||
|
require "linkage_checker"
|
||||||
require "extend/ENV"
|
require "extend/ENV"
|
||||||
require "language/python"
|
require "language/python"
|
||||||
require "tab"
|
require "tab"
|
||||||
@ -1486,22 +1487,50 @@ class Formula
|
|||||||
Requirement.expand(self, &block)
|
Requirement.expand(self, &block)
|
||||||
end
|
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.
|
# Returns a list of Dependency objects that are required at runtime.
|
||||||
# @private
|
# @private
|
||||||
def runtime_dependencies(read_from_tab: true)
|
def runtime_dependencies(read_from_tab: true)
|
||||||
if read_from_tab &&
|
if read_from_tab &&
|
||||||
installed_prefix.directory? &&
|
installed_prefix.directory? &&
|
||||||
(keg = Keg.new(installed_prefix)) &&
|
(keg = opt_or_installed_prefix_keg) &&
|
||||||
(tab_deps = keg.runtime_dependencies)
|
(tab_deps = keg.runtime_dependencies)
|
||||||
return tab_deps.map { |d| Dependency.new d["full_name"] }.compact
|
return tab_deps.map { |d| Dependency.new d["full_name"] }.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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|
|
recursive_dependencies do |_, dependency|
|
||||||
Dependency.prune if dependency.build?
|
Dependency.prune if dependency.build?
|
||||||
Dependency.prune if !dependency.required? && build.without?(dependency)
|
Dependency.prune if !dependency.required? && build.without?(dependency)
|
||||||
end
|
end
|
||||||
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
|
||||||
|
keg = opt_or_installed_prefix_keg
|
||||||
|
return [] unless keg
|
||||||
|
|
||||||
|
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
|
# Returns a list of formulae depended on by this formula that aren't
|
||||||
# installed
|
# installed
|
||||||
def missing_dependencies(hide: nil)
|
def missing_dependencies(hide: nil)
|
||||||
|
|||||||
@ -100,7 +100,7 @@ class LinkageChecker
|
|||||||
checked_dylibs = Set.new
|
checked_dylibs = Set.new
|
||||||
@keg.find do |file|
|
@keg.find do |file|
|
||||||
next if file.symlink? || file.directory?
|
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
|
# weakly loaded dylibs may not actually exist on disk, so skip them
|
||||||
# when checking for broken linkage
|
# when checking for broken linkage
|
||||||
@ -145,10 +145,17 @@ class LinkageChecker
|
|||||||
next false unless dep.optional? || dep.recommended?
|
next false unless dep.optional? || dep.recommended?
|
||||||
formula.build.without?(dep)
|
formula.build.without?(dep)
|
||||||
end
|
end
|
||||||
|
|
||||||
declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name)
|
declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name)
|
||||||
runtime_deps = keg.to_formula.runtime_dependencies(read_from_tab: false)
|
|
||||||
recursive_deps = runtime_deps.map { |dep| dep.to_formula.name }
|
|
||||||
declared_dep_names = declared_deps.map { |dep| dep.split("/").last }
|
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 = []
|
indirect_deps = []
|
||||||
undeclared_deps = []
|
undeclared_deps = []
|
||||||
@brewed_dylibs.each_key do |full_name|
|
@brewed_dylibs.each_key do |full_name|
|
||||||
@ -160,15 +167,19 @@ class LinkageChecker
|
|||||||
undeclared_deps << full_name
|
undeclared_deps << full_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sort_by_formula_full_name!(indirect_deps)
|
sort_by_formula_full_name!(indirect_deps)
|
||||||
sort_by_formula_full_name!(undeclared_deps)
|
sort_by_formula_full_name!(undeclared_deps)
|
||||||
|
|
||||||
unnecessary_deps = declared_dep_names.reject do |full_name|
|
unnecessary_deps = declared_dep_names.reject do |full_name|
|
||||||
name = full_name.split("/").last
|
name = full_name.split("/").last
|
||||||
next true if Formula[name].bin.directory?
|
next true if Formula[name].bin.directory?
|
||||||
@brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
|
@brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
missing_deps = @broken_deps.values.flatten.map { |d| dylib_to_dep(d) }
|
missing_deps = @broken_deps.values.flatten.map { |d| dylib_to_dep(d) }
|
||||||
unnecessary_deps -= missing_deps
|
unnecessary_deps -= missing_deps
|
||||||
|
|
||||||
[indirect_deps, undeclared_deps, unnecessary_deps]
|
[indirect_deps, undeclared_deps, unnecessary_deps]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -93,7 +93,7 @@ module Homebrew
|
|||||||
new_tap = old_tap.tap_migrations[name]
|
new_tap = old_tap.tap_migrations[name]
|
||||||
next unless new_tap
|
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}"
|
new_tap_name = "#{new_tap_user}/#{new_tap_repo}"
|
||||||
|
|
||||||
message = <<~EOS
|
message = <<~EOS
|
||||||
@ -101,9 +101,18 @@ module Homebrew
|
|||||||
EOS
|
EOS
|
||||||
break if new_tap_name == CoreTap.instance.name
|
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
|
message += <<~EOS
|
||||||
You can access it again by running:
|
You can access it again by running:
|
||||||
brew tap #{new_tap_name}
|
brew tap #{new_tap_name}
|
||||||
|
And then you can install it by running:
|
||||||
|
brew #{install_cmd} #{new_tap_new_name}
|
||||||
EOS
|
EOS
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,7 +2,7 @@ require_relative "./extend/formula_cop"
|
|||||||
|
|
||||||
module RuboCop
|
module RuboCop
|
||||||
module Cop
|
module Cop
|
||||||
module FormulaAuditStrict
|
module FormulaAudit
|
||||||
# This cop checks for correct order of components in a Formula
|
# This cop checks for correct order of components in a Formula
|
||||||
#
|
#
|
||||||
# - component_precedence_list has component hierarchy in a nested list
|
# - component_precedence_list has component hierarchy in a nested list
|
||||||
@ -62,8 +62,14 @@ module RuboCop
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# `aspell`: options and resources should be grouped by language
|
||||||
|
WHITELIST = %w[
|
||||||
|
aspell
|
||||||
|
].freeze
|
||||||
|
|
||||||
# Method to format message for reporting component precedence violations
|
# Method to format message for reporting component precedence violations
|
||||||
def component_problem(c1, c2)
|
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)})"
|
problem "`#{format_component(c1)}` (line #{line_number(c1)}) should be put before `#{format_component(c2)}` (line #{line_number(c2)})"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ require_relative "./extend/formula_cop"
|
|||||||
|
|
||||||
module RuboCop
|
module RuboCop
|
||||||
module Cop
|
module Cop
|
||||||
module FormulaAuditStrict
|
module FormulaAudit
|
||||||
# This cop checks if redundant components are present and other component errors
|
# This cop checks if redundant components are present and other component errors
|
||||||
#
|
#
|
||||||
# - `url|checksum|mirror` should be inside `stable` block
|
# - `url|checksum|mirror` should be inside `stable` block
|
||||||
|
|||||||
@ -3,7 +3,7 @@ require_relative "../extend/string"
|
|||||||
|
|
||||||
module RuboCop
|
module RuboCop
|
||||||
module Cop
|
module Cop
|
||||||
module FormulaAuditStrict
|
module FormulaAudit
|
||||||
# This cop audits `desc` in Formulae
|
# This cop audits `desc` in Formulae
|
||||||
#
|
#
|
||||||
# - Checks for existence of `desc`
|
# - Checks for existence of `desc`
|
||||||
@ -33,7 +33,9 @@ module RuboCop
|
|||||||
"Length is calculated as #{@formula_name} + desc. (currently #{desc_length})"
|
"Length is calculated as #{@formula_name} + desc. (currently #{desc_length})"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module FormulaAuditStrict
|
||||||
# This cop audits `desc` in Formulae
|
# This cop audits `desc` in Formulae
|
||||||
#
|
#
|
||||||
# - Checks if `desc` begins with an article
|
# - Checks if `desc` begins with an article
|
||||||
|
|||||||
@ -191,8 +191,7 @@ module RuboCop
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
module FormulaAuditStrict
|
|
||||||
class PyPiUrls < FormulaCop
|
class PyPiUrls < FormulaCop
|
||||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||||
urls = find_every_func_call_by_name(body_node, :url)
|
urls = find_every_func_call_by_name(body_node, :url)
|
||||||
|
|||||||
@ -685,26 +685,42 @@ describe Formula do
|
|||||||
expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"])
|
expect(f5.runtime_dependencies.map(&:name)).to eq(["f1", "f4"])
|
||||||
end
|
end
|
||||||
|
|
||||||
specify "runtime dependencies with optional deps from tap" do
|
describe "#runtime_dependencies" 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(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)
|
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")
|
stub_formula_loader(formula("f2") { url("f2-1.0") }, "baz/qux/f2")
|
||||||
|
|
||||||
f3 = formula "f3" do
|
f3 = formula "f3" do
|
||||||
url "f3-1.0"
|
url "f3-1.0"
|
||||||
|
|
||||||
depends_on "foo/bar/f1" => :optional
|
depends_on "foo/bar/f1" => :optional
|
||||||
depends_on "baz/qux/f2"
|
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
|
end
|
||||||
|
|
||||||
expect(f3.runtime_dependencies.map(&:name)).to eq(["baz/qux/f2"])
|
it "includes non-declared direct dependencies", :focus 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")
|
formula.brew { formula.install }
|
||||||
f3.build = BuildOptions.new(Options.create(["--with-f1"]), f3.options)
|
keg = Keg.for(formula.installed_prefix)
|
||||||
|
keg.link
|
||||||
|
|
||||||
expect(f3.runtime_dependencies.map(&:name)).to eq(["foo/bar/f1", "baz/qux/f2"])
|
linkage_checker = double("linkage checker", undeclared_deps: [dependency.name])
|
||||||
|
allow(LinkageChecker).to receive(:new).and_return(linkage_checker)
|
||||||
|
|
||||||
|
expect(formula.runtime_dependencies.map(&:name)).to eq [dependency.name]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
specify "requirements" do
|
specify "requirements" do
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
require_relative "../../rubocops/components_order_cop"
|
require_relative "../../rubocops/components_order_cop"
|
||||||
|
|
||||||
describe RuboCop::Cop::FormulaAuditStrict::ComponentsOrder do
|
describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
|
||||||
subject(:cop) { described_class.new }
|
subject(:cop) { described_class.new }
|
||||||
|
|
||||||
context "When auditing formula components order" do
|
context "When auditing formula components order" do
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
require_relative "../../rubocops/components_redundancy_cop"
|
require_relative "../../rubocops/components_redundancy_cop"
|
||||||
|
|
||||||
describe RuboCop::Cop::FormulaAuditStrict::ComponentsRedundancy do
|
describe RuboCop::Cop::FormulaAudit::ComponentsRedundancy do
|
||||||
subject(:cop) { described_class.new }
|
subject(:cop) { described_class.new }
|
||||||
|
|
||||||
context "When auditing formula components common errors" do
|
context "When auditing formula components common errors" do
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
require_relative "../../rubocops/formula_desc_cop"
|
require_relative "../../rubocops/formula_desc_cop"
|
||||||
|
|
||||||
describe RuboCop::Cop::FormulaAuditStrict::DescLength do
|
describe RuboCop::Cop::FormulaAudit::DescLength do
|
||||||
subject(:cop) { described_class.new }
|
subject(:cop) { described_class.new }
|
||||||
|
|
||||||
context "When auditing formula desc" do
|
context "When auditing formula desc" do
|
||||||
|
|||||||
@ -164,7 +164,7 @@ describe RuboCop::Cop::FormulaAudit::Urls do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe RuboCop::Cop::FormulaAuditStrict::PyPiUrls do
|
describe RuboCop::Cop::FormulaAudit::PyPiUrls do
|
||||||
subject(:cop) { described_class.new }
|
subject(:cop) { described_class.new }
|
||||||
|
|
||||||
context "when a pypi.python.org URL is used" do
|
context "when a pypi.python.org URL is used" do
|
||||||
|
|||||||
@ -22,7 +22,7 @@ Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshootin
|
|||||||
[](https://travis-ci.org/Homebrew/brew)
|
[](https://travis-ci.org/Homebrew/brew)
|
||||||
[](https://codecov.io/gh/Homebrew/brew)
|
[](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.
|
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)
|
- [@MacHomebrew (Twitter)](https://twitter.com/MacHomebrew)
|
||||||
|
|
||||||
## License
|
## 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/).
|
Documentation is under the [Creative Commons Attribution license](https://creativecommons.org/licenses/by/4.0/).
|
||||||
|
|
||||||
## Donations
|
## Donations
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user