Created
July 18, 2017 15:18
-
-
Save foton/cf7e91c9d087a9e32de05b50442da82b to your computer and use it in GitHub Desktop.
Copy versions from Gemfile.lock to Gemfile (with iternal tests!)
This file contains 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 '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