add deamonize option and start some tests

This commit is contained in:
John Bintz 2011-06-01 10:06:35 -04:00
parent e8fd98faa1
commit 745d49da67
8 changed files with 184 additions and 40 deletions

View File

@ -3,3 +3,4 @@ source "http://rubygems.org"
# Specify your gem's dependencies in guard-rails.gemspec # Specify your gem's dependencies in guard-rails.gemspec
gemspec gemspec
gem 'rake', '0.8.7' gem 'rake', '0.8.7'
gem 'growl'

8
Guardfile Normal file
View File

@ -0,0 +1,8 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'rspec', :version => 2 do
watch(%r{^spec/.+_spec\.rb})
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
end

View File

@ -20,4 +20,7 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.add_dependency 'guard', '>= 0.2.2' s.add_dependency 'guard', '>= 0.2.2'
s.add_development_dependency 'rspec', '~> 2.6.0'
s.add_development_dependency 'mocha'
end end

View File

@ -1,10 +1,11 @@
require 'guard' require 'guard'
require 'guard/guard' require 'guard/guard'
require 'guard/rails/runner'
require 'rbconfig' require 'rbconfig'
module Guard module Guard
class Rails < ::Guard::Guard class Rails < ::Guard::Guard
attr_reader :options attr_reader :options, :runner
def initialize(watchers = [], options = {}) def initialize(watchers = [], options = {})
super super
@ -14,6 +15,8 @@ module Guard
:start_on_start => true, :start_on_start => true,
:force_run => false :force_run => false
}.merge(options) }.merge(options)
@runner = Guard::RailsRunner.new(options)
end end
def start def start
@ -22,56 +25,21 @@ module Guard
end end
def run_all def run_all
UI.info "Restarting Rails"
Notifier.notify("Rails restarting on port #{options[:port]} in #{options[:environment]} environment...", :title => "Restarting Rails...", :image => :pending) Notifier.notify("Rails restarting on port #{options[:port]} in #{options[:environment]} environment...", :title => "Restarting Rails...", :image => :pending)
stop_rails ; start_rails runner.restart
UI.info "Rails restarted, pid #{File.read(pid_file)}"
Notifier.notify("Rails restarted on port #{options[:port]}.", :title => "Rails restarted!", :image => :success) Notifier.notify("Rails restarted on port #{options[:port]}.", :title => "Rails restarted!", :image => :success)
end end
def stop def stop
Notifier.notify("Until next time...", :title => "Rails shutting down.", :image => :pending) Notifier.notify("Until next time...", :title => "Rails shutting down.", :image => :pending)
stop_rails runner.stop
end end
def run_on_change(paths) def run_on_change(paths)
run_all run_all
end end
private
def pid_file
File.expand_path("tmp/pids/#{options[:environment]}.pid")
end
def start_rails
kill_unmanaged_pid! if options[:force_run]
system %{sh -c 'cd #{Dir.pwd} && rails s -e #{options[:environment]} -p #{options[:port]} --pid #{pid_file} &'}
while !File.file?(pid_file)
sleep 0.5
end
UI.info "Rails restarted, pid #{File.read(pid_file)}"
end
def stop_rails
if File.file?(pid_file)
system %{kill -INT #{File.read(pid_file).strip}}
end
end
def unmanaged_pid
if RbConfig::CONFIG['host_os'] =~ /darwin/
%x{lsof -P}.each_line { |line|
if line["*:#{options[:port]} "]
return line.split("\s")[1]
end
}
end
nil
end
def kill_unmanaged_pid!
if pid = unmanaged_pid
system %{kill -INT #{pid}}
end
end
end end
end end

77
lib/guard/rails/runner.rb Normal file
View File

@ -0,0 +1,77 @@
module Guard
class RailsRunner
attr_reader :options
def initialize(options)
@options = options
end
def start
kill_unmanaged_pid! if options[:force_run]
run_rails_command!
count = 0
while !has_pid? && count < 10
wait_for_pid_action
count += 1
end
end
def stop
if File.file?(pid_file)
system %{kill -INT #{File.read(pid_file).strip}}
end
end
def restart
stop
start
end
def build_rails_command
rails_options = [
'-e', options[:environment],
'-p', options[:port],
'--pid', pid_file
]
rails_options << '-d' if options[:daemon]
%{sh -c 'cd #{Dir.pwd} && rails s #{rails_options.join(' ')} &'}
end
private
def run_rails_command!
system build_rails_command
end
def has_pid?
File.file?(pid_file)
end
def wait_for_pid_action
0.5
end
def pid_file
File.expand_path("tmp/pids/#{options[:environment]}.pid")
end
def kill_unmanaged_pid!
if pid = unmanaged_pid
system %{kill -INT #{pid}}
end
end
def unmanaged_pid
if RbConfig::CONFIG['host_os'] =~ /darwin/
%x{lsof -P}.each_line { |line|
if line["*:#{options[:port]} "]
return line.split("\s")[1]
end
}
end
nil
end
end
end

View File

@ -0,0 +1,75 @@
require 'spec_helper'
require 'guard/rails/runner'
describe Guard::RailsRunner do
let(:runner) { Guard::RailsRunner.new(options) }
let(:environment) { 'development' }
let(:port) { 3000 }
let(:default_options) { { :environment => environment, :port => port } }
let(:options) { default_options }
describe '#build_rails_command' do
context 'no daemon' do
it "should not have a daemon switch" do
runner.build_rails_command.should_not match(%r{ -d})
end
end
context 'daemon' do
let(:options) { default_options.merge(:daemon => true) }
it "should have a daemon switch" do
runner.build_rails_command.should match(%r{ -d})
end
end
end
describe '#start' do
let(:kill_expectation) { runner.expects(:kill_unmanaged_pid!) }
let(:pid_stub) { runner.stubs(:has_pid?) }
before do
runner.expects(:run_rails_command!).once
end
context 'do not force run' do
before do
pid_stub.returns(true)
kill_expectation.never
runner.expects(:wait_for_pid_action).never
end
it "should act properly" do
runner.start
end
end
context 'force run' do
let(:options) { default_options.merge(:force_run => true) }
before do
pid_stub.returns(true)
kill_expectation.once
runner.expects(:wait_for_pid_action).never
end
it "should act properly" do
runner.start
end
end
context "don't write the pid" do
before do
pid_stub.returns(false)
kill_expectation.never
runner.expects(:wait_for_pid_action).times(10)
end
it "should act properly" do
runner.start
end
end
end
end

View File

@ -0,0 +1,7 @@
require 'spec_helper'
require 'guard/rails'
describe Guard::Rails do
end

5
spec/spec_helper.rb Normal file
View File

@ -0,0 +1,5 @@
require 'mocha'
RSpec.configure do |c|
c.mock_with :mocha
end