#!/usr/bin/env ruby require 'yaml' require 'set' Private = Struct.new(:name) if ARGV.first == '--all' ARGV.shift elsif ARGV.first == '--no-private' ARGV.shift YAML::add_domain_type('developer.apple.com,2014', 'private') do |type, val| nil end else YAML::add_domain_type('developer.apple.com,2014', 'private') do |type, val| Private.new(val) end end files = {} ARGV.each do |file| yaml = YAML::load_file(file) files[File.basename(file)] = yaml if yaml end YAML::dump(files) # We cheat here and dump everything into the same bucket. names = {} files.each do |k, v| v['provides'].each do |name| names[name] ||= [] names[name] << k end if v['provides'] v['nominals'].each do |name| names[name] ||= [] names[name] << k end if v['nominals'] v['class-members'].each do |name| names[name] ||= [] names[name] << k end if v['class-members'] end all_deps = {} all_private_deps = {} files.each do |k, v| deps = Set.new() private_deps = Set.new() v['top-level'].each do |name| next unless name if name.is_a? Private private_deps.merge(names[name.name] || []) else deps.merge(names[name] || []) end end if v['top-level'] v['member-access'].each do |name| next unless name if name.is_a? Private private_deps.merge(names[name.name] || []) else deps.merge(names[name] || []) end end if v['member-access'] v['dynamic-lookup'].each do |name| next unless name if name.is_a? Private private_deps.merge(names[name.name] || []) else deps.merge(names[name] || []) end end if v['dynamic-lookup'] deps.delete(k) private_deps.delete(k) private_deps.subtract(deps) all_deps[k] = deps.to_a.sort all_private_deps[k] = private_deps.to_a.sort end # Graphviz output! puts 'digraph dependencies {' all_deps.each do |k, v| v.each do |dep| puts "\t\"#{dep}\" -> \"#{k}\"" end if v.empty? puts "\t\"#{k}\"" end end all_private_deps.each do |k, v| v.each do |dep| puts "\t\"#{dep}\" -> \"#{k}\" [style=dotted]" end end puts '}'