Last active
December 28, 2022 18:47
-
-
Save ixti/3680c400850e8fefe52ceeb94dac8b03 to your computer and use it in GitHub Desktop.
Small script that to print CSV that can be used to plan gem upgrades
This file contains hidden or 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
# frozen_string_literal: true | |
require "bundler/inline" | |
require "csv" | |
STDOUT.sync = STDERR.sync = true | |
gemfile do | |
source "https://rubygems.org" | |
gem "http" | |
end | |
lockfile = Bundler.read_file(ARGV[1] || Bundler.default_lockfile) | |
lockfile = Bundler::LockfileParser.new(lockfile) | |
class Infotainment | |
class RubygemsAPI | |
class Version | |
attr_reader :number | |
attr_reader :created_at | |
attr_reader :platform | |
def initialize(data) | |
@number = data.fetch("number") | |
@created_at = data.fetch("created_at").split("T", 2).first | |
@platform = data.fetch("platform") | |
end | |
def ruby? | |
"ruby" == @platform | |
end | |
alias to_s number | |
def ==(other) | |
@number == other.to_s | |
end | |
end | |
BASE_URI = "https://rubygems.org/api/v1" | |
def self.open | |
HTTP.persistent(BASE_URI) { |http| yield new http } | |
end | |
def initialize(http = HTTP) | |
@http = http | |
end | |
def latest(name) | |
get("#{BASE_URI}/versions/#{name}/latest.json").fetch("version") | |
end | |
def versions(name) | |
get("#{BASE_URI}/versions/#{name}.json").map { |data| Version.new data } | |
end | |
private | |
def get(url) | |
5.times do | |
res = @http.get(url).flush | |
return res.parse(:json) if res.status.ok? | |
sleep 1 | |
end | |
raise "Failed to fetch #{url}" | |
end | |
end | |
class Info | |
attr_reader :name | |
def initialize(name, latest, versions) | |
@name = name | |
@latest = latest | |
@versions = versions.select(&:ruby?) | |
end | |
def latest | |
self[@latest] | |
end | |
def [](lookup) | |
@versions.find { |v| v == lookup } | |
end | |
end | |
def self.open | |
RubygemsAPI.open { |api| yield new api } | |
end | |
def initialize(api = RubygemsAPI.new) | |
@info = {} | |
@api = api | |
end | |
def call(name) | |
@info[name] ||= Info.new(name, @api.latest(name), @api.versions(name)) | |
end | |
end | |
CSV do |csv| | |
Infotainment.open do |lookup| | |
csv << ["direct dependency", "gem name", "version", "released at", "latest version", "released at"] | |
lockfile.specs.each do |spec| | |
next unless spec.source.is_a? Bundler::Source::Rubygems | |
info = lookup.call(spec.name) | |
current = info[spec.version.to_s] | |
latest = info.latest | |
csv << [ | |
lockfile.dependencies.key?(spec.name) ? "Y" : "N", | |
spec.name, | |
current.number, | |
current.created_at, | |
latest.number, | |
latest.created_at | |
] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Somewhat similar to
bundle outdated
but prints out data in spreadsheet format and provides info about release date