#!/usr/bin/env ruby # # Annotate your "bundle outdated" with GitHub compare URLs # require 'open-uri' require 'json' def rubygems_gem_info(gem_name) JSON.parse(`curl -s https://rubygems.org/api/v1/gems/#{gem_name}.json`) end def github_repo_tags(repo) JSON.parse(`curl -s https://api.github.com/repos/#{repo}/tags`) end def rubygems_github_repo(gem_name) if gem_info = rubygems_gem_info(gem_name) %w(source_code_uri project_uri homepage_uri).each do |key| if repo_name = gem_info[key].to_s[%r{//github\.com/([^/]+/[^/]+)}, 1] return repo_name end end end nil end def github_compare_url(gem_name, first_version, second_version) if github_repo = rubygems_github_repo(gem_name) tags = github_repo_tags(github_repo) return unless tags.is_a?(Array) tags = tags.sort_by { |tag| tag['name'].length } first_tag = tags.detect { |tag| tag['name'].index(first_version) } second_tag = tags.detect { |tag| tag['name'].index(second_version) } if first_tag && second_tag "https://github.com/#{github_repo}/compare/#{first_tag['name']}...#{second_tag['name']}" end end end IO.popen('bundle outdated', 'r') do |io| io.each_line do |line| line = line.chomp if m = line.match(/^\s+\* (\S+) \((\S+) > (\S+)\)/) if url = github_compare_url(m[1], m[3], m[2]) puts "#{line} — #{url}" else puts line end else puts line end end end