#!/usr/local/bin/ruby require 'rubygems' require 'rubygems/remote_fetcher' file = "Marshal.#{Gem.marshal_version}.Z" uri = URI.parse "http://gems.rubyforge.org/#{file}" data = Gem::RemoteFetcher.fetcher.fetch_path uri data = Gem.inflate data data = Marshal.load data # name => [date1, date2] names_to_dates = Hash.new { |h,k| h[k] = [] } # name => { date1 => version1 } names_to_dates_to_versions = Hash.new { |h,k| h[k] = {} } # name => { date1 => [dep1, dep2] } names_to_dependencies = Hash.new { |h,k| h[k] = {} } # name => date_used_as_dependency names_to_first_use = {} # name => used_by names_of_first_use = {} # name => days_to_first_use names_to_lag = {} # name => number of uses names_to_counts = Hash.new 0 data.each do |name, spec| name = spec.name version = spec.version.to_s date = spec.date dependencies = spec.dependencies.map do |dep| case dep when Gem::Dependency then dep.name when Array then dep.first else raise dep.inspect end end names_to_dates[name] << date names_to_dates_to_versions[name][date] = version names_to_dependencies[name][date] = dependencies dependencies.each do |dependency| names_to_counts[dependency] += 1 end end $names = names_of_first_use def link name if $names[name] then "#{name}" else name end end puts "" puts "
#{data.length} total gems" names_to_dates.each do |name, dates| dates.sort! do |a, b| b <=> a end dates.each do |release_date| deps = names_to_dependencies[name][release_date] next if deps.empty? deps.each do |dep_name| first_use = names_to_first_use[dep_name] if first_use.nil? or first_use > release_date then names_to_first_use[dep_name] = release_date names_of_first_use[dep_name] = name end end end end deps_used = names_to_first_use.length gem_count = names_to_dates.length percent = (deps_used / gem_count.to_f * 100).to_i puts "
#{deps_used} of #{gem_count} gems used as dependencies (#{percent}%)" longest = names_to_first_use.map { |name,| name.to_s.length }.max names_to_first_use.each do |name, date| first_release = names_to_dates[name].last next if first_release.nil? # wtf gem ">= 0.5" lag = (date.to_i / 86400) - (first_release.to_i / 86400) names_to_lag[name] = lag end total_lag = 0 names_to_lag.each { |name, lag| total_lag += lag > 0 ? lag : 0 } average_lag = (total_lag / names_to_lag.length.to_f).round puts "
average time to first use is #{average_lag} days" max_time_to_use = names_to_lag.values.max max_time_name = names_to_lag.invert[max_time_to_use] puts "
maximum time to first use is #{max_time_to_use} (#{max_time_name})" most_uses = names_to_counts.values.max most_dependend_upon = names_to_counts.invert[most_uses] puts "
most depended upon is #{link most_dependend_upon} with #{most_uses} uses" puts "