Skip to content

Instantly share code, notes, and snippets.

@foton
Created July 18, 2017 15:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foton/cf7e91c9d087a9e32de05b50442da82b to your computer and use it in GitHub Desktop.
Save foton/cf7e91c9d087a9e32de05b50442da82b to your computer and use it in GitHub Desktop.
Copy versions from Gemfile.lock to Gemfile (with iternal tests!)
# frozen_string_literal: true
require 'pry'
module Bundler
class GemVersionsFiller
GEM_NAME_REGEXP = /\* ([\w_-]+) /
IGNORE = %w(xxx)
attr_reader :old_gemfile_lines, :new_gemfile_lines
def initialize(gem_file, gemlock_file)
if gem_file.is_a?(String)
@old_gemfile_lines = lines_from(gem_file)
@gemlock_file_lines = lines_from(gemlock_file)
elsif gem_file.is_a?(File)
@old_gemfile_lines = gem_file.readlines
@gemlock_file_lines = gemlock_file.readlines
else
raise "Unsupported input. Use String or File"
end
@new_gemfile_lines = []
end
def append_versions
old_gemfile_lines.each do |line|
if change_line?(line)
# puts("changing line: #{line}")
new_gemfile_lines << append_version_to(line)
else
new_gemfile_lines << line
end
end
return make_result
end
private
def lines_from(multiline_string)
lines = []
multiline_string.each_line { |line| lines << line }
lines
end
def change_line?(line)
return false if line.empty? || line.match(/git:|github:|^#/)
return false if line.match(/,\s?'[\d.]+'/) # gemline with version
!line.match(/^\s*gem/).nil?
end
def append_version_to(line)
m = line.match(/^\s*gem\s+['"](\w[-\w]+(.rb)?)['"]/)
raise "Gem name could not be found on line #{line}" if m.nil?
gemname = m[1]
line.gsub(m[0], m[0] + ", '#{version_from_gemlock(gemname)}'")
end
def unlocked_gems
File.readlines('Gemfile').reject { |line| line =~ /git:|github:|^#/ || IGNORE.detect { |i| line.include?(i) } }
end
def version_from_gemlock(gemname)
v = locked_versions[gemname]
raise "#{gemname} not founded between locked versions! Locked versions: #{locked_versions}" if v.nil?
v
end
def locked_versions
@locked_versions ||= read_locked_versions
end
def read_locked_versions
versions = {}
read_versions = false
intendation = nil
@gemlock_file_lines.each do |line|
read_versions = true if line.match(/^GEM/)
break if line.match(/^PLATFORMS/)
next unless read_versions
if (m = line.match(/(\s*)(\w[-\w]*(.rb)?) \((.*)\)$/)) # gem with version
intendation = m[1] if intendation.nil?
versions[m[2]] = m[4] if m[1] == intendation #just the main ones
end
end
puts("LOCKED_VERSIONS: #{versions}")
versions
end
def make_result
new_gemfile_lines.join('')
end
end
end
def test_it
gemfile = <<-GEMFILE
# frozen_string_literal: true
source 'https://rubygems.org'
ruby '2.4.1'
gem 'cocoon', '1.2.9'
gem 'hash-diff' # I need this badly
gem 'ruby-eet-cz', github: 'ciihla/ruby-eet-cz', require: 'eet_cz'
gem 'activemodel-serializers-xml', git: 'https://github.com/rails/activemodel-serializers-xml', require: false
gem 'gtin.rb'
group :development, :test do
gem 'factory_girl_rails'
gem 'faker', '1.7.2'
gem "letter_opener"
end
GEMFILE
gemfilelock = <<-GEMFILELOCK
GIT
remote: git://github.com/ciihla/ruby-eet-cz.git
revision: 8fc7897e484de52c7058847e7a2741fe66bfde61
specs:
ruby-eet-cz (1.0.0.pre)
activemodel (>= 4.2)
activesupport (>= 4.2)
savon (~> 2.11.0)
GIT
remote: https://github.com/rails/activemodel-serializers-xml
revision: dd9c0acf26aab111ebc647cd8deb99ebc6946531
specs:
activemodel-serializers-xml (1.0.1)
activemodel (> 5.x)
activesupport (> 5.x)
builder (~> 3.1)
GEM
remote: https://rubygems.org/
specs:
actionmailer (5.1.2)
actionpack (= 5.1.2)
actionview (= 5.1.2)
active_model_serializers (0.10.6)
actionpack (>= 4.1, < 6)
activemodel (>= 4.1, < 6)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
cocoon (1.2.10)
database_cleaner (1.6.1)
factory_girl (4.8.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
railties (>= 3.0.0)
faker (1.7.3)
i18n (~> 0.5)
gtin.rb (0.1.2)
hash-diff (0.3.4)
letter_opener (1.4.1)
launchy (~> 2.2)
public_suffix (2.0.5)
puma (3.9.1)
pundit (1.1.0)
activesupport (>= 3.0.0)
rake (12.0.0)
xpath (2.1.0)
nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
database_cleaner
puma
RUBY VERSION
ruby 2.4.1p111
BUNDLED WITH
1.15.1
GEMFILELOCK
result = Bundler::GemVersionsFiller.new(gemfile, gemfilelock).append_versions
expected_result = <<-EXPECTEDGEMFILE
# frozen_string_literal: true
source 'https://rubygems.org'
ruby '2.4.1'
gem 'cocoon', '1.2.9'
gem 'hash-diff', '0.3.4' # I need this badly
gem 'ruby-eet-cz', github: 'ciihla/ruby-eet-cz', require: 'eet_cz'
gem 'activemodel-serializers-xml', git: 'https://github.com/rails/activemodel-serializers-xml', require: false
gem 'gtin.rb', '0.1.2'
group :development, :test do
gem 'factory_girl_rails', '4.8.0'
gem 'faker', '1.7.2'
gem "letter_opener", '1.4.1'
end
EXPECTEDGEMFILE
if result.eql? expected_result
puts 'self test OK'
else
puts "self test FAILED: expected ------\n#{expected_result}-------- \n\ngot -----\n#{result}--------"
end
end
test_it
gemfile = File.open('Gemfile', 'r')
gemfile_lock = File.open('Gemfile.lock', 'r')
new_gemfile_content = Bundler::GemVersionsFiller.new(gemfile, gemfile_lock).append_versions
gemfile.close
gemfile_lock.close
gemfile = File.open('Gemfile_with_versions', 'w')
gemfile.write(new_gemfile_content)
gemfile.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment