gogo 1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gogo.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Originally authored 2012 Brian Hempel
2
+
3
+ Public domain; no restrictions.
4
+
5
+ While the software is provided without copyright, the following clause from the MIT License applies:
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
8
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
10
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE
11
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
12
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
13
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,76 @@
1
+ # GoGo
2
+
3
+ Yaknow how you're waiting for waiting for Rails to start and other people overhear you say "Go Go Go Go!" to your computer?
4
+
5
+ Install the gem:
6
+
7
+ gem install gogo
8
+
9
+ Make sure you're in your Rails project and then run:
10
+
11
+ $ gogo
12
+
13
+ That will launch you into a pseudo-shell with the Rails test environment reloaded. If you want to use gogo for development commands such as `rake db:seed`, `rake db:migrate`, or `rails console`, launch a separate shell and run:
14
+
15
+ $ gogo d
16
+
17
+ Now, run some commands. Ruby scripts that load Rails should start astronomically faster.
18
+
19
+ ## Sounds fishy...
20
+
21
+ It is fishy. GoGo is a hack script.
22
+
23
+ I'm sharing it with the world because it's an incredibly useful hack, but I can't guarantee any level of maintenance on my part. If stuff breaks, you're on your own to fix it. Leave your experience in the [wiki](https://github.com/brianhempel/gogo/wiki) to help others.
24
+
25
+ GoGo is a lot like Spork. GoGo preloads your rails environment. When you run a ruby command, the gogo process is forked and the command is loaded into that environment. Here's a performance comparison for a large project:
26
+
27
+ $ time bundle exec cucumber features/admin/dashboard.feature:0
28
+ real 0m30.457s
29
+ user 0m27.300s
30
+ sys 0m2.941s
31
+
32
+ $ gogo
33
+ Creating default Gofile for Rails...
34
+ Loading application.rb...and environment.rb...and cucumber...and cucumber/rails...and webmock/cucumber...and ruby-debug...and factory_girl/step_definitions...and email_spec...and email_spec/cucumber...and capybara/firebug...and vcr...and rake...took 26.25 seconds.
35
+ test $ cucumber features/admin/dashboard.feature:0
36
+ cucumber took 3.65 seconds.
37
+ test $ cucumber features/admin/dashboard.feature:0
38
+ cucumber took 3.58 seconds.
39
+
40
+ The advantages over Spork are:
41
+
42
+ 1. No DRB weirdness
43
+ 2. Easy install -- little to no modification to test environment.
44
+ 3. Speeds up other rails commands: rake routes, rails g migration, rake db:seed
45
+ 4. Single tab, so you know when code reloads are complete.
46
+
47
+ General disadvantages:
48
+
49
+ 1. It's not a full shell. No aliases or boolean logic || && for commands.
50
+ 2. You're already in a bundled environment, so rake db:seed is going to apply to the test environment. You probably don't want that.
51
+ 3. Have to ctrl-D and reload after Gemfile changes.
52
+ 4. Uses some Mac OS X only features, but if you want to hack those out it shouldn't be too hard.
53
+
54
+ One advantage over even the shell is a per-project and per-environment command history.
55
+
56
+ ## Contributing
57
+
58
+ To fix a problem or add a feature, use the standard pull request workflow:
59
+
60
+ # fork it on github, then clone:
61
+ git clone git@github.com:YOUR_USERNAME/gogo.git
62
+ # hack away
63
+ git push
64
+ # then make a pull request
65
+
66
+ Once you get a pull request accepted, I'll add you so you can commit directly to the repository.
67
+
68
+ git clone git@github.com:brianhempel/gogo.git
69
+ # hack away
70
+ git push
71
+
72
+ ## License
73
+
74
+ Public domain; no restrictions.
75
+
76
+ And certainly: no warrantee of fitness for any purpose. It's a hack. Use at your own risk.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'benchmark'
4
+ require 'fileutils'
5
+ require 'readline'
6
+
7
+ module GoGo
8
+ def self.preload(&block)
9
+ @preload = block if block_given?
10
+ @preload || Proc.new
11
+ end
12
+
13
+ def self.command_filter(&block)
14
+ @command_filter = block if block_given?
15
+ @command_filter || Proc.new
16
+ end
17
+
18
+ def self.before_each_ruby_command(&block)
19
+ @before_each_ruby_command = block if block_given?
20
+ @before_each_ruby_command || Proc.new
21
+ end
22
+ end
23
+
24
+ unless File.exists?("Gofile")
25
+ puts "Creating default Gofile for Rails..."
26
+ default_template_path = File.expand_path('../../lib/gogo/gofile_templates/rails.rb', __FILE__)
27
+ FileUtils.cp(default_template_path, "Gofile")
28
+ end
29
+ load("Gofile")
30
+
31
+ GoGo.preload.call
32
+
33
+ Readline.completion_proc = Proc.new do |str|
34
+ Readline.completion_append_character = "" # space doesn't work on OS X :(
35
+ command_candidates = AUTOCOMPLETE_COMMANDS.grep(/^#{Regexp.escape(str)}/)
36
+ file_candidates = Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
37
+ file_candidates.map! do |path|
38
+ # add a space unless a directory
39
+ File.directory?(path) ? path : path + ' '
40
+ end
41
+ rake_task_candidates = RAKE_COMMANDS.grep(/^#{Regexp.escape(str)}/)
42
+ command_candidates + file_candidates + rake_task_candidates
43
+ end
44
+
45
+ ENV['GOGO_ENV'] ||= 'development'
46
+ history_file_path = ".gogo_history-#{ENV['GOGO_ENV']}"
47
+
48
+ # load old history
49
+ if File.exists?(history_file_path)
50
+ Readline::HISTORY.clear
51
+ File.read(history_file_path).lines.each { |l| Readline::HISTORY << l.chomp }
52
+ end
53
+
54
+ while line = Readline.readline("\033[1;32m#{Dir.pwd.sub(/.*\//, '')} \033[0;35m#{ENV['GOGO_ENV']} \033[0;34m$ \033[0m", true)
55
+ if line.blank?
56
+ Readline::HISTORY.pop # don't store blank commands in history
57
+ next
58
+ end
59
+ given_command, *arguments = line.split
60
+
61
+ command = GoGo.command_filter.call(given_command)
62
+
63
+ unless given_command == 'eval'
64
+ command = `which #{command}`.chomp
65
+
66
+ if command.size == 0
67
+ STDERR.puts "#{given_command}: command not found"
68
+ next
69
+ end
70
+ end
71
+
72
+ command_pid = fork do
73
+ File.open(history_file_path, "a") { |f| f.puts(line) }
74
+
75
+ if given_command == "eval"
76
+ p eval(line.sub(/^eval\s+/, ''))
77
+ elsif `file #{command}` =~ /: a .*ruby.* script text executable/
78
+
79
+ GoGo.before_each_ruby_command.call(given_command, arguments)
80
+
81
+ silence_warnings { ARGV = arguments }
82
+ load(command)
83
+ else
84
+ exec line
85
+ end
86
+ end
87
+
88
+ # send cntl-c to the child
89
+ trap("INT") { Process.kill("INT", command_pid) }
90
+
91
+ command_time = Benchmark.realtime { Process.wait(command_pid) }
92
+ puts "#{line.size < 15 ? line : given_command} took %.2f seconds." % command_time if command_time > 0.4
93
+
94
+ trap("INT", "DEFAULT")
95
+ end
96
+
97
+ puts
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/gogo/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Brian Hempel"]
6
+ gem.email = ["plastichicken@gmail.com"]
7
+ gem.description = "Pseudo-shell hack with Rails environment preloaded for faster boot times and thus faster testing iterations. Go go go go go!"
8
+ gem.summary = gem.description
9
+ gem.homepage = "https://github.com/brianhempel/gogo"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "gogo"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = GoGo::VERSION
17
+ end
@@ -0,0 +1 @@
1
+ require "gogo/version"
@@ -0,0 +1,90 @@
1
+ # autocomplete commands
2
+ # thanks to http://bogojoker.com/readline/
3
+ # and to https://github.com/ruby/ruby/blob/trunk/ext/readline/readline.c
4
+ AUTOCOMPLETE_COMMANDS = ['rake ', 'cucumber features/', 'rails ', 'rspec spec/'].sort
5
+ 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']
6
+
7
+ GoGo.preload do
8
+ if ARGV[0]
9
+ ENV['RAILS_ENV'] = %w{development test production staging}.find { |e| e[0] == ARGV[0][0] } || ARGV[0]
10
+ else
11
+ ENV['RAILS_ENV'] = ENV['GOGO_ENV'] || 'test'
12
+ end
13
+ # need GOGO_ENV for the history file
14
+ ENV['GOGO_ENV'] = ENV['RAILS_ENV']
15
+
16
+ load_time = Benchmark.realtime do
17
+ print "Loading application.rb..."
18
+ require File.expand_path('./config/application', Dir.pwd)
19
+
20
+ # we'll use class reloading
21
+ # thanks to spork for lots of direction here
22
+ # https://github.com/sporkrb/spork-rails/blob/master/lib/spork/app_framework/rails.rb
23
+ # https://github.com/sporkrb/spork-rails/blob/master/lib/spork/ext/rails-reloader.rb
24
+ Rails::Engine.class_eval do
25
+ def eager_load!
26
+ railties.all(&:eager_load!) if defined?(railties)
27
+ # but don't eager load the eager_load_paths
28
+ end
29
+ end
30
+ print "and environment.rb..."
31
+ require File.expand_path('./config/environment', Dir.pwd)
32
+ ActiveSupport::Dependencies.mechanism = :load
33
+
34
+ if Rails.env.test?
35
+ print "and cucumber..."
36
+ require 'rspec'
37
+ begin
38
+ require 'cucumber' # saves 0.4 seconds when running cucumber
39
+
40
+ # load everything that appears in test env.rb
41
+ # this shaves off another 2 seconds
42
+ # even though most of the loads technically fail
43
+ ENV['RAILS_ROOT'] = Dir.pwd
44
+ other_paths = File.read(Dir.pwd + "/features/support/env.rb").scan(/^require ['"](.+?)['"](?!.*gogo: skip)/).flatten
45
+ other_paths.each do |path|
46
+ print "and #{path}..."
47
+ begin
48
+ # load in annoymous modules so, basically, we're just cache-warming
49
+ load(path + '.rb', true)
50
+ rescue
51
+ end
52
+ end
53
+ rescue LoadError
54
+ end
55
+ end
56
+
57
+ print "and rake..."
58
+ require 'rake'
59
+ end
60
+
61
+ puts "took %.2f seconds." % load_time
62
+ end
63
+
64
+ GoGo.command_filter do |given_command|
65
+ # running just "rails" does an exec which reloads everything and defeats the point of preloading
66
+ given_command == 'rails' ? './script/rails' : given_command
67
+ end
68
+
69
+ GoGo.before_each_ruby_command do |given_command, arguments|
70
+ if given_command =~ /^(cucumber|rspec)$/ && ENV['RAILS_ENV'] != 'test'
71
+ STDERR.puts "Don't run your tests when not in the test environment!"
72
+ exit 1
73
+ end
74
+
75
+ # reload classes
76
+ if defined?(ActionDispatch::Reloader)
77
+ # Rails 3.1
78
+ ActionDispatch::Reloader.cleanup!
79
+ ActionDispatch::Reloader.prepare!
80
+ else
81
+ # Rails 3.0
82
+ # pulled from Railties source, this triggers something
83
+ ActionDispatch::Callbacks.new(Proc.new {}, false).call({})
84
+ # ActiveSupport::DescendantsTracker.clear
85
+ # ActiveSupport::Dependencies.clear
86
+
87
+ # fix problem with ::Something::OtherThing resolving to ::OtherThing
88
+ Rails.application.config.eager_load_paths.map { |p| Dir[p + '/**/*.rb'] }.flatten.each { |rb| require_dependency rb }
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module GoGo
2
+ VERSION = "1"
3
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gogo
3
+ version: !ruby/object:Gem::Version
4
+ version: '1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Brian Hempel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-01 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: Pseudo-shell hack with Rails environment preloaded for faster boot times
15
+ and thus faster testing iterations. Go go go go go!
16
+ email:
17
+ - plastichicken@gmail.com
18
+ executables:
19
+ - gogo
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - Gemfile
25
+ - LICENSE
26
+ - README.md
27
+ - Rakefile
28
+ - bin/gogo
29
+ - gogo.gemspec
30
+ - lib/gogo.rb
31
+ - lib/gogo/gofile_templates/rails.rb
32
+ - lib/gogo/version.rb
33
+ homepage: https://github.com/brianhempel/gogo
34
+ licenses: []
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 1.8.17
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: Pseudo-shell hack with Rails environment preloaded for faster boot times
57
+ and thus faster testing iterations. Go go go go go!
58
+ test_files: []