guard-rails 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +8 -0
- data/Guardfile +8 -0
- data/README.md +4 -2
- data/Rakefile +22 -0
- data/guard-rails.gemspec +3 -0
- data/lib/guard/rails.rb +22 -47
- data/lib/guard/rails/runner.rb +88 -0
- data/lib/guard/rails/version.rb +1 -1
- data/spec/lib/guard/rails/runner_spec.rb +106 -0
- data/spec/lib/guard/rails_spec.rb +92 -0
- data/spec/spec_helper.rb +5 -0
- metadata +35 -6
data/Gemfile
CHANGED
@@ -3,3 +3,11 @@ source "http://rubygems.org"
|
|
3
3
|
# Specify your gem's dependencies in guard-rails.gemspec
|
4
4
|
gemspec
|
5
5
|
gem 'rake', '0.8.7'
|
6
|
+
gem 'fakefs', :require => nil
|
7
|
+
gem 'guard'
|
8
|
+
gem 'guard-rspec'
|
9
|
+
|
10
|
+
# TODO: make this more OS-independent...like the rest of the gem
|
11
|
+
gem 'growl'
|
12
|
+
gem 'rb-fsevent'
|
13
|
+
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -5,13 +5,15 @@ Want to restart your Rails development server whilst you work? Now you can!
|
|
5
5
|
watch(%r{^(config|lib)/.*})
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
Lots of fun options!
|
9
9
|
|
10
10
|
* `:port` is the port number to run on (default `3000`)
|
11
11
|
* `:environment` is the environment to use (default `development`)
|
12
12
|
* `:start_on_start` will start the server when starting Guard (default `true`)
|
13
13
|
* `:force_run` kills any process that's holding open the listen port before attempting to (re)start Rails (default `false`).
|
14
|
+
* `:daemon` runs the server as a daemon, without any output to the terminal that ran `guard` (default `false`).
|
15
|
+
* `:timeout` waits this number of seconds when restarting the Rails server before reporting there's a problem (default `20`).
|
14
16
|
|
15
17
|
This is super-alpha, but it works for me! Only really hand-tested in Mac OS X. Feel free to fork'n'fix for other
|
16
|
-
OSes, and to add some real tests.
|
18
|
+
OSes, and to add some more real tests.
|
17
19
|
|
data/Rakefile
CHANGED
@@ -1,2 +1,24 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
namespace :spec do
|
5
|
+
desc "Run on three Rubies"
|
6
|
+
task :platforms do
|
7
|
+
current = %x{rvm-prompt v}
|
8
|
+
|
9
|
+
fail = false
|
10
|
+
%w{1.8.7 1.9.2 ree}.each do |version|
|
11
|
+
puts "Switching to #{version}"
|
12
|
+
system %{rvm #{version}}
|
13
|
+
system %{bundle exec rspec spec}
|
14
|
+
if $?.exitstatus != 0
|
15
|
+
fail = true
|
16
|
+
break
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
system %{rvm #{current}}
|
21
|
+
|
22
|
+
exit (fail ? 1 : 0)
|
23
|
+
end
|
24
|
+
end
|
data/guard-rails.gemspec
CHANGED
data/lib/guard/rails.rb
CHANGED
@@ -1,77 +1,52 @@
|
|
1
1
|
require 'guard'
|
2
2
|
require 'guard/guard'
|
3
|
+
require 'guard/rails/runner'
|
3
4
|
require 'rbconfig'
|
4
5
|
|
5
6
|
module Guard
|
6
7
|
class Rails < ::Guard::Guard
|
7
|
-
attr_reader :options
|
8
|
+
attr_reader :options, :runner
|
8
9
|
|
9
|
-
|
10
|
-
super
|
11
|
-
@options = {
|
10
|
+
DEFAULT_OPTIONS = {
|
12
11
|
:port => 3000,
|
13
12
|
:environment => 'development',
|
14
13
|
:start_on_start => true,
|
15
|
-
:force_run => false
|
16
|
-
|
14
|
+
:force_run => false,
|
15
|
+
:timeout => 20
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(watchers = [], options = {})
|
19
|
+
super
|
20
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
21
|
+
|
22
|
+
@runner = RailsRunner.new(@options)
|
17
23
|
end
|
18
24
|
|
19
25
|
def start
|
20
|
-
UI.info "Guard::Rails
|
26
|
+
UI.info "Guard::Rails will now restart your app on port #{options[:port]} using #{options[:environment]} environment."
|
21
27
|
run_all if options[:start_on_start]
|
22
28
|
end
|
23
29
|
|
24
30
|
def run_all
|
31
|
+
UI.info "Restarting Rails..."
|
25
32
|
Notifier.notify("Rails restarting on port #{options[:port]} in #{options[:environment]} environment...", :title => "Restarting Rails...", :image => :pending)
|
26
|
-
|
27
|
-
|
33
|
+
if runner.restart
|
34
|
+
UI.info "Rails restarted, pid #{runner.pid}"
|
35
|
+
Notifier.notify("Rails restarted on port #{options[:port]}.", :title => "Rails restarted!", :image => :success)
|
36
|
+
else
|
37
|
+
UI.info "Rails NOT restarted, check your log files."
|
38
|
+
Notifier.notify("Rails NOT restarted, check your log files.", :title => "Rails NOT restarted!", :image => :failure)
|
39
|
+
end
|
28
40
|
end
|
29
41
|
|
30
42
|
def stop
|
31
43
|
Notifier.notify("Until next time...", :title => "Rails shutting down.", :image => :pending)
|
32
|
-
|
44
|
+
runner.stop
|
33
45
|
end
|
34
46
|
|
35
47
|
def run_on_change(paths)
|
36
48
|
run_all
|
37
49
|
end
|
38
|
-
|
39
|
-
private
|
40
|
-
def pid_file
|
41
|
-
File.expand_path("tmp/pids/#{options[:environment]}.pid")
|
42
|
-
end
|
43
|
-
|
44
|
-
def start_rails
|
45
|
-
kill_unmanaged_pid! if options[:force_run]
|
46
|
-
system %{sh -c 'cd #{Dir.pwd} && rails s -e #{options[:environment]} -p #{options[:port]} --pid #{pid_file} &'}
|
47
|
-
while !File.file?(pid_file)
|
48
|
-
sleep 0.5
|
49
|
-
end
|
50
|
-
UI.info "Rails restarted, pid #{File.read(pid_file)}"
|
51
|
-
end
|
52
|
-
|
53
|
-
def stop_rails
|
54
|
-
if File.file?(pid_file)
|
55
|
-
system %{kill -INT #{File.read(pid_file).strip}}
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def unmanaged_pid
|
60
|
-
if RbConfig::CONFIG['host_os'] =~ /darwin/
|
61
|
-
%x{lsof -P}.each_line { |line|
|
62
|
-
if line["*:#{options[:port]} "]
|
63
|
-
return line.split("\s")[1]
|
64
|
-
end
|
65
|
-
}
|
66
|
-
end
|
67
|
-
nil
|
68
|
-
end
|
69
|
-
|
70
|
-
def kill_unmanaged_pid!
|
71
|
-
if pid = unmanaged_pid
|
72
|
-
system %{kill -INT #{pid}}
|
73
|
-
end
|
74
|
-
end
|
75
50
|
end
|
76
51
|
end
|
77
52
|
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Guard
|
2
|
+
class RailsRunner
|
3
|
+
MAX_WAIT_COUNT = 10
|
4
|
+
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
kill_unmanaged_pid! if options[:force_run]
|
13
|
+
run_rails_command!
|
14
|
+
count = 0
|
15
|
+
while !has_pid? && count < MAX_WAIT_COUNT
|
16
|
+
wait_for_pid_action
|
17
|
+
count += 1
|
18
|
+
end
|
19
|
+
!(count == MAX_WAIT_COUNT)
|
20
|
+
end
|
21
|
+
|
22
|
+
def stop
|
23
|
+
if File.file?(pid_file)
|
24
|
+
system %{kill -INT #{File.read(pid_file).strip}}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def restart
|
29
|
+
stop
|
30
|
+
start
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_rails_command
|
34
|
+
rails_options = [
|
35
|
+
'-e', options[:environment],
|
36
|
+
'-p', options[:port],
|
37
|
+
'--pid', pid_file
|
38
|
+
]
|
39
|
+
|
40
|
+
rails_options << '-d' if options[:daemon]
|
41
|
+
|
42
|
+
%{sh -c 'cd #{Dir.pwd} && rails s #{rails_options.join(' ')} &'}
|
43
|
+
end
|
44
|
+
|
45
|
+
def pid_file
|
46
|
+
File.expand_path("tmp/pids/#{options[:environment]}.pid")
|
47
|
+
end
|
48
|
+
|
49
|
+
def pid
|
50
|
+
File.file?(pid_file) ? File.read(pid_file).to_i : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def sleep_time
|
54
|
+
options[:timeout].to_f / MAX_WAIT_COUNT.to_f
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def run_rails_command!
|
59
|
+
system build_rails_command
|
60
|
+
end
|
61
|
+
|
62
|
+
def has_pid?
|
63
|
+
File.file?(pid_file)
|
64
|
+
end
|
65
|
+
|
66
|
+
def wait_for_pid_action
|
67
|
+
sleep sleep_time
|
68
|
+
end
|
69
|
+
|
70
|
+
def kill_unmanaged_pid!
|
71
|
+
if pid = unmanaged_pid
|
72
|
+
system %{kill -INT #{pid}}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def unmanaged_pid
|
77
|
+
if RbConfig::CONFIG['host_os'] =~ /darwin/
|
78
|
+
%x{lsof -P}.each_line { |line|
|
79
|
+
if line["*:#{options[:port]} "]
|
80
|
+
return line.split("\s")[1]
|
81
|
+
end
|
82
|
+
}
|
83
|
+
end
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
data/lib/guard/rails/version.rb
CHANGED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'guard/rails/runner'
|
3
|
+
require 'fakefs/spec_helpers'
|
4
|
+
|
5
|
+
describe Guard::RailsRunner do
|
6
|
+
let(:runner) { Guard::RailsRunner.new(options) }
|
7
|
+
let(:environment) { 'development' }
|
8
|
+
let(:port) { 3000 }
|
9
|
+
|
10
|
+
let(:default_options) { { :environment => environment, :port => port } }
|
11
|
+
let(:options) { default_options }
|
12
|
+
|
13
|
+
describe '#pid' do
|
14
|
+
include FakeFS::SpecHelpers
|
15
|
+
|
16
|
+
context 'pid file exists' do
|
17
|
+
let(:pid) { 12345 }
|
18
|
+
|
19
|
+
before do
|
20
|
+
File.open(runner.pid_file, 'w') { |fh| fh.print pid }
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should read the pid" do
|
24
|
+
runner.pid.should == pid
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'pid file does not exist' do
|
29
|
+
it "should return nil" do
|
30
|
+
runner.pid.should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#build_rails_command' do
|
36
|
+
context 'no daemon' do
|
37
|
+
it "should not have a daemon switch" do
|
38
|
+
runner.build_rails_command.should_not match(%r{ -d})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'daemon' do
|
43
|
+
let(:options) { default_options.merge(:daemon => true) }
|
44
|
+
|
45
|
+
it "should have a daemon switch" do
|
46
|
+
runner.build_rails_command.should match(%r{ -d})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#start' do
|
52
|
+
let(:kill_expectation) { runner.expects(:kill_unmanaged_pid!) }
|
53
|
+
let(:pid_stub) { runner.stubs(:has_pid?) }
|
54
|
+
|
55
|
+
before do
|
56
|
+
runner.expects(:run_rails_command!).once
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'do not force run' do
|
60
|
+
before do
|
61
|
+
pid_stub.returns(true)
|
62
|
+
kill_expectation.never
|
63
|
+
runner.expects(:wait_for_pid_action).never
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should act properly" do
|
67
|
+
runner.start.should be_true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'force run' do
|
72
|
+
let(:options) { default_options.merge(:force_run => true) }
|
73
|
+
|
74
|
+
before do
|
75
|
+
pid_stub.returns(true)
|
76
|
+
kill_expectation.once
|
77
|
+
runner.expects(:wait_for_pid_action).never
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should act properly" do
|
81
|
+
runner.start.should be_true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "don't write the pid" do
|
86
|
+
before do
|
87
|
+
pid_stub.returns(false)
|
88
|
+
kill_expectation.never
|
89
|
+
runner.expects(:wait_for_pid_action).times(Guard::RailsRunner::MAX_WAIT_COUNT)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should act properly" do
|
93
|
+
runner.start.should be_false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#sleep_time' do
|
99
|
+
let(:timeout) { 30 }
|
100
|
+
let(:options) { default_options.merge(:timeout => timeout) }
|
101
|
+
|
102
|
+
it "should adjust the sleep time as necessary" do
|
103
|
+
runner.sleep_time.should == (timeout.to_f / Guard::RailsRunner::MAX_WAIT_COUNT.to_f)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'guard/rails'
|
3
|
+
|
4
|
+
describe Guard::Rails do
|
5
|
+
let(:guard) { Guard::Rails.new(watchers, options) }
|
6
|
+
let(:watchers) { [] }
|
7
|
+
let(:options) { {} }
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
it "should initialize with options" do
|
11
|
+
guard
|
12
|
+
|
13
|
+
guard.runner.options[:port].should == 3000
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#start' do
|
18
|
+
let(:ui_expectation) { Guard::UI.expects(:info).with(regexp_matches(/#{Guard::Rails::DEFAULT_OPTIONS[:port]}/)) }
|
19
|
+
|
20
|
+
context 'start on start' do
|
21
|
+
it "should show the right message and run startup" do
|
22
|
+
guard.expects(:run_all).once
|
23
|
+
ui_expectation
|
24
|
+
guard.start
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'no start on start' do
|
29
|
+
let(:options) { { :start_on_start => false } }
|
30
|
+
|
31
|
+
it "should show the right message and not run startup" do
|
32
|
+
guard.expects(:run_all).never
|
33
|
+
ui_expectation
|
34
|
+
guard.start
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#run_all' do
|
40
|
+
let(:pid) { '12345' }
|
41
|
+
|
42
|
+
before do
|
43
|
+
Guard::UI.expects(:info).with('Restarting Rails...')
|
44
|
+
Guard::Notifier.expects(:notify).with(regexp_matches(/Rails restarting/), anything)
|
45
|
+
Guard::RailsRunner.any_instance.stubs(:pid).returns(pid)
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:runner_stub) { Guard::RailsRunner.any_instance.stubs(:restart) }
|
49
|
+
|
50
|
+
context 'with pid file' do
|
51
|
+
before do
|
52
|
+
runner_stub.returns(true)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should restart and show the pid file" do
|
56
|
+
Guard::UI.expects(:info).with(regexp_matches(/#{pid}/))
|
57
|
+
Guard::Notifier.expects(:notify).with(regexp_matches(/Rails restarted/), anything)
|
58
|
+
|
59
|
+
guard.run_all
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'no pid file' do
|
64
|
+
before do
|
65
|
+
runner_stub.returns(false)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should restart and show the pid file" do
|
69
|
+
Guard::UI.expects(:info).with(regexp_matches(/#{pid}/)).never
|
70
|
+
Guard::UI.expects(:info).with(regexp_matches(/Rails NOT restarted/))
|
71
|
+
Guard::Notifier.expects(:notify).with(regexp_matches(/Rails NOT restarted/), anything)
|
72
|
+
|
73
|
+
guard.run_all
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#stop' do
|
79
|
+
it "should stop correctly" do
|
80
|
+
Guard::Notifier.expects(:notify).with('Until next time...', anything)
|
81
|
+
guard.stop
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#run_on_change' do
|
86
|
+
it "should run on change" do
|
87
|
+
guard.expects(:run_all).once
|
88
|
+
guard.run_on_change([])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: guard-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- John Bintz
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-06-03 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -24,6 +24,28 @@ dependencies:
|
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 2.6.0
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: mocha
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *id003
|
27
49
|
description: Restart Rails when things change in your app
|
28
50
|
email:
|
29
51
|
- john@coswellproductions.com
|
@@ -36,13 +58,18 @@ extra_rdoc_files: []
|
|
36
58
|
files:
|
37
59
|
- .gitignore
|
38
60
|
- Gemfile
|
61
|
+
- Guardfile
|
39
62
|
- README.md
|
40
63
|
- Rakefile
|
41
64
|
- guard-rails.gemspec
|
42
65
|
- lib/guard-rails.rb
|
43
66
|
- lib/guard/rails.rb
|
67
|
+
- lib/guard/rails/runner.rb
|
44
68
|
- lib/guard/rails/templates/Guardfile
|
45
69
|
- lib/guard/rails/version.rb
|
70
|
+
- spec/lib/guard/rails/runner_spec.rb
|
71
|
+
- spec/lib/guard/rails_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
46
73
|
has_rdoc: true
|
47
74
|
homepage: ""
|
48
75
|
licenses: []
|
@@ -57,7 +84,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
84
|
requirements:
|
58
85
|
- - ">="
|
59
86
|
- !ruby/object:Gem::Version
|
60
|
-
hash:
|
87
|
+
hash: -1829971580643100829
|
61
88
|
segments:
|
62
89
|
- 0
|
63
90
|
version: "0"
|
@@ -66,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
93
|
requirements:
|
67
94
|
- - ">="
|
68
95
|
- !ruby/object:Gem::Version
|
69
|
-
hash:
|
96
|
+
hash: -1829971580643100829
|
70
97
|
segments:
|
71
98
|
- 0
|
72
99
|
version: "0"
|
@@ -77,5 +104,7 @@ rubygems_version: 1.6.2
|
|
77
104
|
signing_key:
|
78
105
|
specification_version: 3
|
79
106
|
summary: Restart Rails when things change in your app
|
80
|
-
test_files:
|
81
|
-
|
107
|
+
test_files:
|
108
|
+
- spec/lib/guard/rails/runner_spec.rb
|
109
|
+
- spec/lib/guard/rails_spec.rb
|
110
|
+
- spec/spec_helper.rb
|