Created
July 24, 2012 14:40
-
-
Save cie/3170308 to your computer and use it in GitHub Desktop.
IGem - run gem executables with forking, thus save the loading time. Can be used to speed up Rails generate, Rails server startup or Rake from minutes to seconds.
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
=begin | |
IGem - run gem executables with forking, thus save the loading time. Can be used to speed up Rails generate, Rails server startup or Rake from minutes to seconds. | |
Usage: | |
$ rails console | |
>> IGem.run "rake db:migrate" | |
>> IGem.run "rails server", wait: false | |
>> IGem.run "rake --tasks", fork: false | |
The first word of the command can be: | |
* a gem executable: rspec | |
* a gem name and an executable: rspec-core#rspec | |
* a path to a ruby file: script/something.rb | |
Options and default values: | |
fork: true to fork the process or just run in this one (! rails generate and some others will stop the process after running) | |
wait: true if fork is true, wait for the forked process with Process.wait | |
env: {} update the environment with these values | |
! you cannot always change environments this way because bundler will not load gems from other envs | |
=end | |
module IGem | |
def self.run cmdline, opts={} | |
opts = { | |
:fork=>Process.respond_to?(:fork), | |
:wait=>true, | |
:env=>{} | |
}.merge(opts) | |
# split cmdline | |
cmd, *args = cmdline.scan(/(?:[^"\s]+|"[^"]+")+/).map{|s|s.chars.grep(/[^"]/).join} | |
# find executable | |
case cmd | |
when /\// | |
# for example scripts/something.rb | |
executable = cmd | |
when /#/ | |
# for example rspec-core#rspec | |
executable = Gem.bin_path(*cmd.split("#")) | |
else | |
# for example rspec | |
executable = Gem.bin_path(nil, cmd) | |
end | |
# if fork is requested | |
if opts[:fork] | |
fork do | |
ENV.update opts[:env] | |
ARGV.replace args | |
load executable | |
end | |
# wait if requested | |
Process.wait if opts[:wait] | |
else | |
# run without forking | |
ENV.update opts[:env] | |
ARGV.replace args | |
load executable | |
end | |
end | |
end |
Gem.bin_path was called the wrong way. I also added a possibility to execute arbitrary ruby files, or to specify both the gem and the executable name.
Also see my irails gist, this is probably faster for rails server.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, cle, I tried to use your gist with "rails s" command and it throws "Gem::Exception: no default executable for rails-3.2.7", couldn't figure out why. Any thoughts?