Skip to content

Commit

Permalink
brew deps: add --include-requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
apjanke committed Aug 11, 2017
1 parent 67b20d9 commit bb85581
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 45 deletions.
134 changes: 100 additions & 34 deletions Library/Homebrew/cmd/deps.rb
Original file line number Diff line number Diff line change
@@ -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 the intersection of dependencies for <formulae>.
#:
Expand All @@ -19,15 +19,22 @@
#: <formulae>. To include the `:build` type dependencies, pass `--include-build`.
#: Similarly, pass `--include-optional` to include `:optional` dependencies.
#: 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
#: 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.
#:
#: 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`):
#: Show dependencies for installed or all available formulae. Every line of
Expand All @@ -37,6 +44,10 @@
#: The <filters> placeholder is any combination of options `--include-build`,
#: `--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

require "formula"
Expand All @@ -52,45 +63,86 @@ def deps
all?: ARGV.include?("--all"),
topo_order?: ARGV.include?("-n"),
union?: ARGV.include?("--union"),
for_each?: ARGV.include?("--for-each"),
)

if mode.installed? && mode.tree?
puts_deps_tree Formula.installed
if mode.tree?
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?
puts_deps Formula
elsif mode.tree?
raise FormulaUnspecifiedError if ARGV.named.empty?
puts_deps_tree ARGV.formulae
elsif ARGV.named.empty?
raise FormulaUnspecifiedError unless mode.installed?
puts_deps Formula.installed
elsif mode.for_each?
puts_deps ARGV.formulae
else
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.map(&method(:dep_display_name)).uniq
all_deps.sort! unless mode.topo_order?
puts all_deps
end
end

def dep_display_name(d)
ARGV.include?("--full-name") ? d.to_formula.full_name : d.name
def condense_requirements(deps)
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

def deps_for_formula(f, recursive = false)
includes = []
ignores = []
if ARGV.include? "--include-build"
if ARGV.include?("--include-build")
includes << "build?"
else
ignores << "build?"
end
if ARGV.include? "--include-optional"
if ARGV.include?("--include-optional")
includes << "optional?"
else
ignores << "optional?"
end
ignores << "recommended?" if ARGV.include? "--skip-recommended"
ignores << "recommended?" if ARGV.include?("--skip-recommended")

if recursive
deps = f.recursive_dependencies do |dependent, dep|
Expand Down Expand Up @@ -120,7 +172,7 @@ def deps_for_formula(f, recursive = false)
end
end

deps + reqs.select(&:default_formula?).map(&:to_dependency)
deps + reqs.to_a
end

def deps_for_formulae(formulae, recursive = false, &block)
Expand All @@ -129,41 +181,55 @@ def deps_for_formulae(formulae, recursive = false, &block)

def puts_deps(formulae)
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(" ")}"
end
end

def puts_deps_tree(formulae)
def puts_deps_tree(formulae, recursive = false)
formulae.each do |f|
puts "#{f.full_name} (required dependencies)"
recursive_deps_tree(f, "")
puts f.full_name
@dep_stack = []
recursive_deps_tree(f, "", recursive)
puts
end
end

def recursive_deps_tree(f, prefix)
reqs = f.requirements.select(&:default_formula?)
deps = f.deps.default
max = reqs.length - 1
reqs.each_with_index do |req, i|
chr = if i == max && deps.empty?
def recursive_deps_tree(f, prefix, recursive)
reqs = f.requirements
deps = f.deps
dependables = reqs + deps
dependables = dependables.reject(&:optional?) unless ARGV.include?("--include-optional")
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
"├──"
end
puts prefix + "#{chr} :#{dep_display_name(req.to_dependency)}"
end
max = deps.length - 1
deps.each_with_index do |dep, i|
chr = if i == max
"└──"
display_s = "#{tree_lines} #{dep_display_name(dep)}"
is_circular = @dep_stack.include?(dep.name)
display_s = "#{display_s} (CIRCULAR DEPENDENCY)" if is_circular
puts "#{prefix}#{display_s}"
next if !recursive || is_circular
prefix_addition = if i == max
" "
else
"├──"
"│ "
end
if dep.is_a?(Requirement) && dep.default_formula?
recursive_deps_tree(Formulary.factory(dep.to_dependency.name), prefix + prefix_addition, true)
end
if dep.is_a? Dependency
recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_addition, true)
end
prefix_ext = (i == max) ? " " : "│ "
puts prefix + "#{chr} #{dep_display_name(dep)}"
recursive_deps_tree(Formulary.factory(dep.name), prefix + prefix_ext)
end
@dep_stack.pop
end
end
10 changes: 8 additions & 2 deletions completions/zsh/_brew
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ _brew_create() {
':url:_urls'
}

# brew deps [--1] [-n] [--union] [--full-name] [--installed] [--include-build] [--include-optional] [--skip-recommended] formulae
# brew deps --tree [filters] (formulae|--installed)
# brew deps [--1] [-n] [--union] [--full-name] [--installed] [--include-build] [--include-optional] [--skip-recommended] [--include-requirements] formulae
# brew deps --tree [--1] [filters] (formulae|--installed)
# brew deps [filters] (--installed|--all)
# The filters placeholder is any combination of options --include-build, --include-optional, and --skip-recommended as documented above.
_brew_deps() {
Expand All @@ -294,6 +294,7 @@ _brew_deps() {
'--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]' \
'-n[show dependencies in topological order]' \
'--union[show the union of dependencies for formulae, instead of the intersection]' \
Expand All @@ -303,6 +304,11 @@ _brew_deps() {
- tree-deps \
'--tree[show dependencies as a tree]' \
'(*)--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-all \
'--include-build[include \:build dependencies]' \
Expand Down
13 changes: 10 additions & 3 deletions docs/Manpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
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 the intersection of dependencies for `formulae`.

Expand All @@ -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`.
Similarly, pass `--include-optional` to include `:optional` dependencies.
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
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.

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`):
Show dependencies for installed or all available formulae. Every line of
Expand Down
2 changes: 1 addition & 1 deletion manpages/brew-cask.1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BREW\-CASK" "1" "July 2017" "Homebrew" "brew-cask"
.TH "BREW\-CASK" "1" "August 2017" "Homebrew" "brew-cask"
.
.SH "NAME"
\fBbrew\-cask\fR \- a friendly binary installer for macOS
Expand Down
16 changes: 11 additions & 5 deletions manpages/brew.1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "BREW" "1" "July 2017" "Homebrew" "brew"
.TH "BREW" "1" "August 2017" "Homebrew" "brew"
.
.SH "NAME"
\fBbrew\fR \- The missing package manager for macOS
Expand Down Expand Up @@ -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\.
.
.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\.
.
.IP
Expand All @@ -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\.
.
.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
\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\.
.
.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\.
.
.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
\fBdeps\fR [\fIfilters\fR] (\fB\-\-installed\fR|\fB\-\-all\fR)
Expand Down

0 comments on commit bb85581

Please sign in to comment.