From 592bafe24e2fd26205e9928c25fa3681b6bb6ef6 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Sat, 24 Mar 2018 16:55:16 +0000 Subject: [PATCH] Refactor dependencies usage Reuse more code to avoid errors due to duplication. --- Library/Homebrew/build.rb | 8 +-- Library/Homebrew/cmd/deps.rb | 55 ++----------------- Library/Homebrew/cmd/uses.rb | 54 +++---------------- Library/Homebrew/dependable.rb | 11 ++++ Library/Homebrew/dependencies.rb | 78 +++++++++++++++++++++++++++ Library/Homebrew/formula_installer.rb | 6 +-- 6 files changed, 108 insertions(+), 104 deletions(-) diff --git a/Library/Homebrew/build.rb b/Library/Homebrew/build.rb index d61c3672a1..a2a62ccd77 100644 --- a/Library/Homebrew/build.rb +++ b/Library/Homebrew/build.rb @@ -44,9 +44,9 @@ class Build def expand_reqs formula.recursive_requirements do |dependent, req| build = effective_build_options_for(dependent) - if (req.optional? || req.recommended?) && build.without?(req) + if req.prune_from_option?(build) Requirement.prune - elsif req.build? && dependent != formula + elsif req.prune_if_build_and_not_dependent?(dependent, formula) Requirement.prune end end @@ -55,9 +55,9 @@ class Build def expand_deps formula.recursive_dependencies do |dependent, dep| build = effective_build_options_for(dependent) - if (dep.optional? || dep.recommended?) && build.without?(dep) + if dep.prune_from_option?(build) Dependency.prune - elsif dep.build? && dependent != formula + elsif dep.prune_if_build_and_not_dependent?(dependent, formula) Dependency.prune elsif dep.build? Dependency.keep_but_prune_recursive_deps diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index 421edd423c..6a7348c792 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -121,59 +121,14 @@ module Homebrew end def deps_for_formula(f, recursive = false) - includes = [] - ignores = [] - if ARGV.include?("--include-build") - includes << "build?" - else - ignores << "build?" - end - if ARGV.include?("--include-test") - includes << "test?" - else - ignores << "test?" - end - if ARGV.include?("--include-optional") - includes << "optional?" - else - ignores << "optional?" - end - ignores << "recommended?" if ARGV.include?("--skip-recommended") + includes, ignores = argv_includes_ignores(ARGV) if recursive - deps = f.recursive_dependencies do |dependent, dep| - if dep.recommended? - Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep) - elsif dep.test? - if includes.include?("test?") - Dependency.keep_but_prune_recursive_deps - else - Dependency.prune - end - elsif dep.optional? - Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep) - elsif dep.build? - Dependency.prune unless includes.include?("build?") - end - end - reqs = f.recursive_requirements do |dependent, req| - if req.recommended? - Requirement.prune if ignores.include?("recommended?") || dependent.build.without?(req) - elsif req.test? - Requirement.prune unless includes.include?("test?") - elsif req.optional? - Requirement.prune if !includes.include?("optional?") && !dependent.build.with?(req) - elsif req.build? - Requirement.prune unless includes.include?("build?") - end - end + deps = recursive_includes(Dependency, f, includes, ignores) + reqs = recursive_includes(Requirement, f, includes, ignores) else - deps = f.deps.reject do |dep| - ignores.any? { |ignore| dep.send(ignore) } && includes.none? { |include| dep.send(include) } - end - reqs = f.requirements.reject do |req| - ignores.any? { |ignore| req.send(ignore) } && includes.none? { |include| req.send(include) } - end + deps = reject_ignores(f.deps, ignores, includes) + reqs = reject_ignores(f.requirements, ignores, includes) end deps + reqs.to_a diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 4693a5b8d5..416f6e9032 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -42,51 +42,14 @@ module Homebrew formulae = ARGV.include?("--installed") ? Formula.installed : Formula recursive = ARGV.flag? "--recursive" - includes = [] - ignores = [] - if ARGV.include? "--include-build" - includes << "build?" - else - ignores << "build?" - end - if ARGV.include? "--include-test" - includes << "test?" - else - ignores << "test?" - end - if ARGV.include? "--include-optional" - includes << "optional?" - else - ignores << "optional?" - end - ignores << "recommended?" if ARGV.include? "--skip-recommended" + + includes, ignores = argv_includes_ignores(ARGV) uses = formulae.select do |f| used_formulae.all? do |ff| begin if recursive - deps = f.recursive_dependencies do |dependent, dep| - if dep.recommended? - Dependency.prune if ignores.include?("recommended?") || dependent.build.without?(dep) - elsif dep.test? - if includes.include?("test?") - Dependency.keep_but_prune_recursive_deps - else - Dependency.prune - end - elsif dep.optional? - Dependency.prune if !includes.include?("optional?") && !dependent.build.with?(dep) - elsif dep.build? - Dependency.prune unless includes.include?("build?") - end - - # If a tap isn't installed, we can't find the dependencies of one - # its formulae, and an exception will be thrown if we try. - if dep.is_a?(TapDependency) && !dep.tap.installed? - Dependency.keep_but_prune_recursive_deps - end - end - + deps = recursive_includes(Dependency, f, includes, ignores) dep_formulae = deps.flat_map do |dep| begin dep.to_formula @@ -103,7 +66,7 @@ module Homebrew if req.recommended? ignores.include?("recommended?") || dependent.build.without?(req) elsif req.test? - Requirement.prune unless includes.include?("test?") + !includes.include?("test?") elsif req.optional? !includes.include?("optional?") && !dependent.build.with?(req) elsif req.build? @@ -113,13 +76,10 @@ module Homebrew reqs = reqs_by_formula.map(&:last) else - deps = f.deps.reject do |dep| - ignores.any? { |ignore| dep.send(ignore) } && includes.none? { |include| dep.send(include) } - end - reqs = f.requirements.reject do |req| - ignores.any? { |ignore| req.send(ignore) } && includes.none? { |include| req.send(include) } - end + deps = reject_ignores(f.deps, ignores, includes) + reqs = reject_ignores(f.requirements, ignores, includes) end + next true if deps.any? do |dep| begin dep.to_formula.full_name == ff.full_name diff --git a/Library/Homebrew/dependable.rb b/Library/Homebrew/dependable.rb index b6196e939c..3639926dbe 100644 --- a/Library/Homebrew/dependable.rb +++ b/Library/Homebrew/dependable.rb @@ -32,4 +32,15 @@ module Dependable def options Options.create(option_tags) end + + def prune_from_option?(build) + return if !optional? && !recommended? + build.without?(self) + end + + def prune_if_build_and_not_dependent?(dependent, formula = nil) + return false unless build? + return dependent.installed? unless formula + dependent != formula + end end diff --git a/Library/Homebrew/dependencies.rb b/Library/Homebrew/dependencies.rb index 0ed0502d81..36348a14d4 100644 --- a/Library/Homebrew/dependencies.rb +++ b/Library/Homebrew/dependencies.rb @@ -52,3 +52,81 @@ class Requirements < DelegateClass(Set) "#<#{self.class.name}: {#{to_a.join(", ")}}>" end end + +module Homebrew + module_function + + def argv_includes_ignores(argv) + includes = [] + ignores = [] + + if argv.include? "--include-build" + includes << "build?" + else + ignores << "build?" + end + + if argv.include? "--include-test" + includes << "test?" + else + ignores << "test?" + end + + if argv.include? "--include-optional" + includes << "optional?" + else + ignores << "optional?" + end + + ignores << "recommended?" if ARGV.include? "--skip-recommended" + + [includes, ignores] + end + + def recursive_includes(klass, formula, includes, ignores) + type = if klass == Dependency + :dependencies + elsif klass == Requirement + :requirements + else + raise ArgumentError, "Invalid class argument: #{klass}" + end + + formula.send("recursive_#{type}") do |dependent, dep| + if dep.recommended? + if ignores.include?("recommended?") || dependent.build.without?(dep) + klass.prune + end + elsif dep.test? + if includes.include?("test?") + if type == :dependencies + Dependency.keep_but_prune_recursive_deps + end + else + klass.prune + end + elsif dep.optional? + if !includes.include?("optional?") && !dependent.build.with?(dep) + klass.prune + end + elsif dep.build? + klass.prune unless includes.include?("build?") + end + + # If a tap isn't installed, we can't find the dependencies of one + # its formulae, and an exception will be thrown if we try. + if type == :dependencies && + dep.is_a?(TapDependency) && + !dep.tap.installed? + Dependency.keep_but_prune_recursive_deps + end + end + end + + def reject_ignores(dependables, ignores, includes) + dependables.reject do |dep| + next false unless ignores.any? { |ignore| dep.send(ignore) } + includes.none? { |include| dep.send(include) } + end + end +end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index b0dc0eb232..8c7efc978b 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -439,7 +439,7 @@ class FormulaInstaller build = effective_build_options_for(dependent) install_bottle_for_dependent = install_bottle_for?(dependent, build) - if (req.optional? || req.recommended?) && build.without?(req) + if req.prune_from_option?(build) Requirement.prune elsif req.satisfied? Requirement.prune @@ -469,13 +469,13 @@ class FormulaInstaller inherited_options.fetch(dependent.name, []), ) - if (dep.optional? || dep.recommended?) && build.without?(dep) + if dep.prune_from_option?(build) Dependency.prune elsif include_test? && dep.test? && !dep.installed? Dependency.keep_but_prune_recursive_deps elsif dep.build? && install_bottle_for?(dependent, build) Dependency.prune - elsif dep.build? && dependent.installed? + elsif dep.prune_if_build_and_not_dependent?(dependent) Dependency.prune elsif dep.satisfied?(inherited_options[dep.name]) Dependency.skip