Skip to content

Instantly share code, notes, and snippets.

@mindreframer
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindreframer/8973276 to your computer and use it in GitHub Desktop.
Save mindreframer/8973276 to your computer and use it in GitHub Desktop.
mini_bundler
#!/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