From 3cba4cbc19aa3a8782a27928a61050a6518cf1a0 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sat, 19 Aug 2023 15:49:16 -0700 Subject: [PATCH 1/5] dependency_helpers: rework recursive dependency resolution This is a refactor/reworking of the dependency resolution methods in the DependencyHelpers module. These methods are used by both the `brew deps` and `brew uses` commands to get a specific set of dependencies for the user based on multiple criteria. Additive Options: --include-build --include-test --include-optional Subtractive Options: --skip-recommended --missing When a user runs either command the only dependencies that are included by default are recommended and runtime dependencies. This is largely unchanged though we don't include all non-build dependencies as recommended by default anymore. The biggest change is that all installed dependencies are always removed from the list now if the --missing option is passed. This could get skipped before depending on the other options that were passed. Essentially subtractive options now will always be evaluated before additive ones (the docs will need to be updated to make this clear). Beyond that we have no special handling for the optional command anymore. We used to check that the optional dependency was not needed to build the formula but that seems redundant and confusing. Essentially, the #recursive_includes command now behaves much more like the #reject_ignores command (essentially the non-recursive version) which is a good thing for consistency's sake. --- Library/Homebrew/dependencies_helpers.rb | 48 ++++++++---------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/Library/Homebrew/dependencies_helpers.rb b/Library/Homebrew/dependencies_helpers.rb index dd2a3acd2e..390ccf65d9 100644 --- a/Library/Homebrew/dependencies_helpers.rb +++ b/Library/Homebrew/dependencies_helpers.rb @@ -8,29 +8,14 @@ require "cask_dependent" # @api private module DependenciesHelpers def args_includes_ignores(args) - includes = [] + includes = [:recommended?] # included by default + includes << :build? if args.include_build? + includes << :test? if args.include_test? + includes << :optional? if args.include_optional? + ignores = [] - - if args.include_build? - includes << "build?" - else - ignores << "build?" - end - - if args.include_test? - includes << "test?" - else - ignores << "test?" - end - - if args.include_optional? - includes << "optional?" - else - ignores << "optional?" - end - - ignores << "recommended?" if args.skip_recommended? - ignores << "satisfied?" if args.missing? + ignores << :recommended? if args.skip_recommended? + ignores << :satisfied? if args.missing? [includes, ignores] end @@ -41,17 +26,14 @@ module DependenciesHelpers cache_key = "recursive_includes_#{includes}_#{ignores}" klass.expand(root_dependent, cache_key: cache_key) do |dependent, dep| - if dep.recommended? - klass.prune if ignores.include?("recommended?") || dependent.build.without?(dep) - elsif dep.optional? - klass.prune if includes.exclude?("optional?") && !dependent.build.with?(dep) - elsif dep.build? || dep.test? - keep = false - keep ||= dep.test? && includes.include?("test?") && dependent == root_dependent - keep ||= dep.build? && includes.include?("build?") - klass.prune unless keep - elsif dep.satisfied? - klass.prune if ignores.include?("satisfied?") + klass.prune if ignores.any? { |ignore| dep.send(ignore) } + + # NOTE: Untagged dependencies are runtime dependencies and are included by default. + klass.prune if !dep.tags.empty? && includes.none? do |include| + # Ignore indirect test dependencies + next if include == :test? && dependent != root_dependent + + dep.send(include) end # If a tap isn't installed, we can't find the dependencies of one of From e314a43754847697467f8fe48da37c053e961886 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Thu, 24 Aug 2023 21:18:24 -0700 Subject: [PATCH 2/5] dependency_helpers: include required & use public_send - Use .required? instead of .tags.empty? - use .public_send - modify .reject_ignores to be .select_includes - checks ignores first now - Don't use runtime deps with --missing in `brew deps` command --- Library/Homebrew/cmd/deps.rb | 11 ++++++----- Library/Homebrew/cmd/uses.rb | 2 +- Library/Homebrew/dependencies_helpers.rb | 18 ++++++++---------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index bfa63005c6..5ceee33107 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -90,7 +90,8 @@ module Homebrew !args.include_build? && !args.include_test? && !args.include_optional? && - !args.skip_recommended? + !args.skip_recommended? && + !args.missing? if args.tree? || args.graph? dependents = if args.named.present? @@ -197,8 +198,8 @@ module Homebrew deps ||= recursive_includes(Dependency, dependency, includes, ignores) reqs = recursive_includes(Requirement, dependency, includes, ignores) else - deps ||= reject_ignores(dependency.deps, ignores, includes) - reqs = reject_ignores(dependency.requirements, ignores, includes) + deps ||= select_includes(dependency.deps, ignores, includes) + reqs = select_includes(dependency.requirements, ignores, includes) end deps + reqs.to_a @@ -269,8 +270,8 @@ module Homebrew def self.dependables(formula, args:) includes, ignores = args_includes_ignores(args) deps = @use_runtime_dependencies ? formula.runtime_dependencies : formula.deps - deps = reject_ignores(deps, ignores, includes) - reqs = reject_ignores(formula.requirements, ignores, includes) if args.include_requirements? + deps = select_includes(deps, ignores, includes) + reqs = select_includes(formula.requirements, ignores, includes) if args.include_requirements? reqs ||= [] reqs + deps end diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index d10a45614b..e9dfcc277e 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -129,7 +129,7 @@ module Homebrew deps = if recursive recursive_includes(Dependency, d, includes, ignores) else - reject_ignores(d.deps, ignores, includes) + select_includes(d.deps, ignores, includes) end used_formulae.all? do |ff| diff --git a/Library/Homebrew/dependencies_helpers.rb b/Library/Homebrew/dependencies_helpers.rb index 390ccf65d9..64ead61a76 100644 --- a/Library/Homebrew/dependencies_helpers.rb +++ b/Library/Homebrew/dependencies_helpers.rb @@ -8,7 +8,7 @@ require "cask_dependent" # @api private module DependenciesHelpers def args_includes_ignores(args) - includes = [:recommended?] # included by default + includes = [:required?, :recommended?] # included by default includes << :build? if args.include_build? includes << :test? if args.include_test? includes << :optional? if args.include_optional? @@ -26,14 +26,12 @@ module DependenciesHelpers cache_key = "recursive_includes_#{includes}_#{ignores}" klass.expand(root_dependent, cache_key: cache_key) do |dependent, dep| - klass.prune if ignores.any? { |ignore| dep.send(ignore) } - - # NOTE: Untagged dependencies are runtime dependencies and are included by default. - klass.prune if !dep.tags.empty? && includes.none? do |include| + klass.prune if ignores.any? { |ignore| dep.public_send(ignore) } + klass.prune if includes.none? do |include| # Ignore indirect test dependencies next if include == :test? && dependent != root_dependent - dep.send(include) + dep.public_send(include) end # If a tap isn't installed, we can't find the dependencies of one of @@ -42,11 +40,11 @@ module DependenciesHelpers end end - def reject_ignores(dependables, ignores, includes) - dependables.reject do |dep| - next false unless ignores.any? { |ignore| dep.send(ignore) } + def select_includes(dependables, ignores, includes) + dependables.select do |dep| + next false if ignores.any? { |ignore| dep.public_send(ignore) } - includes.none? { |include| dep.send(include) } + includes.any? { |include| dep.public_send(include) } end end From 72152c09c71d68831c86a8ab795c3187d69bc8b6 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sun, 27 Aug 2023 13:50:53 -0700 Subject: [PATCH 3/5] cmd/uses: handle --missing Ignore all dependencies that are already installed before checking if they use the dependency in question. Remove the :satisfied? criteria before checking used dependents. --- Library/Homebrew/cmd/uses.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index e9dfcc277e..0ed8b37f7e 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -120,6 +120,18 @@ module Homebrew deps += args.installed? ? Cask::Caskroom.casks : Cask::Cask.all end + if args.missing? + deps.reject! do |dep| + case dep + when Formula + dep.any_version_installed? + when Cask::Cask + dep.installed? + end + end + ignores.delete(:satisfied?) + end + select_used_dependents(dependents(deps), used_formulae, recursive, includes, ignores) end end From 5c41e85ae9335610cbbf47f1c23b3a20f00f06c8 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Sun, 27 Aug 2023 17:03:02 -0700 Subject: [PATCH 4/5] update cmd/uses and cmd/deps tests These tests were very simple before and now this should result in more code coverage without affecting test performance. The only tricky thing was testing the `--missing` option without actually installing a package using `install_test_formula` because that is very slow (around 10 seconds on my machine). I ended up just writing the tab to a plausible keg directory for each package I wanted to "install". This allows us to test the behavior while also not increasing CI time by ~20 seconds (though it'd probably be faster on CI than my local machine). --- Library/Homebrew/test/cmd/deps_spec.rb | 24 +++++++++++-- Library/Homebrew/test/cmd/uses_spec.rb | 34 +++++++++++++++---- .../spec/shared_context/integration_test.rb | 8 ++--- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/Library/Homebrew/test/cmd/deps_spec.rb b/Library/Homebrew/test/cmd/deps_spec.rb index 308e9d88f1..4676d06587 100644 --- a/Library/Homebrew/test/cmd/deps_spec.rb +++ b/Library/Homebrew/test/cmd/deps_spec.rb @@ -6,16 +6,34 @@ describe "brew deps" do it_behaves_like "parseable arguments" it "outputs all of a Formula's dependencies and their dependencies on separate lines", :integration_test do - setup_test_formula "foo" + # Included in output setup_test_formula "bar" + setup_test_formula "foo" + setup_test_formula "test" + + # Excluded from output setup_test_formula "baz", <<~RUBY url "https://brew.sh/baz-1.0" depends_on "bar" + depends_on "build" => :build + depends_on "test" => :test + depends_on "optional" => :optional + depends_on "recommended_test" => [:recommended, :test] + depends_on "installed" RUBY + setup_test_formula "build" + setup_test_formula "optional" + setup_test_formula "recommended_test" + setup_test_formula "installed" - expect { brew "deps", "baz" } + # Mock `Formula#any_version_installed?` by creating the tab in a plausible keg directory + keg_dir = HOMEBREW_CELLAR/"installed"/"1.0" + keg_dir.mkpath + touch keg_dir/Tab::FILENAME + + expect { brew "deps", "baz", "--include-test", "--missing", "--skip-recommended" } .to be_a_success - .and output("bar\nfoo\n").to_stdout + .and output("bar\nfoo\ntest\n").to_stdout .and not_to_output.to_stderr end end diff --git a/Library/Homebrew/test/cmd/uses_spec.rb b/Library/Homebrew/test/cmd/uses_spec.rb index 10977ba113..eef1cc603a 100644 --- a/Library/Homebrew/test/cmd/uses_spec.rb +++ b/Library/Homebrew/test/cmd/uses_spec.rb @@ -6,15 +6,37 @@ describe "brew uses" do it_behaves_like "parseable arguments" it "prints the Formulae a given Formula is used by", :integration_test do - setup_test_formula "foo" + # Included in output setup_test_formula "bar" - setup_test_formula "baz", <<~RUBY - url "https://brew.sh/baz-1.0" - depends_on "bar" + setup_test_formula "optional", <<~RUBY + url "https://brew.sh/optional-1.0" + depends_on "bar" => :optional RUBY - expect { brew "uses", "--eval-all", "--recursive", "foo" } - .to output(/(bar\nbaz|baz\nbar)/).to_stdout + # Excluded from output + setup_test_formula "foo" + setup_test_formula "test", <<~RUBY + url "https://brew.sh/test-1.0" + depends_on "foo" => :test + RUBY + setup_test_formula "build", <<~RUBY + url "https://brew.sh/build-1.0" + depends_on "foo" => :build + RUBY + setup_test_formula "installed", <<~RUBY + url "https://brew.sh/installed-1.0" + depends_on "foo" + RUBY + + # Mock `Formula#any_version_installed?` by creating the tab in a plausible keg directory + %w[foo installed].each do |formula_name| + keg_dir = HOMEBREW_CELLAR/formula_name/"1.0" + keg_dir.mkpath + touch keg_dir/Tab::FILENAME + end + + expect { brew "uses", "foo", "--eval-all", "--include-optional", "--missing", "--recursive" } + .to output(/^(bar\noptional|optional\nbar)$/).to_stdout .and not_to_output.to_stderr .and be_a_success end diff --git a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb index 1ae7e966bd..bf488562d7 100644 --- a/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb +++ b/Library/Homebrew/test/support/helper/spec/shared_context/integration_test.rb @@ -166,10 +166,6 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin # something here RUBY - when "foo", "gnupg" - content = <<~RUBY - url "https://brew.sh/#{name}-1.0" - RUBY when "bar" content = <<~RUBY url "https://brew.sh/#{name}-1.0" @@ -180,6 +176,10 @@ RSpec.shared_context "integration test" do # rubocop:disable RSpec/ContextWordin url "https://brew.sh/#patchelf-1.0" license "0BSD" RUBY + else + content ||= <<~RUBY + url "https://brew.sh/#{name}-1.0" + RUBY end Formulary.core_path(name).tap do |formula_path| From b2b8f0ea86bc51715e715aabb5b0152ffc515901 Mon Sep 17 00:00:00 2001 From: apainintheneck Date: Mon, 28 Aug 2023 22:14:26 -0700 Subject: [PATCH 5/5] cmd/uses & cmd/deps: update help/man pages - add clarification about precedence of command options - reword some options for readability - clarify the defaults in `brew deps` --- Library/Homebrew/cmd/deps.rb | 5 ++++- Library/Homebrew/cmd/uses.rb | 10 ++++++---- completions/fish/brew.fish | 8 ++++---- completions/zsh/_brew | 8 ++++---- docs/Manpage.md | 15 ++++++++++----- manpages/brew.1 | 16 +++++++++++----- 6 files changed, 39 insertions(+), 23 deletions(-) diff --git a/Library/Homebrew/cmd/deps.rb b/Library/Homebrew/cmd/deps.rb index 5ceee33107..bd14a89c9a 100644 --- a/Library/Homebrew/cmd/deps.rb +++ b/Library/Homebrew/cmd/deps.rb @@ -15,7 +15,10 @@ module Homebrew description <<~EOS Show dependencies for . Additional options specific to may be appended to the command. When given multiple formula arguments, - show the intersection of dependencies for each formula. + show the intersection of dependencies for each formula. By default, `deps` + shows all required and recommended dependencies. + + Note: `--missing` and `--skip-recommended` have precedence over `--include-*`. EOS switch "-n", "--topological", description: "Sort dependencies in topological order." diff --git a/Library/Homebrew/cmd/uses.rb b/Library/Homebrew/cmd/uses.rb index 0ed8b37f7e..dda289d5ba 100644 --- a/Library/Homebrew/cmd/uses.rb +++ b/Library/Homebrew/cmd/uses.rb @@ -22,6 +22,8 @@ module Homebrew of . When given multiple formula arguments, show the intersection of formulae that use . By default, `uses` shows all formulae and casks that specify as a required or recommended dependency for their stable builds. + + Note: `--missing` and `--skip-recommended` have precedence over `--include-*`. EOS switch "--recursive", description: "Resolve more than one level of dependencies." @@ -33,13 +35,13 @@ module Homebrew description: "Evaluate all available formulae and casks, whether installed or not, to show " \ "their dependents." switch "--include-build", - description: "Include all formulae that specify as `:build` type dependency." + description: "Include formulae that specify as a `:build` dependency." switch "--include-test", - description: "Include all formulae that specify as `:test` type dependency." + description: "Include formulae that specify as a `:test` dependency." switch "--include-optional", - description: "Include all formulae that specify as `:optional` type dependency." + description: "Include formulae that specify as an `:optional` dependency." switch "--skip-recommended", - description: "Skip all formulae that specify as `:recommended` type dependency." + description: "Skip all formulae that specify as a `:recommended` dependency." switch "--formula", "--formulae", description: "Include only formulae." switch "--cask", "--casks", diff --git a/completions/fish/brew.fish b/completions/fish/brew.fish index 05d2ce33d4..891069b43c 100644 --- a/completions/fish/brew.fish +++ b/completions/fish/brew.fish @@ -1700,14 +1700,14 @@ __fish_brew_complete_arg 'uses' -l debug -d 'Display any debugging information' __fish_brew_complete_arg 'uses' -l eval-all -d 'Evaluate all available formulae and casks, whether installed or not, to show their dependents' __fish_brew_complete_arg 'uses' -l formula -d 'Include only formulae' __fish_brew_complete_arg 'uses' -l help -d 'Show this message' -__fish_brew_complete_arg 'uses' -l include-build -d 'Include all formulae that specify formula as `:build` type dependency' -__fish_brew_complete_arg 'uses' -l include-optional -d 'Include all formulae that specify formula as `:optional` type dependency' -__fish_brew_complete_arg 'uses' -l include-test -d 'Include all formulae that specify formula as `:test` type dependency' +__fish_brew_complete_arg 'uses' -l include-build -d 'Include formulae that specify formula as a `:build` dependency' +__fish_brew_complete_arg 'uses' -l include-optional -d 'Include formulae that specify formula as an `:optional` dependency' +__fish_brew_complete_arg 'uses' -l include-test -d 'Include formulae that specify formula as a `:test` dependency' __fish_brew_complete_arg 'uses' -l installed -d 'Only list formulae and casks that are currently installed' __fish_brew_complete_arg 'uses' -l missing -d 'Only list formulae and casks that are not currently installed' __fish_brew_complete_arg 'uses' -l quiet -d 'Make some output more quiet' __fish_brew_complete_arg 'uses' -l recursive -d 'Resolve more than one level of dependencies' -__fish_brew_complete_arg 'uses' -l skip-recommended -d 'Skip all formulae that specify formula as `:recommended` type dependency' +__fish_brew_complete_arg 'uses' -l skip-recommended -d 'Skip all formulae that specify formula as a `:recommended` dependency' __fish_brew_complete_arg 'uses' -l verbose -d 'Make some output more verbose' __fish_brew_complete_arg 'uses; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)' diff --git a/completions/zsh/_brew b/completions/zsh/_brew index a085839f6b..27c2049677 100644 --- a/completions/zsh/_brew +++ b/completions/zsh/_brew @@ -2092,14 +2092,14 @@ _brew_uses() { '--debug[Display any debugging information]' \ '--eval-all[Evaluate all available formulae and casks, whether installed or not, to show their dependents]' \ '--help[Show this message]' \ - '--include-build[Include all formulae that specify formula as `:build` type dependency]' \ - '--include-optional[Include all formulae that specify formula as `:optional` type dependency]' \ - '--include-test[Include all formulae that specify formula as `:test` type dependency]' \ + '--include-build[Include formulae that specify formula as a `:build` dependency]' \ + '--include-optional[Include formulae that specify formula as an `:optional` dependency]' \ + '--include-test[Include formulae that specify formula as a `:test` dependency]' \ '(--all --missing)--installed[Only list formulae and casks that are currently installed]' \ '(--installed)--missing[Only list formulae and casks that are not currently installed]' \ '--quiet[Make some output more quiet]' \ '--recursive[Resolve more than one level of dependencies]' \ - '--skip-recommended[Skip all formulae that specify formula as `:recommended` type dependency]' \ + '--skip-recommended[Skip all formulae that specify formula as a `:recommended` dependency]' \ '--verbose[Make some output more verbose]' \ - formula \ '(--cask)--formula[Include only formulae]' \ diff --git a/docs/Manpage.md b/docs/Manpage.md index 2d3f11a6f1..9c2a7dac01 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -139,7 +139,10 @@ a bug report, you will be required to provide this information. Show dependencies for *`formula`*. Additional options specific to *`formula`* may be appended to the command. When given multiple formula arguments, -show the intersection of dependencies for each formula. +show the intersection of dependencies for each formula. By default, `deps` +shows all required and recommended dependencies. + +Note: `--missing` and `--skip-recommended` have precedence over `--include-*`. * `-n`, `--topological`: Sort dependencies in topological order. @@ -819,6 +822,8 @@ of *`formula`*. When given multiple formula arguments, show the intersection of formulae that use *`formula`*. By default, `uses` shows all formulae and casks that specify *`formula`* as a required or recommended dependency for their stable builds. +Note: `--missing` and `--skip-recommended` have precedence over `--include-*`. + * `--recursive`: Resolve more than one level of dependencies. * `--installed`: @@ -828,13 +833,13 @@ specify *`formula`* as a required or recommended dependency for their stable bui * `--eval-all`: Evaluate all available formulae and casks, whether installed or not, to show their dependents. * `--include-build`: - Include all formulae that specify *`formula`* as `:build` type dependency. + Include formulae that specify *`formula`* as a `:build` dependency. * `--include-test`: - Include all formulae that specify *`formula`* as `:test` type dependency. + Include formulae that specify *`formula`* as a `:test` dependency. * `--include-optional`: - Include all formulae that specify *`formula`* as `:optional` type dependency. + Include formulae that specify *`formula`* as an `:optional` dependency. * `--skip-recommended`: - Skip all formulae that specify *`formula`* as `:recommended` type dependency. + Skip all formulae that specify *`formula`* as a `:recommended` dependency. * `--formula`: Include only formulae. * `--cask`: diff --git a/manpages/brew.1 b/manpages/brew.1 index 1c8b2a9092..54ad4559c8 100644 --- a/manpages/brew.1 +++ b/manpages/brew.1 @@ -155,7 +155,10 @@ Control whether Homebrew automatically links external tap shell completion files Show Homebrew and system configuration info useful for debugging\. If you file a bug report, you will be required to provide this information\. . .SS "\fBdeps\fR [\fIoptions\fR] [\fIformula\fR|\fIcask\fR \.\.\.]" -Show dependencies for \fIformula\fR\. Additional options specific to \fIformula\fR may be appended to the command\. When given multiple formula arguments, show the intersection of dependencies for each formula\. +Show dependencies for \fIformula\fR\. Additional options specific to \fIformula\fR may be appended to the command\. When given multiple formula arguments, show the intersection of dependencies for each formula\. By default, \fBdeps\fR shows all required and recommended dependencies\. +. +.P +Note: \fB\-\-missing\fR and \fB\-\-skip\-recommended\fR have precedence over \fB\-\-include\-*\fR\. . .TP \fB\-n\fR, \fB\-\-topological\fR @@ -1149,6 +1152,9 @@ Disable/enable quarantining of downloads (default: enabled)\. .SS "\fBuses\fR [\fIoptions\fR] \fIformula\fR [\.\.\.]" Show formulae and casks that specify \fIformula\fR as a dependency; that is, show dependents of \fIformula\fR\. When given multiple formula arguments, show the intersection of formulae that use \fIformula\fR\. By default, \fBuses\fR shows all formulae and casks that specify \fIformula\fR as a required or recommended dependency for their stable builds\. . +.P +Note: \fB\-\-missing\fR and \fB\-\-skip\-recommended\fR have precedence over \fB\-\-include\-*\fR\. +. .TP \fB\-\-recursive\fR Resolve more than one level of dependencies\. @@ -1167,19 +1173,19 @@ Evaluate all available formulae and casks, whether installed or not, to show the . .TP \fB\-\-include\-build\fR -Include all formulae that specify \fIformula\fR as \fB:build\fR type dependency\. +Include formulae that specify \fIformula\fR as a \fB:build\fR dependency\. . .TP \fB\-\-include\-test\fR -Include all formulae that specify \fIformula\fR as \fB:test\fR type dependency\. +Include formulae that specify \fIformula\fR as a \fB:test\fR dependency\. . .TP \fB\-\-include\-optional\fR -Include all formulae that specify \fIformula\fR as \fB:optional\fR type dependency\. +Include formulae that specify \fIformula\fR as an \fB:optional\fR dependency\. . .TP \fB\-\-skip\-recommended\fR -Skip all formulae that specify \fIformula\fR as \fB:recommended\fR type dependency\. +Skip all formulae that specify \fIformula\fR as a \fB:recommended\fR dependency\. . .TP \fB\-\-formula\fR