Skip to content

Instantly share code, notes, and snippets.

@yujinakayama
Created January 9, 2015 04:45
Show Gist options
  • Save yujinakayama/294fd2e5e56161c171fa to your computer and use it in GitHub Desktop.
Save yujinakayama/294fd2e5e56161c171fa to your computer and use it in GitHub Desktop.
Automatic Gemfile version specifier
# Run `ruby gemfile_version_specifier.rb` in project root directory.
require 'astrolabe/builder'
require 'parser/current'
require 'bundler'
source_buffer = Parser::Source::Buffer.new('Gemfile')
source_buffer.read
builder = Astrolabe::Builder.new
parser = Parser::CurrentRuby.new(builder)
root_node = parser.parse(source_buffer)
rewriter = Parser::Source::Rewriter.new(source_buffer)
gem_nodes_without_version_specification = root_node.each_node(:send).select do |send_node|
_receiver, message, gem_name_node, version_node, = *send_node
next false unless message == :gem
next false unless gem_name_node.str_type?
version_node.nil?
end
gem_specs = Bundler::LockfileParser.new(File.read('Gemfile.lock')).specs
gem_nodes_without_version_specification.each do |send_node|
_receiver, _message, gem_name_node, = *send_node
gem_name, = *gem_name_node
gem_spec = gem_specs.find { |spec| spec.name == gem_name }
version_specification = '~> ' + gem_spec.version.to_s.split('.')[0, 2].join('.')
rewriter.insert_after(gem_name_node.loc.expression, ", '#{version_specification}'")
end
rewrittern_source = rewriter.process
File.write('Gemfile', rewrittern_source)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment