Skip to content

Instantly share code, notes, and snippets.

@brand-it
Created October 1, 2018 15:21
Show Gist options
  • Save brand-it/e024b4ab037cda59189b891f9ab35756 to your computer and use it in GitHub Desktop.
Save brand-it/e024b4ab037cda59189b891f9ab35756 to your computer and use it in GitHub Desktop.
I have had it come up some times where I need a isolated gem installer using ruby. Found this is a nice way to handle that problem. Used it in https://github.com/newdark/faker-alfred-workflow
require 'fileutils'
require 'rubygems'
require 'rubygems/gem_runner'
require 'rubygems/exceptions'
require File.expand_path('./logger', __dir__).to_s
ENV['GEM_HOME'] = File.expand_path('gems', __dir__).to_s
FileUtils.mkdir_p(ENV['GEM_HOME'])
ENV['GEM_PATH'] = "#{ENV['GEM_HOME']}:/var/lib/ruby/gems/1.8"
Gem.clear_paths
module GemInstaller
def install(lib)
suppress_output do
return false if `gem list #{lib}`.include?(lib)
Logger.info("running 'install #{lib} --no-ri --no-rdoc'")
Gem::GemRunner.new.run(['install', lib, '--no-ri', '--no-rdoc'])
Logger.info("failed to 'install #{lib} --no-ri --no-rdoc'")
false
end
rescue Gem::SystemExitException
Logger.info("Successfully Installed #{lib}")
true
end
def reinstall(lib)
suppress_output do
return install(lib) unless `gem list #{lib}`.include?(lib)
Logger.info("Uninstalling #{lib}")
Gem::GemRunner.new.run(['uninstall', lib, '-a'])
Logger.info("Failed to uninstall #{lib}")
install(lib)
end
rescue StandardError => exception
Logger.error("Failure #{exception.message}")
end
def suppress_output
original_stdout, original_stderr = $stdout.clone, $stderr.clone
$stderr.reopen File.new('/dev/null', 'w')
$stdout.reopen File.new('/dev/null', 'w')
yield
ensure
$stdout.reopen original_stdout
$stderr.reopen original_stderr
end
end
require 'fileutils'
class Logger
ERROR_LOG_PATH = File.join([File.expand_path('logs', __dir__).to_s, 'error.log'])
INFO_LOG_PATH = File.join([File.expand_path('logs', __dir__).to_s, 'info.log'])
class << self
def create_log_file
return if File.exist?(Logger::ERROR_LOG_PATH) && File.exist?(Logger::INFO_LOG_PATH)
FileUtils.mkdir_p(File.expand_path('logs', __dir__).to_s)
FileUtils.touch(Logger::ERROR_LOG_PATH)
FileUtils.touch(Logger::INFO_LOG_PATH)
end
def log(message, log_path: Logger::INFO_LOG_PATH)
create_log_file
return if message.to_s == ''
File.open(log_path, 'a') do |file|
file.write("#{message}\n")
end
end
def info(message)
log message, log_path: Logger::INFO_LOG_PATH
end
def error(message)
log message, log_path: Logger::ERROR_LOG_PATH
end
end
end
@brand-it
Copy link
Author

brand-it commented Oct 1, 2018

this includes out suppression and a simple logger tool that can pump that output to the relative directory in which the code is running in.

@brand-it
Copy link
Author

brand-it commented Oct 1, 2018

require File.expand_path('./gem_installer', __dir__).to_s
extend GemInstaller
install 'faker'
require 'faker'

add this code to the top of any script you want and it will install the gem if it is not already installed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment