| require 'git' | |
| require 'bundler' | |
| require 'json' | |
| require 'pry' | |
| def gem_freshness_map(lockfile) | |
| {}.tap do |gem_freshness| | |
| uris = lockfile.specs.each do |spec| | |
| clazz = spec.source.class | |
| puts "Evaluating #{spec.name}" | |
| if clazz == Bundler::Source::Rubygems | |
| gem_freshness.merge!(rubygem_latest_version_date(spec)) | |
| elsif clazz == Bundler::Source::Git | |
| gem_freshness.merge!(git_gem_latest_version_date(spec)) | |
| else | |
| puts clazz | |
| end | |
| end | |
| end | |
| end | |
| def rubygem_latest_version_date(spec) | |
| gem_name = spec.name | |
| gem_info_file = "/tmp/rubygems_version_info_#{gem_name}.json" | |
| unless File.exist? gem_info_file | |
| gem_json = `curl -q https://rubygems.org/api/v1/versions/#{gem_name}.json > #{gem_info_file}` | |
| end | |
| begin | |
| gem_version_json = JSON.parse(File.read(gem_info_file)) | |
| most_recent_version_date = gem_version_json.map { |version| Time.parse(version['built_at']) }.sort.last | |
| {gem_name => most_recent_version_date} | |
| rescue JSON::ParserError => e | |
| p e.message | |
| {gem_name => Time.now} # can't tell because it's probably an internal gem | |
| end | |
| end | |
| def git_gem_latest_version_date(spec) | |
| gem_name = spec.source.name | |
| {gem_name => date_of_last_commit(spec.source.uri, gem_name)} | |
| end | |
| def date_of_last_commit(uri, name) | |
| gem_copy_directory = "/tmp/checkout_#{name}_#{Time.now.strftime("%Y-%m-%d")}" | |
| return Time.now if name == 'parallel_tests' # 60 sec instead of < 1 sec | |
| if Dir.exist? gem_copy_directory | |
| g = Git.open(gem_copy_directory + "/#{name}") | |
| else | |
| g = Git.clone(uri, name, :path => gem_copy_directory, depth: 1) | |
| end | |
| g.log.first.date | |
| end | |
| def _pretty(freshness_map) | |
| max_display_length = freshness_map.keys.map { |k| k.length }.max | |
| freshness_map.sort_by { |k, v| v }.to_h.map { |k, v| | |
| "#{k}#{' ' * (max_display_length - k.length)}last updated: #{v}" | |
| } | |
| end | |
| lockfile = Bundler::LockfileParser.new(Bundler.read_file("Gemfile.lock")) | |
| freshness_map = gem_freshness_map(lockfile) | |
| count_to_show = ARGV[0] || 5 | |
| puts "These are not how old our gems are; this is how old our gems would be if we updated all of them." | |
| puts "Oldest #{count_to_show}:" | |
| puts _pretty(freshness_map)[0..count_to_show.to_i] | |
| # ruby up_to_date_gemfinder.rb 10 | |
| # These are not how old our gems are; this is how old our gems would be if we updated all of them. | |
| # Oldest 10: | |
| # capistrano-ext last updated: 2008-06-14 06:00:00 UTC | |
| # colored last updated: 2010-02-10 08:00:00 UTC | |
| # vegas last updated: 2010-10-11 07:00:00 UTC | |
| # erubis last updated: 2011-04-01 15:00:00 UTC | |
| # rack-cache last updated: 2012-03-05 00:00:00 UTC | |
| # sql_queries_count last updated: 2012-04-02 00:00:00 UTC | |
| # journey last updated: 2012-06-14 00:00:00 UTC | |
| # pbkdf256 last updated: 2012-09-27 00:00:00 UTC | |
| # fssm last updated: 2013-01-27 00:00:00 UTC | |
| # net-ssh-gateway last updated: 2013-02-06 00:00:00 UTC | |
| # trackless_triggers last updated: 2013-03-05 00:00:00 UTC |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment