class Build::Dependency::Visualization

Attributes

alias_attributes[R]
base_attributes[R]
dependency_attributes[R]
private_edge_attributes[R]
provider_attributes[R]
provider_edge_attributes[R]
provision_attributes[R]
selection_attributes[R]

Public Class Methods

new() click to toggle source
# File lib/build/dependency/visualization.rb, line 26
def initialize
        @base_attributes = {
                :shape => 'box',
                :style => 'filled',
                :fillcolor => 'white',
                :fontname => 'Monaco',
        }
        
        @provision_attributes = @base_attributes.dup
        
        @alias_attributes = @base_attributes.merge(
                :fillcolor => 'lightgrey',
        )
        
        @dependency_attributes = @base_attributes.merge(
                :fillcolor => 'orange',
        )
        
        @selection_attributes = {
                :fillcolor => 'lightbrown',
        }
        
        @private_edge_attributes = {
                :arrowhead => 'empty',
                :color => '#0000005f'
        }
        
        @provider_attributes = {
                :fillcolor => 'lightblue',
        }
        
        @provider_edge_attributes = {
                :arrowhead => 'none',
        }
end

Public Instance Methods

generate(chain) click to toggle source
# File lib/build/dependency/visualization.rb, line 74
def generate(chain)
        graph = Graphviz::Graph.new
        graph.attributes[:ratio] = :auto
        
        dependencies = dependencies_by_name(chain.dependencies)
        
        chain.ordered.each do |resolution|
                provider = resolution.provider
                name = provider.name
                
                # Provider is the dependency that provides the dependency referred to by name.
                node = graph.add_node(name.to_s, @base_attributes.dup)
                
                if dependencies.include?(resolution.dependency.name)
                        node.attributes.update(@dependency_attributes)
                elsif chain.selection.include?(provider.name)
                        node.attributes.update(@selection_attributes)
                end
                
                # A provision has dependencies...
                provider.dependencies.each do |dependency|
                        if dependency_node = graph.nodes[dependency.name.to_s]
                                edge = node.connect(dependency_node)
                                
                                if dependency.private?
                                        edge.attributes.update(@private_edge_attributes)
                                end
                        end
                end
                
                # A provision provides other provisions...
                provider.provisions.each do |provision_name, provision|
                        next if name == provision_name
                        
                        provides_node = graph.nodes[provision_name.to_s] || graph.add_node(provision_name.to_s, @provision_attributes)
                        
                        if provision.alias?
                                provides_node.attributes = @alias_attributes
                        end
                        
                        node.attributes.update(@provider_attributes)
                        
                        unless provides_node.connected?(node)
                                edge = provides_node.connect(node)
                                
                                edge.attributes.update(@provider_edge_attributes)
                        end
                end
        end
        
        chain.provisions.each do |provision|
                node = graph.nodes[provision.name.to_s]
                
                node.attributes.update(penwidth: 2.0)
        end
        
        # Put all dependencies at the same level so as to not make the graph too confusingraph.
        done = Set.new
        chain.ordered.each do |resolution|
                provider = resolution.provider
                name = "subgraph-#{provider.name}"
                
                subgraph = graph.nodes[name] || graph.add_subgraph(name, :rank => :same)
                
                provider.dependencies.each do |dependency|
                        next if done.include? dependency
                        
                        done << dependency
                        
                        if dependency_node = graph.nodes[dependency.name.to_s]
                                subgraph.add_node(dependency_node.name)
                        end
                end
        end
        
        return graph
end

Private Instance Methods

dependencies_by_name(dependencies) click to toggle source
# File lib/build/dependency/visualization.rb, line 154
def dependencies_by_name(dependencies)
        dependencies.map{|depends| [depends.name, depends]}.to_h
end