Before

1# typed: true # rubocop:todo Sorbet/StrictSigil
2# frozen_string_literal: true
3
4require "abstract_command"
5require "formula"
6require "cask/caskroom"
7require "dependencies_helpers"
8
9module Homebrew
10 module Cmd
11 class Deps < AbstractCommand
12 include DependenciesHelpers
13
14 cmd_args do
15 description <<~EOS
16 Show dependencies for <formula>. When given multiple formula arguments,
17 show the intersection of dependencies for each formula. By default, `deps`
18 shows all required and recommended dependencies.
19
…lines 20–84 unchanged (65 lines)
85 conflicts "--installed", "--eval-all"
86 conflicts "--formula", "--cask"
87 formula_options
88
89 named_args [:formula, :cask]
90 end
91
92 sig { override.void }
93 def run
94 raise UsageError, "`brew deps --os=all` is not supported." if args.os == "all"
95 raise UsageError, "`brew deps --arch=all` is not supported." if args.arch == "all"
96
97 os, arch = args.os_arch_combinations.fetch(0)
98 eval_all = args.eval_all?
99
100 Formulary.enable_factory_cache!
101
102 SimulateSystem.with(os:, arch:) do
103 @use_runtime_dependencies = true
104
105 installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
106 unless installed
107 not_using_runtime_dependencies_reason = if args.installed?
108 "not all the named formulae were installed"
109 else
…lines 110–191 unchanged (82 lines)
192 puts_deps(sorted_dependents_formulae_and_casks, recursive:)
193 return
194 end
195
196 dependents = dependents(args.named.to_formulae_and_casks)
197 check_head_spec(dependents) if args.HEAD?
198
199 all_deps = deps_for_dependents(dependents, recursive:, &(args.union? ? :| : :&))
200 condense_requirements(all_deps)
201 all_deps.map! { |d| dep_display_name(d) }
202 all_deps.uniq!
203 all_deps.sort! unless args.topological?
204 puts all_deps
205 end
206 end
207
208 private
209
210 def sorted_dependents(formulae_or_casks)
211 dependents(formulae_or_casks).sort_by(&:name)
212 end
213
214 def condense_requirements(deps)
215 deps.select! { |dep| dep.is_a?(Dependency) } unless args.include_requirements?
216 deps.select! { |dep| dep.is_a?(Requirement) || dep.installed? } if args.installed?
217 end
218
219 def dep_display_name(dep)
220 str = if dep.is_a? Requirement
221 if args.include_requirements?
222 ":#{dep.display_s}"
223 else
224 # This shouldn't happen, but we'll put something here to help debugging
…lines 225–237 unchanged (13 lines)
238 str = "#{str} [recommended]" if dep.recommended?
239 str = "#{str} [implicit]" if dep.implicit?
240 end
241
242 str
243 end
244
245 def deps_for_dependent(dependency, recursive: false)
246 includes, ignores = args_includes_ignores(args)
247
248 deps = dependency.runtime_dependencies if @use_runtime_dependencies
249
250 if recursive
251 deps ||= recursive_dep_includes(dependency, includes, ignores)
252 reqs = recursive_req_includes(dependency, includes, ignores)
253 else
254 deps ||= select_includes(dependency.deps, ignores, includes)
255 reqs = select_includes(dependency.requirements, ignores, includes)
256 end
257
258 deps + reqs.to_a
259 end
260
261 def deps_for_dependents(dependents, recursive: false, &block)
262 dependents.map { |d| deps_for_dependent(d, recursive:) }.reduce(&block)
263 end
264
265 def check_head_spec(dependents)
266 headless = dependents.select { |d| d.is_a?(Formula) && d.active_spec_sym != :head }
267 .to_sentence two_words_connector: " or ", last_word_connector: " or "
268 opoo "No head spec for #{headless}, using stable spec instead" unless headless.empty?
269 end
270
271 def puts_deps(dependents, recursive: false)
272 check_head_spec(dependents) if args.HEAD?
273 dependents.each do |dependent|
274 deps = deps_for_dependent(dependent, recursive:)
275 condense_requirements(deps)
276 deps.sort_by!(&:name)
277 deps.map! { |d| dep_display_name(d) }
278 puts "#{dependent.full_name}: #{deps.join(" ")}"
279 end
280 end
281
282 def dot_code(dependents, recursive:)
283 dep_graph = {}
284 dependents.each do |d|
285 graph_deps(d, dep_graph:, recursive:)
286 end
287
288 dot_code = dep_graph.map do |d, deps|
289 deps.map do |dep|
290 attributes = []
291 attributes << "style = dotted" if dep.build?
292 attributes << "arrowhead = empty" if dep.test?
…lines 293–297 unchanged (5 lines)
298 comment = " # #{dep.tags.map(&:inspect).join(", ")}" if dep.tags.any?
299 " \"#{d.name}\" -> \"#{dep}\"#{" [#{attributes.join(", ")}]" if attributes.any?}#{comment}"
300 end
301 end.flatten.join("\n")
302 "digraph {\n#{dot_code}\n}"
303 end
304
305 def graph_deps(formula, dep_graph:, recursive:)
306 return if dep_graph.key?(formula)
307
308 dependables = dependables(formula)
309 dep_graph[formula] = dependables
310 return unless recursive
311
312 dependables.each do |dep|
313 next unless dep.is_a? Dependency
314
315 graph_deps(Formulary.factory(dep.name),
316 dep_graph:,
317 recursive: true)
318 end
319 end
320
321 def puts_deps_tree(dependents, recursive: false)
322 check_head_spec(dependents) if args.HEAD?
323 dependents.each do |d|
324 puts d.full_name
325 recursive_deps_tree(d, deps_seen: {}, prefix: "", recursive:)
326 puts
327 end
328 end
329
330 def dependables(formula)
331 includes, ignores = args_includes_ignores(args)
332 deps = @use_runtime_dependencies ? formula.runtime_dependencies : formula.deps
333 deps = select_includes(deps, ignores, includes)
334 reqs = select_includes(formula.requirements, ignores, includes) if args.include_requirements?
335 reqs ||= []
336 reqs + deps
337 end
338
339 def recursive_deps_tree(formula, deps_seen:, prefix:, recursive:)
340 dependables = dependables(formula)
341 max = dependables.length - 1
342 deps_seen[formula.name] = true
343 dependables.each_with_index do |dep, i|
344 tree_lines = if i == max
…lines 345–385 unchanged (41 lines)

After

1# typed: strict
2# frozen_string_literal: true
3
4require "abstract_command"
5require "formula"
6require "cask/caskroom"
7require "dependencies_helpers"
8
9module Homebrew
10 module Cmd
11 class Deps < AbstractCommand
12 include DependenciesHelpers
13
14 class DepsCombineMode < T::Enum
15 enums do
16 # enum values are not mutable, and calling .freeze on them breaks Sorbet
17 # rubocop:disable Style/MutableConstant
18 Intersection = new
19 Union = new
20 # rubocop:enable Style/MutableConstant
21 end
22 end
23
24 cmd_args do
25 description <<~EOS
26 Show dependencies for <formula>. When given multiple formula arguments,
27 show the intersection of dependencies for each formula. By default, `deps`
28 shows all required and recommended dependencies.
…lines 29–95 unchanged (67 lines)
96 conflicts "--formula", "--cask"
97 formula_options
98
99 named_args [:formula, :cask]
100 end
101
102 sig { override.params(argv: T::Array[String]).void }
103 def initialize(argv = ARGV.freeze)
104 super
105 @use_runtime_dependencies = T.let(true, T::Boolean)
106 end
107
108 sig { override.void }
109 def run
110 raise UsageError, "`brew deps --os=all` is not supported." if args.os == "all"
111 raise UsageError, "`brew deps --arch=all` is not supported." if args.arch == "all"
112
113 os, arch = args.os_arch_combinations.fetch(0)
114 eval_all = args.eval_all?
115
116 Formulary.enable_factory_cache!
117
118 SimulateSystem.with(os:, arch:) do
119 installed = args.installed? || dependents(args.named.to_formulae_and_casks).all?(&:any_version_installed?)
120 unless installed
121 not_using_runtime_dependencies_reason = if args.installed?
122 "not all the named formulae were installed"
123 else
124 "`--installed` was not passed"
125 end
…lines 126–206 unchanged (81 lines)
207 return
208 end
209
210 dependents = dependents(args.named.to_formulae_and_casks)
211 check_head_spec(dependents) if args.HEAD?
212
213 deps_combine_mode = args.union? ? DepsCombineMode::Union : DepsCombineMode::Intersection
214 all_deps = deps_for_dependents(dependents, deps_combine_mode:, recursive:)
215 condense_requirements(all_deps)
216 all_deps.map! { dep_display_name(it) }
217 all_deps.uniq!
218 all_deps.sort! unless args.topological?
219 puts all_deps
220 end
221 end
222
223 private
224
225 sig {
226 params(formulae_or_casks: T::Array[T.any(Formula, Keg, Cask::Cask)])
227 .returns(T::Array[T.any(Formula, CaskDependent)])
228 }
229 def sorted_dependents(formulae_or_casks)
230 dependents(formulae_or_casks).sort_by(&:name)
231 end
232
233 sig { params(deps: T::Array[T.any(Dependency, Requirement)]).void }
234 def condense_requirements(deps)
235 deps.select! { |dep| dep.is_a?(Dependency) } unless args.include_requirements?
236 deps.select! { |dep| dep.is_a?(Requirement) || dep.installed? } if args.installed?
237 end
238
239 sig { params(dep: T.any(Requirement, Dependency)).returns(String) }
240 def dep_display_name(dep)
241 str = if dep.is_a? Requirement
242 if args.include_requirements?
243 ":#{dep.display_s}"
244 else
245 # This shouldn't happen, but we'll put something here to help debugging
…lines 246–259 unchanged (14 lines)
260 str = "#{str} [implicit]" if dep.implicit?
261 end
262
263 str
264 end
265
266 sig {
267 params(dependency: T.any(Formula, CaskDependent), recursive: T::Boolean)
268 .returns(T::Array[T.any(Dependency, Requirement)])
269 }
270 def deps_for_dependent(dependency, recursive: false)
271 includes, ignores = args_includes_ignores(args)
272
273 deps = dependency.runtime_dependencies if @use_runtime_dependencies
274
275 if recursive
…lines 276–279 unchanged (4 lines)
280 reqs = select_includes(dependency.requirements, ignores, includes)
281 end
282
283 deps + reqs.to_a
284 end
285
286 sig {
287 params(
288 dependents: T::Array[T.any(Formula, CaskDependent)],
289 deps_combine_mode: DepsCombineMode,
290 recursive: T::Boolean,
291 ).returns(T::Array[T.any(Dependency, Requirement)])
292 }
293 def deps_for_dependents(dependents, deps_combine_mode:, recursive:)
294 symbol = (deps_combine_mode == DepsCombineMode::Intersection) ? :& : :|
295 dependents.map { deps_for_dependent(it, recursive:) }.reduce(symbol)
296 end
297
298 sig { params(dependents: T::Array[T.any(Formula, CaskDependent)]).void }
299 def check_head_spec(dependents)
300 headless = dependents.select { it.is_a?(Formula) && it.active_spec_sym != :head }
301 .to_sentence two_words_connector: " or ", last_word_connector: " or "
302 opoo "No head spec for #{headless}, using stable spec instead" unless headless.empty?
303 end
304
305 sig { params(dependents: T::Array[T.any(Formula, CaskDependent)], recursive: T::Boolean).void }
306 def puts_deps(dependents, recursive: false)
307 check_head_spec(dependents) if args.HEAD?
308 dependents.each do |dependent|
309 deps = deps_for_dependent(dependent, recursive:)
310 condense_requirements(deps)
311 deps.sort_by!(&:name)
312 deps.map! { dep_display_name(it) }
313 puts "#{dependent.full_name}: #{deps.join(" ")}"
314 end
315 end
316
317 sig { params(dependents: T::Array[T.any(Formula, CaskDependent)], recursive: T::Boolean).returns(String) }
318 def dot_code(dependents, recursive:)
319 dep_graph = {}
320 dependents.each { graph_deps(it, dep_graph:, recursive:) }
321
322 dot_code = dep_graph.map do |d, deps|
323 deps.map do |dep|
324 attributes = []
325 attributes << "style = dotted" if dep.build?
326 attributes << "arrowhead = empty" if dep.test?
…lines 327–332 unchanged (6 lines)
333 " \"#{d.name}\" -> \"#{dep}\"#{" [#{attributes.join(", ")}]" if attributes.any?}#{comment}"
334 end
335 end.flatten.join("\n")
336 "digraph {\n#{dot_code}\n}"
337 end
338
339 sig {
340 params(
341 formula: T.any(Formula, CaskDependent),
342 dep_graph: T::Hash[T.any(Formula, CaskDependent), T::Array[T.any(Dependency, Requirement)]],
343 recursive: T::Boolean,
344 ).void
345 }
346 def graph_deps(formula, dep_graph:, recursive:)
347 return if dep_graph.key?(formula)
348
349 dependables = dependables(formula)
350 dep_graph[formula] = dependables
351 return unless recursive
…lines 352–355 unchanged (4 lines)
356 graph_deps(Formulary.factory(dep.name),
357 dep_graph:,
358 recursive: true)
359 end
360 end
361
362 sig { params(dependents: T::Array[T.any(Formula, CaskDependent)], recursive: T::Boolean).void }
363 def puts_deps_tree(dependents, recursive: false)
364 check_head_spec(dependents) if args.HEAD?
365 dependents.each do |d|
366 puts d.full_name
367 recursive_deps_tree(d, deps_seen: {}, prefix: "", recursive:)
368 puts
369 end
370 end
371
372 sig { params(formula: T.any(Formula, CaskDependent)).returns(T::Array[T.any(Dependency, Requirement)]) }
373 def dependables(formula)
374 includes, ignores = args_includes_ignores(args)
375 deps = @use_runtime_dependencies ? formula.runtime_dependencies : formula.deps
376 deps = select_includes(deps, ignores, includes)
377 reqs = select_includes(formula.requirements, ignores, includes) if args.include_requirements?
378 reqs ||= []
379 reqs + deps
380 end
381
382 sig {
383 params(
384 formula: T.any(Formula, CaskDependent),
385 deps_seen: T::Hash[String, T::Boolean],
386 prefix: String, recursive: T::Boolean
387 ).void
388 }
389 def recursive_deps_tree(formula, deps_seen:, prefix:, recursive:)
390 dependables = dependables(formula)
391 max = dependables.length - 1
392 deps_seen[formula.name] = true
393 dependables.each_with_index do |dep, i|
394 tree_lines = if i == max
…lines 395–435 unchanged (41 lines)

Before

program
comment "# typed: true # rubocop:todo Sorbet/StrictSigil"
comment "# frozen_string_literal: true"
call
identifier "require"
argument_list
string
" "\""
string_content "abstract_command"
" "\""
call
identifier "require"
argument_list
string
" "\""
string_content "formula"
" "\""
call
identifier "require"
argument_list
string
" "\""
string_content "cask/caskroom"
" "\""
call
identifier "require"
argument_list
string
" "\""
string_content "dependencies_helpers"
" "\""
module
module "module"
constant "Homebrew"
body_statement
module
module "module"
constant "Cmd"
body_statement
class
class "class"
constant "Deps"
superclass
< "<"
constant "AbstractCommand"
body_statement
call
identifier "include"
argument_list
constant "DependenciesHelpers"
call (+506 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
identifier "override"
. "."
identifier "void"
} "}"
method
def "def"
identifier "run"
body_statement
if_modifier (+21 nodes collapsed)
if_modifier (+21 nodes collapsed)
assignment
left_assignment_list
identifier "os"
, ","
identifier "arch"
= "="
call
call
identifier "args"
. "."
identifier "os_arch_combinations"
. "."
identifier "fetch"
argument_list
( "("
integer "0"
) ")"
assignment
identifier "eval_all"
= "="
call
identifier "args"
. "."
identifier "eval_all?"
call
constant "Formulary"
. "."
identifier "enable_factory_cache!"
call
constant "SimulateSystem"
. "."
identifier "with"
argument_list
( "("
pair
hash_key_symbol "os"
: ":"
, ","
pair
hash_key_symbol "arch"
: ":"
) ")"
do_block
do "do"
body_statement
assignment
instance_variable "@use_runtime_dependencies"
= "="
true "true"
assignment (+30 nodes collapsed)
unless (+30 nodes collapsed)
call (+84 nodes collapsed)
call (+64 nodes collapsed)
if (+30 nodes collapsed)
assignment
identifier "recursive"
= "="
unary
! "!"
call
identifier "args"
. "."
identifier "direct?"
if (+265 nodes collapsed)
if (+91 nodes collapsed)
assignment
identifier "dependents"
= "="
call
identifier "dependents"
argument_list
( "("
call
call
identifier "args"
. "."
identifier "named"
. "."
identifier "to_formulae_and_casks"
) ")"
if_modifier
call
identifier "check_head_spec"
argument_list
( "("
identifier "dependents"
) ")"
if "if"
call
identifier "args"
. "."
constant "HEAD?"
assignment
identifier "all_deps"
= "="
call
identifier "deps_for_dependents"
argument_list
( "("
identifier "dependents"
, ","
pair
hash_key_symbol "recursive"
: ":"
, ","
block_argument
& "&"
parenthesized_statements
( "("
conditional
call
identifier "args"
. "."
identifier "union?"
? "?"
simple_symbol ":|"
: ":"
simple_symbol ":&"
) ")"
) ")"
call
identifier "condense_requirements"
argument_list
( "("
identifier "all_deps"
) ")"
call
identifier "all_deps"
. "."
identifier "map!"
block
{ "{"
block_parameters
| "|"
identifier "d"
| "|"
block_body
call
identifier "dep_display_name"
argument_list
( "("
identifier "d"
) ")"
} "}"
call
identifier "all_deps"
. "."
identifier "uniq!"
unless_modifier
call
identifier "all_deps"
. "."
identifier "sort!"
unless "unless"
call
identifier "args"
. "."
identifier "topological?"
call
identifier "puts"
argument_list
identifier "all_deps"
end "end"
end "end"
identifier "private"
method (+24 nodes collapsed)
method (+67 nodes collapsed)
method (+186 nodes collapsed)
method (+108 nodes collapsed)
method
def "def"
identifier "deps_for_dependents"
method_parameters
( "("
identifier "dependents"
, ","
keyword_parameter
identifier "recursive"
: ":"
false "false"
, ","
block_parameter
& "&"
identifier "block"
) ")"
body_statement
call
call
identifier "dependents"
. "."
identifier "map"
block
{ "{"
block_parameters
| "|"
identifier "d"
| "|"
block_body
call
identifier "deps_for_dependent"
argument_list
( "("
identifier "d"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
} "}"
. "."
identifier "reduce"
argument_list
( "("
block_argument
& "&"
identifier "block"
) ")"
end "end"
method
def "def"
identifier "check_head_spec"
method_parameters
( "("
identifier "dependents"
) ")"
body_statement
assignment
identifier "headless"
= "="
call
call
identifier "dependents"
. "."
identifier "select"
block
{ "{"
block_parameters
| "|"
identifier "d"
| "|"
block_body
binary
call
identifier "d"
. "."
identifier "is_a?"
argument_list
( "("
constant "Formula"
) ")"
&& "&&"
binary
call
identifier "d"
. "."
identifier "active_spec_sym"
!= "!="
simple_symbol ":head"
} "}"
. "."
identifier "to_sentence"
argument_list
pair
hash_key_symbol "two_words_connector"
: ":"
string
" "\""
string_content " or "
" "\""
, ","
pair
hash_key_symbol "last_word_connector"
: ":"
string
" "\""
string_content " or "
" "\""
unless_modifier
call
identifier "opoo"
argument_list
string
" "\""
string_content "No head spec for "
interpolation
#{ "#{"
identifier "headless"
} "}"
string_content ", using stable spec instead"
" "\""
unless "unless"
call
identifier "headless"
. "."
identifier "empty?"
end "end"
method
def "def"
identifier "puts_deps"
method_parameters
( "("
identifier "dependents"
, ","
keyword_parameter
identifier "recursive"
: ":"
false "false"
) ")"
body_statement
if_modifier
call
identifier "check_head_spec"
argument_list
( "("
identifier "dependents"
) ")"
if "if"
call
identifier "args"
. "."
constant "HEAD?"
call
identifier "dependents"
. "."
identifier "each"
do_block
do "do"
block_parameters
| "|"
identifier "dependent"
| "|"
body_statement
assignment
identifier "deps"
= "="
call
identifier "deps_for_dependent"
argument_list
( "("
identifier "dependent"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
call
identifier "condense_requirements"
argument_list
( "("
identifier "deps"
) ")"
call
identifier "deps"
. "."
identifier "sort_by!"
argument_list
( "("
block_argument
& "&"
simple_symbol ":name"
) ")"
call
identifier "deps"
. "."
identifier "map!"
block
{ "{"
block_parameters
| "|"
identifier "d"
| "|"
block_body
call
identifier "dep_display_name"
argument_list
( "("
identifier "d"
) ")"
} "}"
call (+28 nodes collapsed)
end "end"
end "end"
method
def "def"
identifier "dot_code"
method_parameters
( "("
identifier "dependents"
, ","
keyword_parameter
identifier "recursive"
: ":"
) ")"
body_statement
assignment
identifier "dep_graph"
= "="
hash
{ "{"
} "}"
call
identifier "dependents"
. "."
identifier "each"
do_block
do "do"
block_parameters
| "|"
identifier "d"
| "|"
body_statement
call
identifier "graph_deps"
argument_list
( "("
identifier "d"
, ","
pair
hash_key_symbol "dep_graph"
: ":"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
end "end"
assignment (+197 nodes collapsed)
string
" "\""
string_content "digraph {"
escape_sequence "\\n"
interpolation
#{ "#{"
identifier "dot_code"
} "}"
escape_sequence "\\n"
string_content "}"
" "\""
end "end"
method (+98 nodes collapsed)
method (+70 nodes collapsed)
method (+81 nodes collapsed)
method (+283 nodes collapsed)
end "end"
end "end"
end "end"

After

program
comment "# typed: strict"
comment "# frozen_string_literal: true"
call
identifier "require"
argument_list
string
" "\""
string_content "abstract_command"
" "\""
call
identifier "require"
argument_list
string
" "\""
string_content "formula"
" "\""
call
identifier "require"
argument_list
string
" "\""
string_content "cask/caskroom"
" "\""
call
identifier "require"
argument_list
string
" "\""
string_content "dependencies_helpers"
" "\""
module
module "module"
constant "Homebrew"
body_statement
module
module "module"
constant "Cmd"
body_statement
class
class "class"
constant "Deps"
superclass
< "<"
constant "AbstractCommand"
body_statement
call
identifier "include"
argument_list
constant "DependenciesHelpers"
class
class "class"
constant "DepsCombineMode"
superclass
< "<"
scope_resolution
constant "T"
:: "::"
constant "Enum"
body_statement
call
identifier "enums"
do_block
do "do"
comment "# enum values are not mutable, and calling .freeze on them b"...
comment "# rubocop:disable Style/MutableConstant"
body_statement
assignment
constant "Intersection"
= "="
identifier "new"
assignment
constant "Union"
= "="
identifier "new"
comment "# rubocop:enable Style/MutableConstant"
end "end"
end "end"
call (+506 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "override"
. "."
identifier "params"
argument_list
( "("
pair
hash_key_symbol "argv"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
constant "String"
] "]"
) ")"
. "."
identifier "void"
} "}"
method
def "def"
identifier "initialize"
method_parameters
( "("
optional_parameter
identifier "argv"
= "="
call
constant "ARGV"
. "."
identifier "freeze"
) ")"
body_statement
super "super"
assignment
instance_variable "@use_runtime_dependencies"
= "="
call
constant "T"
. "."
identifier "let"
argument_list
( "("
true "true"
, ","
scope_resolution
constant "T"
:: "::"
constant "Boolean"
) ")"
end "end"
call
identifier "sig"
block
{ "{"
block_body
call
identifier "override"
. "."
identifier "void"
} "}"
method
def "def"
identifier "run"
body_statement
if_modifier (+21 nodes collapsed)
if_modifier (+21 nodes collapsed)
assignment
left_assignment_list
identifier "os"
, ","
identifier "arch"
= "="
call
call
identifier "args"
. "."
identifier "os_arch_combinations"
. "."
identifier "fetch"
argument_list
( "("
integer "0"
) ")"
assignment
identifier "eval_all"
= "="
call
identifier "args"
. "."
identifier "eval_all?"
call
constant "Formulary"
. "."
identifier "enable_factory_cache!"
call
constant "SimulateSystem"
. "."
identifier "with"
argument_list
( "("
pair
hash_key_symbol "os"
: ":"
, ","
pair
hash_key_symbol "arch"
: ":"
) ")"
do_block
do "do"
body_statement
assignment (+30 nodes collapsed)
unless (+30 nodes collapsed)
call (+84 nodes collapsed)
call (+64 nodes collapsed)
if (+30 nodes collapsed)
assignment
identifier "recursive"
= "="
unary
! "!"
call
identifier "args"
. "."
identifier "direct?"
if (+265 nodes collapsed)
if (+91 nodes collapsed)
assignment
identifier "dependents"
= "="
call
identifier "dependents"
argument_list
( "("
call
call
identifier "args"
. "."
identifier "named"
. "."
identifier "to_formulae_and_casks"
) ")"
if_modifier
call
identifier "check_head_spec"
argument_list
( "("
identifier "dependents"
) ")"
if "if"
call
identifier "args"
. "."
constant "HEAD?"
assignment
identifier "deps_combine_mode"
= "="
conditional
call
identifier "args"
. "."
identifier "union?"
? "?"
scope_resolution
constant "DepsCombineMode"
:: "::"
constant "Union"
: ":"
scope_resolution
constant "DepsCombineMode"
:: "::"
constant "Intersection"
assignment
identifier "all_deps"
= "="
call
identifier "deps_for_dependents"
argument_list
( "("
identifier "dependents"
, ","
pair
hash_key_symbol "deps_combine_mode"
: ":"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
call
identifier "condense_requirements"
argument_list
( "("
identifier "all_deps"
) ")"
call
identifier "all_deps"
. "."
identifier "map!"
block
{ "{"
block_body
call
identifier "dep_display_name"
argument_list
( "("
identifier "it"
) ")"
} "}"
call
identifier "all_deps"
. "."
identifier "uniq!"
unless_modifier
call
identifier "all_deps"
. "."
identifier "sort!"
unless "unless"
call
identifier "args"
. "."
identifier "topological?"
call
identifier "puts"
argument_list
identifier "all_deps"
end "end"
end "end"
identifier "private"
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "formulae_or_casks"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "Keg"
, ","
scope_resolution
constant "Cask"
:: "::"
constant "Cask"
) ")"
] "]"
) ")"
. "."
identifier "returns"
argument_list
( "("
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
] "]"
) ")"
} "}"
method (+24 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "deps"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Dependency"
, ","
constant "Requirement"
) ")"
] "]"
) ")"
. "."
identifier "void"
} "}"
method (+67 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dep"
: ":"
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Requirement"
, ","
constant "Dependency"
) ")"
) ")"
. "."
identifier "returns"
argument_list
( "("
constant "String"
) ")"
} "}"
method (+186 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dependency"
: ":"
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
) ")"
. "."
identifier "returns"
argument_list
( "("
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Dependency"
, ","
constant "Requirement"
) ")"
] "]"
) ")"
} "}"
method (+108 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dependents"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
] "]"
, ","
pair
hash_key_symbol "deps_combine_mode"
: ":"
constant "DepsCombineMode"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
, ","
) ")"
. "."
identifier "returns"
argument_list
( "("
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Dependency"
, ","
constant "Requirement"
) ")"
] "]"
) ")"
} "}"
method
def "def"
identifier "deps_for_dependents"
method_parameters
( "("
identifier "dependents"
, ","
keyword_parameter
identifier "deps_combine_mode"
: ":"
, ","
keyword_parameter
identifier "recursive"
: ":"
) ")"
body_statement
assignment
identifier "symbol"
= "="
conditional
parenthesized_statements
( "("
binary
identifier "deps_combine_mode"
== "=="
scope_resolution
constant "DepsCombineMode"
:: "::"
constant "Intersection"
) ")"
? "?"
simple_symbol ":&"
: ":"
simple_symbol ":|"
call
call
identifier "dependents"
. "."
identifier "map"
block
{ "{"
block_body
call
identifier "deps_for_dependent"
argument_list
( "("
identifier "it"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
} "}"
. "."
identifier "reduce"
argument_list
( "("
identifier "symbol"
) ")"
end "end"
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dependents"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
] "]"
) ")"
. "."
identifier "void"
} "}"
method
def "def"
identifier "check_head_spec"
method_parameters
( "("
identifier "dependents"
) ")"
body_statement
assignment
identifier "headless"
= "="
call
call
identifier "dependents"
. "."
identifier "select"
block
{ "{"
block_body
binary
call
identifier "it"
. "."
identifier "is_a?"
argument_list
( "("
constant "Formula"
) ")"
&& "&&"
binary
call
identifier "it"
. "."
identifier "active_spec_sym"
!= "!="
simple_symbol ":head"
} "}"
. "."
identifier "to_sentence"
argument_list
pair
hash_key_symbol "two_words_connector"
: ":"
string
" "\""
string_content " or "
" "\""
, ","
pair
hash_key_symbol "last_word_connector"
: ":"
string
" "\""
string_content " or "
" "\""
unless_modifier
call
identifier "opoo"
argument_list
string
" "\""
string_content "No head spec for "
interpolation
#{ "#{"
identifier "headless"
} "}"
string_content ", using stable spec instead"
" "\""
unless "unless"
call
identifier "headless"
. "."
identifier "empty?"
end "end"
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dependents"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
] "]"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
) ")"
. "."
identifier "void"
} "}"
method
def "def"
identifier "puts_deps"
method_parameters
( "("
identifier "dependents"
, ","
keyword_parameter
identifier "recursive"
: ":"
false "false"
) ")"
body_statement
if_modifier
call
identifier "check_head_spec"
argument_list
( "("
identifier "dependents"
) ")"
if "if"
call
identifier "args"
. "."
constant "HEAD?"
call
identifier "dependents"
. "."
identifier "each"
do_block
do "do"
block_parameters
| "|"
identifier "dependent"
| "|"
body_statement
assignment
identifier "deps"
= "="
call
identifier "deps_for_dependent"
argument_list
( "("
identifier "dependent"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
call
identifier "condense_requirements"
argument_list
( "("
identifier "deps"
) ")"
call
identifier "deps"
. "."
identifier "sort_by!"
argument_list
( "("
block_argument
& "&"
simple_symbol ":name"
) ")"
call
identifier "deps"
. "."
identifier "map!"
block
{ "{"
block_body
call
identifier "dep_display_name"
argument_list
( "("
identifier "it"
) ")"
} "}"
call (+28 nodes collapsed)
end "end"
end "end"
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dependents"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
] "]"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
) ")"
. "."
identifier "returns"
argument_list
( "("
constant "String"
) ")"
} "}"
method
def "def"
identifier "dot_code"
method_parameters
( "("
identifier "dependents"
, ","
keyword_parameter
identifier "recursive"
: ":"
) ")"
body_statement
assignment
identifier "dep_graph"
= "="
hash
{ "{"
} "}"
call
identifier "dependents"
. "."
identifier "each"
block
{ "{"
block_body
call
identifier "graph_deps"
argument_list
( "("
identifier "it"
, ","
pair
hash_key_symbol "dep_graph"
: ":"
, ","
pair
hash_key_symbol "recursive"
: ":"
) ")"
} "}"
assignment (+197 nodes collapsed)
string
" "\""
string_content "digraph {"
escape_sequence "\\n"
interpolation
#{ "#{"
identifier "dot_code"
} "}"
escape_sequence "\\n"
string_content "}"
" "\""
end "end"
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "formula"
: ":"
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
, ","
pair
hash_key_symbol "dep_graph"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Hash"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
, ","
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Dependency"
, ","
constant "Requirement"
) ")"
] "]"
] "]"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
, ","
) ")"
. "."
identifier "void"
} "}"
method (+98 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "dependents"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
] "]"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
) ")"
. "."
identifier "void"
} "}"
method (+70 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "formula"
: ":"
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
) ")"
. "."
identifier "returns"
argument_list
( "("
element_reference
scope_resolution
constant "T"
:: "::"
constant "Array"
[ "["
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Dependency"
, ","
constant "Requirement"
) ")"
] "]"
) ")"
} "}"
method (+81 nodes collapsed)
call
identifier "sig"
block
{ "{"
block_body
call
call
identifier "params"
argument_list
( "("
pair
hash_key_symbol "formula"
: ":"
call
constant "T"
. "."
identifier "any"
argument_list
( "("
constant "Formula"
, ","
constant "CaskDependent"
) ")"
, ","
pair
hash_key_symbol "deps_seen"
: ":"
element_reference
scope_resolution
constant "T"
:: "::"
constant "Hash"
[ "["
constant "String"
, ","
scope_resolution
constant "T"
:: "::"
constant "Boolean"
] "]"
, ","
pair
hash_key_symbol "prefix"
: ":"
constant "String"
, ","
pair
hash_key_symbol "recursive"
: ":"
scope_resolution
constant "T"
:: "::"
constant "Boolean"
) ")"
. "."
identifier "void"
} "}"
method (+283 nodes collapsed)
end "end"
end "end"
end "end"