Skip to content

Instantly share code, notes, and snippets.

@ChrisLundquist
Last active December 27, 2015 03:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChrisLundquist/7259536 to your computer and use it in GitHub Desktop.
Save ChrisLundquist/7259536 to your computer and use it in GitHub Desktop.
Generate pretty reports of Gemfile.lock.diffs
#!/usr/bin/env ruby
# Pretty print how the versions of gems changed between diffs of Gemfile.lock
# usage: ./bundle_differ.rb path/to/Gemfile.lock.diff
#
# Example Output:
# ffi 1.9.0 -> 1.9.3
# guard 2.1.1 -> 2.2.2
# jquery-ui-rails 4.0.5 -> 4.1.0
# listen 2.1.1 -> 2.2.0
# uglifier 2.2.1 -> 2.3.0
# unf 0.1.2 -> 0.1.3
def top_level?(line)
spaces = line =~ /^.(\s+)/
return false unless $1
scope = $1.length
scope == 4
end
# get rid of -+ and leading spaces
def normalize_format(line)
line.gsub(/^(-|\+)\s+/,"")
end
# takes an array like:
# ["ffi (1.9.0)", "guard (2.1.1)", "jquery-ui-rails (4.0.5)", "listen (2.1.1)", "uglifier (2.2.1)", "unf (0.1.2)"]
# and turns it into a hash like { :name => version }
def gem_lines_to_hash(lines)
lines.reduce({}) do |gems,line|
name,version = line.split(" ")
version.gsub!(/[\(\)]/,'')
gems[name] = version
gems
end
end
diff_filename = ARGV.shift
diff = if diff_filename
File.read(diff_filename)
else
STDIN.read
end
old_lines = []
new_lines = []
diff.each_line do |line|
line.chomp!
case line
when /^- / # Starts with a '-'. Was removed
next unless top_level?(line)
old_lines << normalize_format(line)
when /^\+ / # Starts with a '+'. was added.
next unless top_level?(line)
new_lines << normalize_format(line)
else
# Skip the line
end
end
old_gems = gem_lines_to_hash(old_lines)
new_gems = gem_lines_to_hash(new_lines)
# make a list of names we need to print.
# Be sure to account for old gems that were removed and new gems that were just added
gem_names = (old_gems.keys + new_gems.keys).uniq
# Find the longest key so we can right justify the version changes
longest_name = gem_names.max_by { |i| i.length }.length
longest_version = (old_gems.values + new_gems.values).max_by { |i| i.length}.length
gem_names.each do |gem_name|
printf("%-#{longest_name}s %-#{longest_version}s -> %-#{longest_version}s\n", gem_name, old_gems[gem_name], new_gems[gem_name])
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment