Created
January 30, 2012 14:44
-
-
Save brianhempel/1704773 to your computer and use it in GitHub Desktop.
Pseudo-shell with Rails application.rb and environment.rb already loaded--like spork but no DRB and speeds up rake commands and rails console in addition to tests
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 | |
require 'benchmark' | |
if ARGV[0] | |
ENV['RAILS_ENV'] = %w{development test production staging}.find { |e| e[0] == ARGV[0][0] } || ARGV[0] | |
else | |
ENV['RAILS_ENV'] ='test' | |
end | |
load_time = Benchmark.realtime do | |
print "Loading application.rb..." | |
require File.expand_path('./config/application', Dir.pwd) | |
# we'll use class reloading | |
# thanks to spork for lots of direction here | |
# https://github.com/sporkrb/spork-rails/blob/master/lib/spork/app_framework/rails.rb | |
# https://github.com/sporkrb/spork-rails/blob/master/lib/spork/ext/rails-reloader.rb | |
Rails::Engine.class_eval do | |
def eager_load! | |
railties.all(&:eager_load!) if defined?(railties) | |
# but don't eager load the eager_load_paths | |
end | |
end | |
print "and environment.rb..." | |
require File.expand_path('./config/environment', Dir.pwd) | |
ActiveSupport::Dependencies.mechanism = :load | |
if Rails.env.test? | |
print "and cucumber..." | |
require 'rspec' | |
begin | |
require 'cucumber' # saves 0.4 seconds when running cucumber | |
# this shaves off another 2 seconds | |
# even though most of the loads technically fail | |
ENV['RAILS_ROOT'] = Dir.pwd | |
other_paths = File.read(Dir.pwd + "/features/support/env.rb").scan(/require ['"](.+?)['"]/).flatten | |
other_paths.each do |path| | |
print "and #{path}..." | |
begin | |
load(path + '.rb', true) | |
rescue | |
end | |
end | |
rescue LoadError | |
end | |
end | |
print "and rake..." | |
require 'rake' | |
end | |
puts "took %.2f seconds." % load_time | |
require 'readline' | |
# thanks to http://bogojoker.com/readline/ | |
# and to https://github.com/ruby/ruby/blob/trunk/ext/readline/readline.c | |
AUTOCOMPLETE_COMMANDS = ['rake ', 'cucumber features/', 'rails ', 'rspec spec/'].sort | |
RAKE_COMMANDS = ['db', 'db:migrate', 'db:test:prepare', 'db:rollback', 'routes', 'sunspot:reindex', 'sunspot:solr:start', 'sunspot:solr:start', 'sunspot:solr:stop', 'assets:clean', 'assets:precompile'] | |
Readline.completion_append_character = "" # space doesn't work on OS X :( | |
Readline.completion_proc = Proc.new do |str| | |
command_candidates = AUTOCOMPLETE_COMMANDS.grep(/^#{Regexp.escape(str)}/) | |
file_candidates = Dir[str+'*'].grep(/^#{Regexp.escape(str)}/) | |
file_candidates.map! do |path| | |
# add a space unless a directory | |
File.directory?(path) ? path : path + ' ' | |
end | |
rake_task_candidates = RAKE_COMMANDS.grep(/^#{Regexp.escape(str)}/) | |
command_candidates + file_candidates + rake_task_candidates | |
end | |
history_file_path = ".jumpstart_history-#{Rails.env}" | |
# load old history | |
if File.exists?(history_file_path) | |
Readline::HISTORY.clear | |
File.read(history_file_path).lines.each { |l| Readline::HISTORY << l.chomp } | |
end | |
while line = Readline.readline("\033[1;30m#{Dir.pwd.sub(/.*\//, '')} \033[0;35m#{Rails.env} \033[0;34m$ \033[0m", true) | |
if line.blank? | |
Readline::HISTORY.pop # don't store blank commands in history | |
next | |
end | |
given_command, *arguments = line.split | |
command = (given_command == 'rails') ? './script/rails' : given_command | |
unless given_command == 'eval' | |
command = `which #{command}`.chomp | |
if command.size == 0 | |
STDERR.puts "#{given_command}: command not found" | |
next | |
end | |
end | |
command_pid = fork do | |
File.open(history_file_path, "a") { |f| f.puts(line) } | |
if given_command == "eval" | |
p eval(line.sub(/^eval\s+/, '')) | |
elsif `file #{command}` =~ /: a .*ruby.* script text executable/ | |
# reload classes | |
if defined?(ActionDispatch::Reloader) | |
# Rails 3.1 | |
ActionDispatch::Reloader.cleanup! | |
ActionDispatch::Reloader.prepare! | |
else | |
# Rails 3.0 | |
# pulled from Railties source, this triggers something | |
ActionDispatch::Callbacks.new(Proc.new {}, false).call({}) | |
# ActiveSupport::DescendantsTracker.clear | |
# ActiveSupport::Dependencies.clear | |
# fix problem with ::Something::OtherThing resolving to ::OtherThing | |
Rails.application.config.eager_load_paths.map { |p| Dir[p + '/**/*.rb'] }.flatten.each { |rb| require_dependency rb } | |
end | |
silence_warnings { ARGV = arguments } | |
load(command) | |
else | |
exec line | |
end | |
end | |
# send cntl-c to the child | |
trap("INT") { Process.kill("INT", command_pid) } | |
command_time = Benchmark.realtime { Process.wait(command_pid) } | |
puts "#{line.size < 15 ? line : given_command} took %.2f seconds." % command_time if command_time > 0.4 | |
trap("INT", "DEFAULT") | |
end | |
puts |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment