diff options
author | Kevin Moore <kevin@thinkpixellab.com> | 2010-05-13 01:31:24 -0700 |
---|---|---|
committer | Kevin Moore <kevin@thinkpixellab.com> | 2010-05-24 00:16:38 -0500 |
commit | f4148898f614032dbadfbd3b0aa9cbd1a757a489 (patch) | |
tree | 3f4846294136e81466d70a3bf2d046a213019e49 /lib/bundler/graph.rb | |
parent | 7ef704d19604f1b60b482badc3a4fb6ef2e32488 (diff) | |
download | bundler-f4148898f614032dbadfbd3b0aa9cbd1a757a489.tar.gz |
'bundle viz'
Removed silly 'puts' in cli
Fake Gem::Requirement.none? [not in Gem < 1.3.7]
Diffstat (limited to 'lib/bundler/graph.rb')
-rw-r--r-- | lib/bundler/graph.rb | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/bundler/graph.rb b/lib/bundler/graph.rb new file mode 100644 index 0000000000..0e8e28a6aa --- /dev/null +++ b/lib/bundler/graph.rb @@ -0,0 +1,130 @@ +module Bundler + class Graph + + USER_OPTIONS = {:style => 'filled, bold', :fillcolor => '#cccccc'}.freeze + + def initialize(env) + @env = env + end + + def nodes + populate + @nodes + end + + def groups + populate + @groups + end + + def viz(output_file, show_gem_versions = false, show_dependency_requirements = false) + require 'graphviz' + populate + + graph_viz = GraphViz::new('Gemfile', {:concentrate => true, :dpi => 65 } ) + graph_viz.edge[:fontname] = graph_viz.node[:fontname] = 'Arial, Helvetica, SansSerif' + graph_viz.edge[:fontsize] = 12 + + viz_nodes = {} + + # populate all of the nodes + nodes.each do |name, node| + label = name.dup + label << "\n#{node.version}" if show_gem_versions + options = { :label => label } + options.merge!( USER_OPTIONS ) if node.is_user + viz_nodes[name] = graph_viz.add_node( name, options ) + end + + group_nodes = {} + @groups.each do |name, dependencies| + group_nodes[name] = graph_viz.add_node(name.to_s, { :shape => 'folder', :fontsize => 16 }.merge(USER_OPTIONS)) + dependencies.each do |dependency| + options = { :weight => 2 } + if show_dependency_requirements && (dependency.requirement.to_s != ">= 0") + options[:label] = dependency.requirement.to_s + end + graph_viz.add_edge( group_nodes[name], viz_nodes[dependency.name], options ) + end + end + + @groups.keys.select { |group| group != :default }.each do |group| + graph_viz.add_edge( group_nodes[group], group_nodes[:default], { :weight => 2 } ) + end + + viz_nodes.each do |name, node| + nodes[name].dependencies.each do |dependency| + options = { } + if nodes[dependency.name].is_user + options[:constraint] = false + end + if show_dependency_requirements && (dependency.requirement.to_s != ">= 0") + options[:label] = dependency.requirement.to_s + end + + graph_viz.add_edge( node, viz_nodes[dependency.name], options ) + end + end + + graph_viz.output( :png => output_file ) + end + + private + + def populate + return if @populated + + # hash of name => GraphNode + @nodes = {} + @groups = {} + + # Populate @nodes + @env.specs.each { |spec| @nodes[spec.name] = GraphNode.new(spec.name, spec.version) } + + # For gems in Gemfile, add details + @env.dependencies.each do |dependency| + node = @nodes[dependency.name] + node.is_user = true + + dependency.groups.each do |group| + if @groups.has_key? group + group = @groups[group] + else + group = @groups[group] = [] + end + group << dependency + end + end + + # walk though a final time and add edges + @env.specs.each do |spec| + + from = @nodes[spec.name] + spec.runtime_dependencies.each do |dependency| + from.dependencies << dependency + end + + end + + @nodes.freeze + @groups.freeze + @populated = true + end + + end + + # Add version info + class GraphNode + + def initialize(name, version) + @name = name + @version = version + @is_user = false + @dependencies = [] + end + + attr_reader :name, :dependencies, :version + attr_accessor :is_user + + end +end |