Merge pull request #2996 from apjanke/non-formula-reqs-in-brew-deps-tree

brew deps: add --include-requirements, plus some fixes
This commit is contained in:
Andrew Janke 2017-08-14 20:19:39 -04:00 committed by GitHub
commit 60d8218abf
4 changed files with 128 additions and 43 deletions

View File

@ -1,4 +1,4 @@
#: * `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] <formulae>: #: * `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] [`--include-requirements`] <formulae>:
#: Show dependencies for <formulae>. When given multiple formula arguments, #: Show dependencies for <formulae>. When given multiple formula arguments,
#: show the intersection of dependencies for <formulae>. #: show the intersection of dependencies for <formulae>.
#: #:
@ -19,15 +19,22 @@
#: <formulae>. To include the `:build` type dependencies, pass `--include-build`. #: <formulae>. To include the `:build` type dependencies, pass `--include-build`.
#: Similarly, pass `--include-optional` to include `:optional` dependencies. #: Similarly, pass `--include-optional` to include `:optional` dependencies.
#: To skip `:recommended` type dependencies, pass `--skip-recommended`. #: To skip `:recommended` type dependencies, pass `--skip-recommended`.
#: To include requirements in addition to dependencies, pass `--include-requirements`.
#: #:
#: * `deps` `--tree` [<filters>] (<formulae>|`--installed`): #: * `deps` `--tree` [`--1`] [<filters>] [`--annotate`] (<formulae>|`--installed`):
#: Show dependencies as a tree. When given multiple formula arguments, output #: Show dependencies as a tree. When given multiple formula arguments, output
#: individual trees for every formula. #: individual trees for every formula.
#: #:
#: If `--1` is passed, only one level of children is displayed.
#:
#: If `--installed` is passed, output a tree for every installed formula. #: If `--installed` is passed, output a tree for every installed formula.
#: #:
#: The <filters> placeholder is any combination of options `--include-build`, #: The <filters> placeholder is any combination of options `--include-build`,
#: `--include-optional`, and `--skip-recommended` as documented above. #: `--include-optional`, `--skip-recommended`, and `--include-requirements` as
#: documented above.
#:
#: If `--annotate` is passed, the build, optional, and recommended dependencies
#: are marked as such in the output.
#: #:
#: * `deps` [<filters>] (`--installed`|`--all`): #: * `deps` [<filters>] (`--installed`|`--all`):
#: Show dependencies for installed or all available formulae. Every line of #: Show dependencies for installed or all available formulae. Every line of
@ -37,6 +44,10 @@
#: The <filters> placeholder is any combination of options `--include-build`, #: The <filters> placeholder is any combination of options `--include-build`,
#: `--include-optional`, and `--skip-recommended` as documented above. #: `--include-optional`, and `--skip-recommended` as documented above.
# The undocumented `--for-each` option will switch into the mode used by `deps --all`,
# but only list dependencies for specified formula, one specified formula per line.
# This is used for debugging the `--installed`/`--all` display mode.
# encoding: UTF-8 # encoding: UTF-8
require "formula" require "formula"
@ -52,20 +63,26 @@ module Homebrew
all?: ARGV.include?("--all"), all?: ARGV.include?("--all"),
topo_order?: ARGV.include?("-n"), topo_order?: ARGV.include?("-n"),
union?: ARGV.include?("--union"), union?: ARGV.include?("--union"),
for_each?: ARGV.include?("--for-each"),
) )
if mode.installed? && mode.tree? if mode.tree?
puts_deps_tree Formula.installed if mode.installed?
puts_deps_tree Formula.installed, !ARGV.one?
else
raise FormulaUnspecifiedError if ARGV.named.empty?
puts_deps_tree ARGV.formulae, !ARGV.one?
end
elsif mode.all? elsif mode.all?
puts_deps Formula puts_deps Formula
elsif mode.tree?
raise FormulaUnspecifiedError if ARGV.named.empty?
puts_deps_tree ARGV.formulae
elsif ARGV.named.empty? elsif ARGV.named.empty?
raise FormulaUnspecifiedError unless mode.installed? raise FormulaUnspecifiedError unless mode.installed?
puts_deps Formula.installed puts_deps Formula.installed
elsif mode.for_each?
puts_deps ARGV.formulae
else else
all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&)) all_deps = deps_for_formulae(ARGV.formulae, !ARGV.one?, &(mode.union? ? :| : :&))
all_deps = condense_requirements(all_deps)
all_deps = all_deps.select(&:installed?) if mode.installed? all_deps = all_deps.select(&:installed?) if mode.installed?
all_deps = all_deps.map(&method(:dep_display_name)).uniq all_deps = all_deps.map(&method(:dep_display_name)).uniq
all_deps.sort! unless mode.topo_order? all_deps.sort! unless mode.topo_order?
@ -73,24 +90,59 @@ module Homebrew
end end
end end
def dep_display_name(d) def condense_requirements(deps)
ARGV.include?("--full-name") ? d.to_formula.full_name : d.name if ARGV.include?("--include-requirements")
deps
else
deps.map do |dep|
if dep.is_a? Dependency
dep
elsif dep.default_formula?
dep.to_dependency
end
end.compact
end
end
def dep_display_name(dep)
str = if dep.is_a? Requirement
if ARGV.include?("--include-requirements")
if dep.default_formula?
":#{dep.display_s} (#{dep_display_name(dep.to_dependency)})"
else
":#{dep.display_s}"
end
elsif dep.default_formula?
dep_display_name(dep.to_dependency)
else
# This shouldn't happen, but we'll put something here to help debugging
"::#{dep.name}"
end
else
ARGV.include?("--full-name") ? dep.to_formula.full_name : dep.name
end
if ARGV.include?("--annotate")
str = "#{str} [build]" if dep.build?
str = "#{str} [optional" if dep.optional?
str = "#{str} [recommended]" if dep.recommended?
end
str
end end
def deps_for_formula(f, recursive = false) def deps_for_formula(f, recursive = false)
includes = [] includes = []
ignores = [] ignores = []
if ARGV.include? "--include-build" if ARGV.include?("--include-build")
includes << "build?" includes << "build?"
else else
ignores << "build?" ignores << "build?"
end end
if ARGV.include? "--include-optional" if ARGV.include?("--include-optional")
includes << "optional?" includes << "optional?"
else else
ignores << "optional?" ignores << "optional?"
end end
ignores << "recommended?" if ARGV.include? "--skip-recommended" ignores << "recommended?" if ARGV.include?("--skip-recommended")
if recursive if recursive
deps = f.recursive_dependencies do |dependent, dep| deps = f.recursive_dependencies do |dependent, dep|
@ -120,7 +172,7 @@ module Homebrew
end end
end end
deps + reqs.select(&:default_formula?).map(&:to_dependency) deps + reqs.to_a
end end
def deps_for_formulae(formulae, recursive = false, &block) def deps_for_formulae(formulae, recursive = false, &block)
@ -129,41 +181,55 @@ module Homebrew
def puts_deps(formulae) def puts_deps(formulae)
formulae.each do |f| formulae.each do |f|
deps = deps_for_formula(f).sort_by(&:name).map(&method(:dep_display_name)) deps = deps_for_formula(f)
deps = condense_requirements(deps)
deps = deps.sort_by(&:name).map(&method(:dep_display_name))
puts "#{f.full_name}: #{deps.join(" ")}" puts "#{f.full_name}: #{deps.join(" ")}"
end end
end end
def puts_deps_tree(formulae) def puts_deps_tree(formulae, recursive = false)
formulae.each do |f| formulae.each do |f|
puts "#{f.full_name} (required dependencies)" puts f.full_name
recursive_deps_tree(f, "") @dep_stack = []
recursive_deps_tree(f, "", recursive)
puts puts
end end
end end
def recursive_deps_tree(f, prefix) def recursive_deps_tree(f, prefix, recursive)
reqs = f.requirements.select(&:default_formula?) reqs = f.requirements
deps = f.deps.default deps = f.deps
max = reqs.length - 1 dependables = reqs + deps
reqs.each_with_index do |req, i| dependables = dependables.reject(&:optional?) unless ARGV.include?("--include-optional")
chr = if i == max && deps.empty? dependables = dependables.reject(&:build?) unless ARGV.include?("--include-build")
dependables = dependables.reject(&:recommended?) if ARGV.include?("--skip-recommended")
max = dependables.length - 1
@dep_stack.push f.name
dependables.each_with_index do |dep, i|
next if !ARGV.include?("--include-requirements") && dep.is_a?(Requirement) && !dep.default_formula?
tree_lines = if i == max
"└──" "└──"
else else
"├──" "├──"
end end
puts prefix + "#{chr} :#{dep_display_name(req.to_dependency)}" display_s = "#{tree_lines} #{dep_display_name(dep)}"
end is_circular = @dep_stack.include?(dep.name)
max = deps.length - 1 display_s = "#{display_s} (CIRCULAR DEPENDENCY)" if is_circular
deps.each_with_index do |dep, i| puts "#{prefix}#{display_s}"
chr = if i == max next if !recursive || is_circular
"└──" prefix_addition = if i == max
" "
else else
"├──" ""
end end
prefix_ext = (i == max) ? " " : "" if dep.is_a?(Requirement) && dep.default_formula?
puts prefix + "#{chr} #{dep_display_name(dep)}" recursive_deps_tree(Formulary.factory(dep.to_dependency.name), prefix + prefix_addition, true)
recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_ext) end
if dep.is_a? Dependency
recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_addition, true)
end end
end end
@dep_stack.pop
end
end end

View File

@ -284,8 +284,8 @@ _brew_create() {
':url:_urls' ':url:_urls'
} }
# brew deps [--1] [-n] [--union] [--full-name] [--installed] [--include-build] [--include-optional] [--skip-recommended] formulae # brew deps [--1] [-n] [--union] [--full-name] [--installed] [--include-build] [--include-optional] [--skip-recommended] [--include-requirements] formulae
# brew deps --tree [filters] (formulae|--installed) # brew deps --tree [--1] [filters] (formulae|--installed)
# brew deps [filters] (--installed|--all) # brew deps [filters] (--installed|--all)
# The filters placeholder is any combination of options --include-build, --include-optional, and --skip-recommended as documented above. # The filters placeholder is any combination of options --include-build, --include-optional, and --skip-recommended as documented above.
_brew_deps() { _brew_deps() {
@ -294,6 +294,7 @@ _brew_deps() {
'--include-build[include \:build dependencies]' \ '--include-build[include \:build dependencies]' \
'--include-optional[include \:optional dependencies]' \ '--include-optional[include \:optional dependencies]' \
'--skip-recommended[skip \:recommended type dependencies]' \ '--skip-recommended[skip \:recommended type dependencies]' \
'--include-requirements[include requirements]' \
'--1[only show dependencies one level down, instead of recursing]' \ '--1[only show dependencies one level down, instead of recursing]' \
'-n[show dependencies in topological order]' \ '-n[show dependencies in topological order]' \
'--union[show the union of dependencies for formulae, instead of the intersection]' \ '--union[show the union of dependencies for formulae, instead of the intersection]' \
@ -303,6 +304,11 @@ _brew_deps() {
- tree-deps \ - tree-deps \
'--tree[show dependencies as a tree]' \ '--tree[show dependencies as a tree]' \
'(*)--installed[show dependencies for all installed formulae]' \ '(*)--installed[show dependencies for all installed formulae]' \
'--include-build[include \:build dependencies]' \
'--include-optional[include \:optional dependencies]' \
'--skip-recommended[skip \:recommended type dependencies]' \
'--include-requirements[include requirements]' \
'--1[only show dependencies one level down, instead of recursing]' \
'(--installed)*:formulae:__brew_formulae' \ '(--installed)*:formulae:__brew_formulae' \
- installed-all \ - installed-all \
'--include-build[include \:build dependencies]' \ '--include-build[include \:build dependencies]' \

View File

@ -77,7 +77,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
a bug report, you will likely be asked for this information if you do not a bug report, you will likely be asked for this information if you do not
provide it. provide it.
* `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] `formulae`: * `deps` [`--1`] [`-n`] [`--union`] [`--full-name`] [`--installed`] [`--include-build`] [`--include-optional`] [`--skip-recommended`] [`--include-requirements`] `formulae`:
Show dependencies for `formulae`. When given multiple formula arguments, Show dependencies for `formulae`. When given multiple formula arguments,
show the intersection of dependencies for `formulae`. show the intersection of dependencies for `formulae`.
@ -98,15 +98,22 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note
`formulae`. To include the `:build` type dependencies, pass `--include-build`. `formulae`. To include the `:build` type dependencies, pass `--include-build`.
Similarly, pass `--include-optional` to include `:optional` dependencies. Similarly, pass `--include-optional` to include `:optional` dependencies.
To skip `:recommended` type dependencies, pass `--skip-recommended`. To skip `:recommended` type dependencies, pass `--skip-recommended`.
To include requirements in addition to dependencies, pass `--include-requirements`.
* `deps` `--tree` [`filters`] (`formulae`|`--installed`): * `deps` `--tree` [`--1`] [`filters`] [`--annotate`] (`formulae`|`--installed`):
Show dependencies as a tree. When given multiple formula arguments, output Show dependencies as a tree. When given multiple formula arguments, output
individual trees for every formula. individual trees for every formula.
If `--1` is passed, only one level of children is displayed.
If `--installed` is passed, output a tree for every installed formula. If `--installed` is passed, output a tree for every installed formula.
The `filters` placeholder is any combination of options `--include-build`, The `filters` placeholder is any combination of options `--include-build`,
`--include-optional`, and `--skip-recommended` as documented above. `--include-optional`, `--skip-recommended`, and `--include-requirements` as
documented above.
If `--annotate` is passed, the build, optional, and recommended dependencies
are marked as such in the output.
* `deps` [`filters`] (`--installed`|`--all`): * `deps` [`filters`] (`--installed`|`--all`):
Show dependencies for installed or all available formulae. Every line of Show dependencies for installed or all available formulae. Every line of

View File

@ -88,7 +88,7 @@ If \fB\-\-quiet\fR is passed, list only the names of commands without the header
Show Homebrew and system configuration useful for debugging\. If you file a bug report, you will likely be asked for this information if you do not provide it\. Show Homebrew and system configuration useful for debugging\. If you file a bug report, you will likely be asked for this information if you do not provide it\.
. .
.TP .TP
\fBdeps\fR [\fB\-\-1\fR] [\fB\-n\fR] [\fB\-\-union\fR] [\fB\-\-full\-name\fR] [\fB\-\-installed\fR] [\fB\-\-include\-build\fR] [\fB\-\-include\-optional\fR] [\fB\-\-skip\-recommended\fR] \fIformulae\fR \fBdeps\fR [\fB\-\-1\fR] [\fB\-n\fR] [\fB\-\-union\fR] [\fB\-\-full\-name\fR] [\fB\-\-installed\fR] [\fB\-\-include\-build\fR] [\fB\-\-include\-optional\fR] [\fB\-\-skip\-recommended\fR] [\fB\-\-include\-requirements\fR] \fIformulae\fR
Show dependencies for \fIformulae\fR\. When given multiple formula arguments, show the intersection of dependencies for \fIformulae\fR\. Show dependencies for \fIformulae\fR\. When given multiple formula arguments, show the intersection of dependencies for \fIformulae\fR\.
. .
.IP .IP
@ -107,17 +107,23 @@ If \fB\-\-full\-name\fR is passed, list dependencies by their full name\.
If \fB\-\-installed\fR is passed, only list those dependencies that are currently installed\. If \fB\-\-installed\fR is passed, only list those dependencies that are currently installed\.
. .
.IP .IP
By default, \fBdeps\fR shows required and recommended dependencies for \fIformulae\fR\. To include the \fB:build\fR type dependencies, pass \fB\-\-include\-build\fR\. Similarly, pass \fB\-\-include\-optional\fR to include \fB:optional\fR dependencies\. To skip \fB:recommended\fR type dependencies, pass \fB\-\-skip\-recommended\fR\. By default, \fBdeps\fR shows required and recommended dependencies for \fIformulae\fR\. To include the \fB:build\fR type dependencies, pass \fB\-\-include\-build\fR\. Similarly, pass \fB\-\-include\-optional\fR to include \fB:optional\fR dependencies\. To skip \fB:recommended\fR type dependencies, pass \fB\-\-skip\-recommended\fR\. To include requirements in addition to dependencies, pass \fB\-\-include\-requirements\fR\.
. .
.TP .TP
\fBdeps\fR \fB\-\-tree\fR [\fIfilters\fR] (\fIformulae\fR|\fB\-\-installed\fR) \fBdeps\fR \fB\-\-tree\fR [\fB\-\-1\fR] [\fIfilters\fR] [\fB\-\-annotate\fR] (\fIformulae\fR|\fB\-\-installed\fR)
Show dependencies as a tree\. When given multiple formula arguments, output individual trees for every formula\. Show dependencies as a tree\. When given multiple formula arguments, output individual trees for every formula\.
. .
.IP .IP
If \fB\-\-1\fR is passed, only one level of children is displayed\.
.
.IP
If \fB\-\-installed\fR is passed, output a tree for every installed formula\. If \fB\-\-installed\fR is passed, output a tree for every installed formula\.
. .
.IP .IP
The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-build\fR, \fB\-\-include\-optional\fR, and \fB\-\-skip\-recommended\fR as documented above\. The \fIfilters\fR placeholder is any combination of options \fB\-\-include\-build\fR, \fB\-\-include\-optional\fR, \fB\-\-skip\-recommended\fR, and \fB\-\-include\-requirements\fR as documented above\.
.
.IP
If \fB\-\-annotate\fR is passed, the build, optional, and recommended dependencies are marked as such in the output\.
. .
.TP .TP
\fBdeps\fR [\fIfilters\fR] (\fB\-\-installed\fR|\fB\-\-all\fR) \fBdeps\fR [\fIfilters\fR] (\fB\-\-installed\fR|\fB\-\-all\fR)