Skip to content

Instantly share code, notes, and snippets.

@brianhempel
Created January 30, 2012 14:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianhempel/1704773 to your computer and use it in GitHub Desktop.
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
#!/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