Merge pull request #8126 from MLH-Fellowship/integrate-deps

deps: Print cask dependencies
This commit is contained in:
Mike McQuaid 2020-07-30 10:20:30 +01:00 committed by GitHub
commit 4888a677c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 198 additions and 35 deletions

View File

@ -0,0 +1,59 @@
# frozen_string_literal: true
# An adapter for casks to provide dependency information in a formula-like interface
class CaskDependent
def initialize(cask)
@cask = cask
end
def name
@cask.token
end
def full_name
@cask.full_name
end
def runtime_dependencies
recursive_dependencies
end
def deps
@deps ||= begin
@cask.depends_on.formula.map do |f|
Dependency.new f
end
end
end
def requirements
@requirements ||= begin
requirements = []
dsl_reqs = @cask.depends_on
dsl_reqs.arch&.each do |arch|
requirements << ArchRequirement.new([:x86_64]) if arch[:bits] == 64
requirements << ArchRequirement.new([arch[:type]])
end
dsl_reqs.cask.each do |cask_ref|
requirements << Requirement.new([{ cask: cask_ref }])
end
requirements << dsl_reqs.macos if dsl_reqs.macos
requirements << X11Requirement.new if dsl_reqs.x11
requirements
end
end
def recursive_dependencies(&block)
Dependency.expand(self, &block)
end
def recursive_requirements(&block)
Requirement.expand(self, &block)
end
def any_version_installed?
@cask.installed?
end
end

View File

@ -35,6 +35,7 @@ module Homebrew
def freeze_named_args!(named_args)
# Reset cache values reliant on named_args
@formulae = nil
@formulae_and_casks = nil
@resolved_formulae = nil
@resolved_formulae_casks = nil
@formulae_paths = nil
@ -90,6 +91,24 @@ module Homebrew
end.uniq(&:name).freeze
end
def formulae_and_casks
@formulae_and_casks ||= begin
formulae_and_casks = []
downcased_unique_named.each do |name|
formulae_and_casks << Formulary.factory(name, spec)
rescue FormulaUnavailableError
begin
formulae_and_casks << Cask::CaskLoader.load(name)
rescue Cask::CaskUnavailableError
raise "No available formula or cask with the name \"#{name}\""
end
end
formulae_and_casks.freeze
end
end
def resolved_formulae
require "formula"

View File

@ -3,6 +3,7 @@
require "formula"
require "ostruct"
require "cli/parser"
require "cask/caskroom"
module Homebrew
extend DependenciesHelpers
@ -64,51 +65,68 @@ module Homebrew
Formulary.enable_factory_cache!
recursive = !args.send("1?")
installed = args.installed? || args.formulae.all?(&:opt_or_installed_prefix_keg)
installed = args.installed? || dependents(args.formulae_and_casks).all?(&:any_version_installed?)
@use_runtime_dependencies = installed && recursive &&
!args.tree? &&
!args.include_build? &&
!args.include_test? &&
!args.include_optional? &&
!args.skip_recommended?
if args.tree?
if args.installed?
puts_deps_tree Formula.installed.sort, recursive
dependents = if args.named.present?
sorted_dependents(args.formulae_and_casks)
elsif args.installed?
sorted_dependents(Formula.installed + Cask::Caskroom.casks)
else
raise FormulaUnspecifiedError if args.no_named?
puts_deps_tree args.formulae, recursive
raise FormulaUnspecifiedError
end
puts_deps_tree dependents, recursive
return
elsif args.all?
puts_deps Formula.sort, recursive
puts_deps sorted_dependents(Formula.to_a + Cask::Cask.to_a), recursive
return
elsif !args.no_named? && args.for_each?
puts_deps args.formulae, recursive
puts_deps sorted_dependents(args.formulae_and_casks), recursive
return
end
if args.no_named?
raise FormulaUnspecifiedError unless args.installed?
puts_deps Formula.installed.sort, recursive
puts_deps sorted_dependents(Formula.installed + Cask::Caskroom.casks), recursive
return
end
all_deps = deps_for_formulae(args.formulae, recursive, &(args.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps.select!(&:installed?) if args.installed?
dependents = dependents(args.formulae_and_casks)
all_deps = deps_for_dependents(dependents, recursive, &(args.union? ? :| : :&))
condense_requirements(all_deps)
all_deps.map!(&method(:dep_display_name))
all_deps.uniq!
all_deps.sort! unless args.n?
puts all_deps
end
def condense_requirements(deps)
return deps if args.include_requirements?
def dependents(formulae_or_casks)
formulae_or_casks.map do |formula_or_cask|
if formula_or_cask.is_a?(Formula)
formula_or_cask
else
CaskDependent.new(formula_or_cask)
end
end
end
deps.select { |dep| dep.is_a? Dependency }
def sorted_dependents(formulae_or_casks)
dependents(formulae_or_casks).sort_by(&:name)
end
def condense_requirements(deps)
deps.select! { |dep| dep.is_a?(Dependency) } unless args.include_requirements?
deps.select! { |dep| dep.is_a?(Requirement) || dep.installed? } if args.installed?
end
def dep_display_name(dep)
@ -136,41 +154,41 @@ module Homebrew
str
end
def deps_for_formula(f, recursive = false)
def deps_for_dependent(d, recursive = false)
includes, ignores = argv_includes_ignores(ARGV)
deps = f.runtime_dependencies if @use_runtime_dependencies
deps = d.runtime_dependencies if @use_runtime_dependencies
if recursive
deps ||= recursive_includes(Dependency, f, includes, ignores)
reqs = recursive_includes(Requirement, f, includes, ignores)
deps ||= recursive_includes(Dependency, d, includes, ignores)
reqs = recursive_includes(Requirement, d, includes, ignores)
else
deps ||= reject_ignores(f.deps, ignores, includes)
reqs = reject_ignores(f.requirements, ignores, includes)
deps ||= reject_ignores(d.deps, ignores, includes)
reqs = reject_ignores(d.requirements, ignores, includes)
end
deps + reqs.to_a
end
def deps_for_formulae(formulae, recursive = false, &block)
formulae.map { |f| deps_for_formula(f, recursive) }.reduce(&block)
def deps_for_dependents(dependents, recursive = false, &block)
dependents.map { |d| deps_for_dependent(d, recursive) }.reduce(&block)
end
def puts_deps(formulae, recursive = false)
formulae.each do |f|
deps = deps_for_formula(f, recursive)
deps = condense_requirements(deps)
def puts_deps(dependents, recursive = false)
dependents.each do |d|
deps = deps_for_dependent(d, recursive)
condense_requirements(deps)
deps.sort_by!(&:name)
deps.map!(&method(:dep_display_name))
puts "#{f.full_name}: #{deps.join(" ")}"
puts "#{d.full_name}: #{deps.join(" ")}"
end
end
def puts_deps_tree(formulae, recursive = false)
formulae.each do |f|
puts f.full_name
def puts_deps_tree(dependents, recursive = false)
dependents.each do |d|
puts d.full_name
@dep_stack = []
recursive_deps_tree(f, "", recursive)
recursive_deps_tree(d, "", recursive)
puts
end
end

View File

@ -84,7 +84,7 @@ module DependenciesHelpers
[includes, ignores]
end
def recursive_includes(klass, formula, includes, ignores)
def recursive_includes(klass, root_dependent, includes, ignores)
type = if klass == Dependency
:dependencies
elsif klass == Requirement
@ -93,7 +93,7 @@ module DependenciesHelpers
raise ArgumentError, "Invalid class argument: #{klass}"
end
formula.send("recursive_#{type}") do |dependent, dep|
root_dependent.send("recursive_#{type}") do |dependent, dep|
if dep.recommended?
klass.prune if ignores.include?("recommended?") || dependent.build.without?(dep)
elsif dep.optional?

View File

@ -135,7 +135,11 @@ class Requirement
klass = self.class.name || self.class.to_s
klass.sub!(/(Dependency|Requirement)$/, "")
klass.sub!(/^(\w+::)*/, "")
klass.downcase
return klass.downcase if klass.present?
return @cask if @cask.present?
""
end
def which(cmd)

View File

@ -0,0 +1,63 @@
# frozen_string_literal: true
require "cask/cask_loader"
require "cask_dependent"
describe CaskDependent, :needs_macos do
subject(:dependent) { described_class.new test_cask }
let :test_cask do
Cask::CaskLoader.load(+<<-RUBY)
cask "testing" do
depends_on formula: "baz"
depends_on cask: "foo-cask"
depends_on macos: ">= :mojave"
depends_on x11: true
end
RUBY
end
describe "#deps" do
it "is the formula dependencies of the cask" do
expect(dependent.deps.map(&:name))
.to eq %w[baz]
end
end
describe "#requirements" do
it "is the requirements of the cask" do
expect(dependent.requirements.map(&:name))
.to eq %w[foo-cask macos x11]
end
end
describe "#recursive_dependencies", :integration_test do
it "is all the dependencies of the cask" do
setup_test_formula "foo"
setup_test_formula "bar"
setup_test_formula "baz", <<-RUBY
url "https://brew.sh/baz-1.0"
depends_on "bar"
depends_on :osxfuse
RUBY
expect(dependent.recursive_dependencies.map(&:name))
.to eq(%w[foo bar baz])
end
end
describe "#recursive_requirements", :integration_test do
it "is all the dependencies of the cask" do
setup_test_formula "foo"
setup_test_formula "bar"
setup_test_formula "baz", <<-RUBY
url "https://brew.sh/baz-1.0"
depends_on "bar"
depends_on :osxfuse
RUBY
expect(dependent.recursive_requirements.map(&:name))
.to eq(%w[foo-cask macos x11 osxfuse])
end
end
end