Created
October 27, 2011 09:54
-
-
Save octplane/1319193 to your computer and use it in GitHub Desktop.
List gems, show dependencies, show broken gems. Uses trollop gem.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'rubygems' | |
require 'trollop' | |
require 'pp' | |
opts = Trollop::options do | |
opt :list, "List local installed gems in shell friendly format", :type => :boolean | |
opt :info, "Display Dependency information about gem", :type => :string | |
opt :check, "Check All installed gems and return broken dependencies", :type=> :boolean | |
end | |
class Node | |
include Enumerable | |
attr_reader :name, :missing | |
attr_accessor :is_dependency_of | |
@@nodes ||= [] | |
def Node.build(name, missing=false) | |
match = @@nodes.find {|n| n.name == name} | |
return match || Node.new(name, missing) | |
end | |
def initialize(name, missing=false) | |
@name = name | |
@nodes = [] | |
@is_dependency_of = [] | |
@missing = missing | |
@@nodes << self | |
end | |
def <=>(other) | |
return @name <=> other.name | |
end | |
def add_parent(node) | |
if not @nodes.include?(node) | |
@nodes << node | |
node.is_dependency_of << self | |
end | |
end | |
STEP = 4 | |
def dump(style = :normal, indent_level=0) | |
if style == :normal | |
sout = "" | |
margin = '' | |
0.upto(indent_level/STEP-1) { |p| margin += (p==0 ? ' ' : '|') + ' '*(STEP - 1) } | |
margin += '|' + '-'*(STEP - 2) | |
sout += margin + "gem: #{@name}\n" | |
@nodes.each do |child| | |
sout += child.dump(style, indent_level+STEP) | |
end | |
return sout | |
elsif style == :dot | |
sout = "" | |
if @dumped == true | |
return "" | |
end | |
@nodes.each do |child| | |
sout += ' '*(STEP - 1) +"\"#{@name}\" -> \"#{child.name}\"\n" | |
end | |
is_dependency_of.each do |parent| | |
sout += ' '*(STEP - 1) +"\"#{parent.name}\" -> \"#{@name}\"\n" | |
end | |
# I have been dumped, so mark me | |
@dumped = true | |
@nodes.each do |child| | |
sout += child.dump(style, indent_level+STEP) | |
end | |
return sout | |
elsif style == :missing_only | |
sout = "" | |
@@nodes.each do |node| | |
if node.missing | |
sout += "Missing: #{node.name} (#{node.is_dependency_of.map{|g| g.name}.join(", ")})\n" | |
end | |
end | |
return sout | |
elsif style == :parentless | |
sout = "Gem having no parents\n" | |
@@nodes.select{ |n| n.is_dependency_of.length == 0}.each do |n| | |
sout += "- #{n.name}\n" | |
end | |
return sout | |
end | |
end | |
end | |
def get_gem(name_regex = /.*/, req = Gem::Requirement.default) | |
dep = Gem::Dependency.new name_regex, Gem::Requirement.default | |
specs = Gem.source_index.search dep | |
end | |
def dependency_graph(spec) | |
$stderr.puts "Graphing:"+spec.map{|s| s.name+' '+s.version.to_s}.join("\n") if spec.is_a? Array | |
n = Node.build(spec.name+" "+(spec.version.to_s)) | |
(spec.dependencies rescue []).each do |dependency| | |
next if dependency.type == :development | |
begin | |
ispecs =get_gem(dependency.name, *dependency.requirement) | |
rescue Exception => e | |
$stderr.puts "Exception while trying to get Gem for dependencies of :"+ spec.inspect | |
raise e | |
end | |
ispecs.each do |ispec| | |
dependency = dependency_graph(ispec) | |
n.add_parent(dependency) | |
end | |
if ispecs.length == 0 | |
# The Gem is not available locally. This sucks. | |
dependency = Node.build(dependency.name, true) | |
n.add_parent(dependency) | |
end | |
end | |
return n | |
end | |
def gem_name(spec) | |
"#{spec.name}\t#{spec.version}" | |
end | |
if opts[:list] | |
specs = get_gem() | |
specs.each do |spec| | |
puts gem_name(spec) | |
end | |
elsif opts[:info] | |
m = dependency_graph(get_gem(opts[:info])[0]) | |
puts m.dump(:normal, 3) | |
elsif opts[:check] | |
m = nil | |
get_gem().each do |spec| | |
m = dependency_graph(spec) | |
end | |
# At least one gem | |
if m != nil | |
puts m.dump(:missing_only) | |
end | |
else | |
$stderr.puts "Not doing anything --help for help." | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Information Display.
Show all dependencies of a given gem, in a tree.
All gem version satisfying the gem dependencies are displayed in the tree.
Output sample: