Skip to content

Instantly share code, notes, and snippets.

@brentkirby
Created July 16, 2011 05:04
Show Gist options
  • Save brentkirby/1086028 to your computer and use it in GitHub Desktop.
Save brentkirby/1086028 to your computer and use it in GitHub Desktop.
Rake task to update a Gemfile using currently installed gem versions. This way if no version is specified, it will sub in the one installed on system.
require 'bundler'
require 'bundler/dsl'
require 'fileutils'
require 'tempfile'
namespace :gemfile do
task :fresh do
builder = Freshie.new
tempfile = Tempfile.new("#{builder.gemfile}.temp")
File.open( builder.gemfile, "r") do |file|
file.each_line do |line|
if dep = builder.find_match( line )
pad = line.rindex(/gem/)
repl = "gem #{dep.first.inspect}, \"= #{dep.last}\""
line.gsub!(/^\s?[\s+]?(gem.*)$/, repl.rjust( (repl.size + pad), " " ))
end
tempfile.puts line
end
end
FileUtils.mv(tempfile.path, builder.gemfile)
end
end
class Freshie
attr_accessor :dependencies, :gemfile, :system_gems
def initialize( gemfile = nil )
@gemfile ||= File.expand_path("../../../", __FILE__) << "/Gemfile"
@dependencies = []
builder = Bundler::Dsl.new
builder.instance_eval( Bundler.read_file(@gemfile.to_s), @gemfile.to_s, 1 )
deps = builder.instance_variable_get('@dependencies')
deps.each{ |dep| add_dependency(dep) }
@dependencies.uniq!
end
def add_dependency( dep )
return true unless dep.source.nil? && dep.requirement.to_s.match(/\=\ 0$/)
sys_version = system_gems[dep.name]
return true if sys_version.nil?
@dependencies << [ dep.name, sys_version ]
end
def system_gems
@system_gems ||= (`gem list`).split("\n").inject({}) do |hash, spec|
parts = spec.strip.match(/^([\w+|\-?]+\s{1})(.*)$/ix).captures
versions = parts.map!(&:strip).last.split(",").map!(&:strip)
hash.merge!( parts.first => versions.first.gsub(/[^.\d\w]/,'') )
end
end
def find_match( line )
matches = line.match(/(gem)\s?(\S+)/i)
return false if matches.nil?
spec = matches.captures.last.gsub!(/[^\w|\-]/, '')
dep = @dependencies.detect{ |d| spec == d.first }
( dep.nil? ? false : dep )
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment