Last active
August 29, 2015 13:56
-
-
Save mindreframer/8973276 to your computer and use it in GitHub Desktop.
mini_bundler
This file contains hidden or 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
#!/usr/bin/env ruby | |
#### Usage: | |
## ./mini_bundler -> will install gems | |
## ./mini_bundler cache -> will cache installed gem-file in vendor/cache | |
def execute(cmd) | |
log "CMD: #{cmd}" | |
%x(#{cmd}) | |
end | |
def log(msg) | |
puts "--- #{msg}" | |
end | |
class MiniBundler | |
def gems | |
@gems ||= File.read(gems_file).split("\n").select{|x| x.strip != '' && x[0..0] != '#'} | |
end | |
def gems_with_version | |
gems[0..-1].map do |x| | |
{ | |
:name => x.split.first, | |
:version => x.split.last.gsub( /[\(\)]/ , '') | |
} | |
end | |
end | |
def gems_file | |
File.join(File.dirname(__FILE__), 'gems.txt') | |
end | |
def current_gemlist | |
@current_gemlist ||= %x(gem list).split("\n") | |
end | |
def root_folder | |
File.expand_path(File.join(File.dirname(__FILE__), '..')) | |
end | |
def install | |
gems_with_version.each do |gem_hash| | |
version = gem_hash[:version] | |
name = gem_hash[:name] | |
found_gems = current_gemlist.grep(%r(\b#{name})).first.to_s | |
ensure_gem(name, version, found_gems) | |
end | |
end | |
def ensure_gem(name, version, found_gems) | |
if found_gems.strip == '' | |
log "GEM #{name}: installing #{version}" | |
install_cached_or_not(name, version) | |
elsif found_gems.include?(',') or !found_gems.include?(version) | |
log "GEM #{name}: multiple versions installed!" | |
versions = found_gems.match(/\(.*\)/).to_s.gsub(/[\(\)]/, '').split(',').map{|x| x.strip} | |
(versions - [version]).each do |v| | |
uninstall_gem(name, v) | |
end | |
unless versions.include?(version) | |
install_cached_or_not(name, version) | |
end | |
else | |
log "GEM #{name}: already installed." | |
end | |
end | |
def update_cache | |
log "updating cache..." | |
gems_to_cache = gems_with_version.map do |gem_hash| | |
version = gem_hash[:version] | |
name = gem_hash[:name] | |
files_to_check = rubygems_cache_folders.map{|x| "#{x}/#{name}-#{version}.gem"} | |
files_to_check.select{|x| File.exist?(x)}.first | |
end | |
ensure_clean_vendor_cache | |
gems_to_cache.each do |gem_file| | |
copy_to_vendor(gem_file) | |
end | |
end | |
def rubygems_cache_folders | |
require 'rubygems' | |
rubygems_cache_folders = Gem.path.map{|x| x + "/cache"} | |
end | |
protected | |
def ensure_clean_vendor_cache | |
execute("rm -rf #{root_folder}/vendor/cache") | |
execute("mkdir #{root_folder}/vendor/cache") | |
end | |
def copy_to_vendor(gem_file) | |
execute("cp #{gem_file} #{root_folder}/vendor/cache/") | |
end | |
def install_cached_or_not(name, version) | |
vendored_gem_name = File.join(root_folder, "vendor/cache/#{name}-#{version}.gem") | |
if File.exist?(vendored_gem_name) | |
res = execute "gem install --ignore-dependencies --local --no-ri --no-rdoc #{vendored_gem_name}" | |
raise "could not install gem #{name}-#{version}" if res.include?('ERROR') | |
else | |
res = execute "gem install #{name} -v #{version} --no-ri --no-rdoc" | |
raise "could not install gem #{name}-#{version}" if res.include?('ERROR') | |
end | |
end | |
def uninstall_gem(name, version) | |
log "uninstalling #{name} - #{version}" | |
cmd = "gem uninstall #{name} -v #{version}" | |
require 'pty' | |
require 'expect' | |
PTY.spawn(cmd) do |reader, writer| | |
# cont. in 0.2s if input doesn't match | |
reader.expect(/Remove executables/, 0.2) | |
writer.puts('Y') rescue log("could not write to expect...") | |
end | |
end | |
end | |
mini_bundler = MiniBundler.new | |
action = ARGV[0] | |
case action | |
when /cache/ then | |
mini_bundler.update_cache | |
else | |
mini_bundler.install | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment