rrails 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changes.md +6 -0
- data/README.md +78 -32
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/rrails +90 -3
- data/bin/rrails-server +3 -0
- data/lib/rrails/client.rb +42 -31
- data/lib/rrails/server.rb +145 -43
- data/rrails.gemspec +2 -1
- metadata +3 -2
data/Changes.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
v1.0.0 2012-10-16 01:03:00 +0900
|
2
|
+
- XXX: It may have many imcopatible changes. "1.0.0" does not mean "stable version".
|
3
|
+
- MOD: support UNIXDomainSocket instead of TCPSocket. And UnixDomainSocket is default behaviour. So you can be easy to run rrails in many rails project. But you should run rrails clinet under your project's directory.(thanks quark-zju)
|
4
|
+
- MOD: "rails-server" command is obsolate. please use "rrails start" instead. see more about README.md. (thanks quark-zju)
|
5
|
+
- MOD: pry command is removed. please use pry hacks instead. https://gist.github.com/941174 (thanks quark-zju)
|
6
|
+
|
1
7
|
v0.4.0 2012-10-15 09:56:00 +0900
|
2
8
|
------------------------------------------------------------------------
|
3
9
|
- MOD: pty support. So you can use rails console/server from rrails. (thanks quark-zju)
|
data/README.md
CHANGED
@@ -1,41 +1,54 @@
|
|
1
1
|
# rrails
|
2
2
|
|
3
|
-
Preload rails environment
|
3
|
+
Preload rails environment to make rails/rake commands faster.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
Without rrails:
|
8
|
+
|
9
|
+
$ time ( rails generate >/dev/null )
|
10
|
+
( rails generate > /dev/null; ) 9.29s user 0.41s system 98% cpu 9.807 total
|
11
|
+
$ time ( rake routes >/dev/null )
|
12
|
+
( rake routes > /dev/null; ) 8.17s user 0.36s system 98% cpu 8.639 total
|
13
|
+
|
14
|
+
With rrails:
|
15
|
+
|
16
|
+
$ source <(rrails shellrc)
|
17
|
+
$ rrails start # optionally
|
18
|
+
|
19
|
+
$ time ( rails generate >/dev/null )
|
20
|
+
( rails generate > /dev/null; ) 0.05s user 0.01s system 6% cpu 0.904 total
|
21
|
+
$ time ( rake routes >/dev/null )
|
22
|
+
( rake routes > /dev/null; ) 0.04s user 0.01s system 12% cpu 0.359 total
|
4
23
|
|
5
24
|
## Requirements
|
6
25
|
|
7
|
-
*
|
8
|
-
* Ruby 1.9.
|
26
|
+
* POSIX Environment (Linux 2.6 - , Mac OSX Montain Lion). Windows is not supported.
|
27
|
+
* Ruby 1.9.3p194 or above
|
9
28
|
|
10
29
|
## Usage
|
11
30
|
|
12
|
-
Start server:
|
13
|
-
|
14
|
-
$ cd ~/rails_project
|
15
|
-
$ export RAILS_ENV=development # optionally
|
16
|
-
$ bundle exec rrails-server
|
17
|
-
|
18
31
|
Run rails/rake commands using rrails:
|
19
32
|
|
20
|
-
$ export RAILS_ENV=development
|
21
|
-
$ rrails
|
22
|
-
$ rrails
|
23
|
-
$ rrails
|
24
|
-
$ rrails
|
25
|
-
$ rrails
|
26
|
-
$ rrails --
|
33
|
+
$ export RAILS_ENV=development # optionally
|
34
|
+
$ rrails rails generate model Yakiniku # first command, slow
|
35
|
+
$ rrails rails server # fast
|
36
|
+
$ rrails rails console # fast
|
37
|
+
$ rrails rake db:migrate # fast
|
38
|
+
$ rrails rake routes # fast
|
39
|
+
$ rrails -- rake -T # '--' is needed. Otherwise '-T' will be parsed by rrails
|
40
|
+
|
41
|
+
For more options, run:
|
42
|
+
|
43
|
+
$ rrails --help
|
27
44
|
|
28
|
-
|
29
|
-
# commands, you may want to add '--pty' option.
|
30
|
-
# This makes sure that interactive things (like line editing)
|
31
|
-
# work correctly, but it also redirect all STDERR to STDOUT
|
32
|
-
# and keys like ^C may not work correctly.
|
33
|
-
$ rrails --pty -- rails server # use debugger
|
45
|
+
### Shell integration
|
34
46
|
|
35
|
-
You may want to add following
|
47
|
+
You may want to add following lines to your shell rc file:
|
36
48
|
|
37
49
|
rrails-exec() {
|
38
|
-
if
|
50
|
+
if [ -e config/environment.rb ]; then
|
51
|
+
# this might be slow, see below
|
39
52
|
rrails -- "$@"
|
40
53
|
else
|
41
54
|
command "$@"
|
@@ -44,17 +57,50 @@ You may want to add following code to your shell rc file:
|
|
44
57
|
alias rails='rrails-exec rails'
|
45
58
|
alias rake='rrails-exec rake'
|
46
59
|
|
47
|
-
|
60
|
+
Directly running `rrails` (even without `bundle exec`) may be slow due to levels of dummy wrappers of Bundler.
|
61
|
+
You can replace `rrails` with an absolute path `/(path_to_rrails_gem)/bin/rrails` to get rid of Bundle initializing code.
|
62
|
+
This can save about 0.9 seconds.
|
63
|
+
|
64
|
+
These lines (with correct absolute path) can be generated by `rrails shellrc`. So you can quickly update your shell rc file using:
|
65
|
+
|
66
|
+
rrails shellrc >> ~/.zshrc
|
48
67
|
|
49
|
-
|
50
|
-
So, rrails can run rails/rake commands by preloaded daemon.
|
68
|
+
### Bundler
|
51
69
|
|
52
|
-
|
70
|
+
rrails works with bundler. Ususally `bundle exec` (which is slow) is not needed. `gem 'rrails'` is not required in Gemfile, either.
|
53
71
|
|
54
|
-
|
55
|
-
* it can't use zsh's histroy.
|
72
|
+
In case you want to make sure Gemfile is in use, or rrails version is specified in Gemfile, just run this before others:
|
56
73
|
|
57
|
-
|
74
|
+
$ bundle exec rrails start
|
75
|
+
|
76
|
+
### PTY mode
|
77
|
+
|
78
|
+
rrails's PTY mode makes sure that interactive things (like line editing)
|
79
|
+
work correctly. Note it also redirect all STDERR to STDOUT and keys like `^C`
|
80
|
+
may not work correctly.
|
81
|
+
|
82
|
+
PTY mode is enabled only for `rails console` and `rails db` by default.
|
83
|
+
If you need an interactive console for other commands, you can add `--pty` option:
|
84
|
+
|
85
|
+
$ rrails --pty rails server # if debugger is in use
|
86
|
+
|
87
|
+
Note: PTY mode does not support nested programs. For example, `pry` runs `less`
|
88
|
+
as its pager. This doesn't work properly. You need disable the pager of pry:
|
89
|
+
|
90
|
+
Pry.config.pager = false
|
91
|
+
|
92
|
+
### The server
|
93
|
+
|
94
|
+
By default, rrails will start a server process on demand per project per rails\_env.
|
95
|
+
The server writes pid and socket files to `./tmp/` and remove them when exiting.
|
96
|
+
|
97
|
+
You can control the server using:
|
98
|
+
|
99
|
+
$ export RAILS_ENV=development # optionally
|
100
|
+
$ rrails stop
|
101
|
+
$ rrails restart
|
102
|
+
$ rrails reload
|
103
|
+
$ rrails status
|
58
104
|
|
59
105
|
## See Also
|
60
106
|
|
@@ -62,7 +108,7 @@ So I wrote rrails.
|
|
62
108
|
* rails-sh: https://github.com/jugyo/rails-sh
|
63
109
|
|
64
110
|
## Contributing to rrails
|
65
|
-
|
111
|
+
|
66
112
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
67
113
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
68
114
|
* Fork the project.
|
data/Rakefile
CHANGED
@@ -21,6 +21,7 @@ Jeweler::Tasks.new do |gem|
|
|
21
21
|
gem.description = %Q{remote run rails/rake command}
|
22
22
|
gem.email = "walf443@gmail.com"
|
23
23
|
gem.authors = ["Keiji, Yoshimi"]
|
24
|
+
gem.extra_rdoc_files = %w[Changes.md README.md LICENSE.txt]
|
24
25
|
# dependencies defined in Gemfile
|
25
26
|
end
|
26
27
|
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
data/bin/rrails
CHANGED
@@ -1,6 +1,93 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
|
5
|
+
# goto project root
|
6
|
+
def chdir_to_project_root
|
7
|
+
while not File.exists?('Gemfile') do
|
8
|
+
Dir.chdir('..')
|
9
|
+
break if Dir.pwd == '/'
|
10
|
+
end
|
11
|
+
if not File.exists?('Gemfile')
|
12
|
+
raise RuntimeError.new('Can not locate project root')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# parse options
|
17
|
+
require 'optparse'
|
18
|
+
options = { ondemand: true }
|
19
|
+
opts = OptionParser.new
|
20
|
+
opts.banner =<<'!'
|
21
|
+
Usage: rrails [options] [-- rails_or_rake_cmds]
|
22
|
+
rrails [options] start | stop | restart | reload | status
|
23
|
+
rrails shellrc
|
24
|
+
rrails --help
|
25
|
+
|
26
|
+
Options:
|
27
|
+
!
|
28
|
+
opts.on('-h', '--help', 'Show this document.') {}
|
29
|
+
opts.on('-E', '--rails_env=s', 'Set Rails env.') {|v| options[:rails_env] = v}
|
30
|
+
opts.on('-s', '--socket=s', 'Set RRails server socket file. If this is set, host and port are ignored.') {|v| options[:socket] = v}
|
31
|
+
opts.on('--host=s', 'Set server hostname. Default: localhost.') {|v| options[:host] = v}
|
32
|
+
opts.on('-p', '--port=i', 'Set server port. Default: decided by rails_env.') {|v| options[:port] = v}
|
33
|
+
opts.on('--[no-]ondemand', '(Client) Start RRails server on demand. Default: true.') {|v| options[:ondemand] = v}
|
34
|
+
opts.on('-t', '--[no-]pty', "(Client) Prepare a PTY. Default: decided by commands.") {|v| options[:pty] = v }
|
35
|
+
opts.on('--logfile=s', '(Server) Set log file path. Default: (stderr).') {|v| options[:logfile] = v}
|
36
|
+
opts.on('--pidfile=s', '(Server) Set RRails server pidfile file.') {|v| options[:pidfile] = v}
|
37
|
+
opts.on('-b', '--[no-]background', '(Server) Run in background.') {|v| options[:background] = v}
|
38
|
+
opts.parse!(ARGV)
|
39
|
+
|
40
|
+
# run client or server
|
41
|
+
case ARGV.first
|
42
|
+
when nil, ''
|
43
|
+
# show help
|
44
|
+
STDERR.puts opts
|
45
|
+
when /^s(erver)$/
|
46
|
+
when 'start', 'stop', 'reload', 'restart', 'status'
|
47
|
+
# server
|
48
|
+
chdir_to_project_root
|
49
|
+
require 'rrails/server'
|
50
|
+
RemoteRails::Server.new(options).send(ARGV.first)
|
51
|
+
when /shellrc/
|
52
|
+
# shell rc
|
53
|
+
rc = <<-"!"
|
54
|
+
rrails-exec() {
|
55
|
+
if [ -e config/environment.rb ]; then
|
56
|
+
"#{__FILE__}" -- "$@"
|
57
|
+
else
|
58
|
+
command "$@"
|
59
|
+
fi
|
60
|
+
}
|
61
|
+
alias rrails="#{__FILE__}"
|
62
|
+
alias rails='rrails-exec rails'
|
63
|
+
alias rake='rrails-exec rake'
|
64
|
+
!
|
65
|
+
rc.gsub! /^ /, ''
|
66
|
+
puts rc
|
67
|
+
else
|
68
|
+
chdir_to_project_root
|
69
|
+
|
70
|
+
# check server and start server on demand
|
71
|
+
if options[:ondemand]
|
72
|
+
options[:ondemand_callback] = proc do
|
73
|
+
require 'rrails/server'
|
74
|
+
require 'bundler/setup'
|
75
|
+
options[:background] = true
|
76
|
+
server = RemoteRails::Server.new(options)
|
77
|
+
if not server.alive?
|
78
|
+
puts 'Starting RRails server on demand ...'
|
79
|
+
server.start
|
80
|
+
sleep 1 while not server.alive?
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# start client
|
86
|
+
require 'rrails/client'
|
87
|
+
require 'shellwords'
|
88
|
+
|
89
|
+
options[:cmd] = Shellwords.join(ARGV)
|
90
|
+
exitcode = RemoteRails::Client.new(options).run
|
91
|
+
exit exitcode
|
92
|
+
end
|
93
|
+
|
data/bin/rrails-server
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
ENV["RAILS_ENV"] ||= ARGV.shift
|
4
4
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
5
|
+
warn "-------------------------------------------------------------------------------------------------------------"
|
6
|
+
warn "rrails-server command is obsolate. This command will be deleted in future. Please use 'rrails start' instead."
|
7
|
+
warn "-------------------------------------------------------------------------------------------------------------"
|
5
8
|
require 'rrails'
|
6
9
|
require 'rrails/server'
|
7
10
|
RemoteRails::Server.new.start
|
data/lib/rrails/client.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'rrails'
|
3
|
-
require 'shellwords'
|
4
|
-
require 'optparse'
|
5
3
|
require 'io/console'
|
6
4
|
|
7
5
|
module RemoteRails
|
@@ -17,32 +15,27 @@ module RemoteRails
|
|
17
15
|
# client.run
|
18
16
|
#
|
19
17
|
class Client
|
20
|
-
def self.opts_parser(options = {})
|
21
|
-
opts = OptionParser.new
|
22
|
-
opts.banner = 'Usage: rrails [options] [[--] commands]'
|
23
|
-
opts.on('-h', '--help', 'This help.') {|v| options[:help] = v }
|
24
|
-
opts.on('--host=s', 'RRails server hostname. Default value is "localhost".') {|v| options[:host] = v }
|
25
|
-
opts.on('-E', '--rails_env=s') {|v| options[:rails_env] = v }
|
26
|
-
opts.on('-p', '--port=i', 'RRails server port. Default value is decided from RAILS_ENV.') {|v| options[:port] = v }
|
27
|
-
opts.on('-t', '--[no-]pty', "Prepare a PTY. Default value is decided by commands.") {|v| options[:pty] = v }
|
28
|
-
return opts
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.new_with_options(argv)
|
32
|
-
options = {}
|
33
|
-
opts_parser(options).parse!(argv)
|
34
|
-
|
35
|
-
cmd = Shellwords.join(argv)
|
36
|
-
options[:cmd] = cmd == "" ? nil : cmd
|
37
|
-
self.new(options)
|
38
|
-
end
|
39
|
-
|
40
18
|
def initialize(options={})
|
41
19
|
@cmd = options[:cmd] || ""
|
42
|
-
|
20
|
+
|
43
21
|
@rails_env = options[:rails_env] || ENV['RAILS_ENV'] || 'development'
|
22
|
+
|
23
|
+
@socket = "#{options[:socket] || './tmp/sockets/rrails-'}#{@rails_env}.socket"
|
24
|
+
@host = options[:host] || 'localhost'
|
44
25
|
@port = options[:port] || DEFAULT_PORT[@rails_env]
|
26
|
+
|
45
27
|
@use_pty = options[:pty]
|
28
|
+
@ondemand_callback = options[:ondemand_callback]
|
29
|
+
|
30
|
+
if @cmd.is_a? Array
|
31
|
+
require 'shellwords'
|
32
|
+
@cmd = Shellwords.join(@cmd)
|
33
|
+
end
|
34
|
+
|
35
|
+
if (options[:host] || options[:port]) && (!options[:socket])
|
36
|
+
@socket = nil
|
37
|
+
end
|
38
|
+
|
46
39
|
if @use_pty.nil?
|
47
40
|
# decide use_pty from cmd
|
48
41
|
case @cmd
|
@@ -53,12 +46,16 @@ module RemoteRails
|
|
53
46
|
end
|
54
47
|
|
55
48
|
def run
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
sock = nil
|
50
|
+
begin
|
51
|
+
sock = connect
|
52
|
+
rescue
|
53
|
+
if @ondemand_callback
|
54
|
+
@ondemand_callback.call
|
55
|
+
sock = connect
|
56
|
+
end
|
59
57
|
end
|
60
58
|
|
61
|
-
sock = TCPSocket.open(@host, @port)
|
62
59
|
sock.puts("#{@use_pty ? 'P' : ' '}#@cmd")
|
63
60
|
running = true
|
64
61
|
|
@@ -80,7 +77,7 @@ module RemoteRails
|
|
80
77
|
while running && line = sock.gets
|
81
78
|
case line.chomp
|
82
79
|
when /^EXIT\t(.+)$/
|
83
|
-
|
80
|
+
return $1.to_i
|
84
81
|
when /^OUT\t(.+)$/
|
85
82
|
STDOUT.write($1.split(',').map(&:to_i).pack('c*'))
|
86
83
|
when /^ERR\t(.+)$/
|
@@ -92,12 +89,26 @@ module RemoteRails
|
|
92
89
|
running = false
|
93
90
|
rescue Interrupt
|
94
91
|
running = false
|
95
|
-
|
92
|
+
return 130
|
93
|
+
ensure
|
94
|
+
running = false
|
95
|
+
thread.kill
|
96
96
|
end
|
97
97
|
|
98
|
-
STDERR.puts "\nERROR: RRails server disconnected"
|
99
|
-
|
98
|
+
STDERR.puts "\r\nERROR: RRails server disconnected"
|
99
|
+
return -1
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def connect
|
105
|
+
if @socket
|
106
|
+
UNIXSocket.open(@socket)
|
107
|
+
else
|
108
|
+
TCPSocket.open(@host, @port)
|
109
|
+
end
|
100
110
|
end
|
101
111
|
|
102
112
|
end
|
113
|
+
|
103
114
|
end
|
data/lib/rrails/server.rb
CHANGED
@@ -6,6 +6,8 @@ require 'stringio'
|
|
6
6
|
require 'shellwords'
|
7
7
|
require 'pty'
|
8
8
|
require 'benchmark'
|
9
|
+
require 'fileutils'
|
10
|
+
|
9
11
|
|
10
12
|
# FIXME: rails command require APP_PATH constants.
|
11
13
|
APP_PATH = File.expand_path('./config/application')
|
@@ -20,55 +22,138 @@ module RemoteRails
|
|
20
22
|
PAGE_SIZE = 4096
|
21
23
|
|
22
24
|
def initialize(options={})
|
23
|
-
@rails_env
|
24
|
-
@
|
25
|
-
|
26
|
-
@host
|
27
|
-
@port
|
28
|
-
@
|
25
|
+
@rails_env = options[:rails_env] || ENV['RAILS_ENV'] || "development"
|
26
|
+
@pidfile = "#{options[:pidfile] || './tmp/pids/rrails-'}#{@rails_env}.pid"
|
27
|
+
@background = options[:background] || false
|
28
|
+
@host = options[:host] || 'localhost'
|
29
|
+
@port = options[:port] || DEFAULT_PORT[@rails_env]
|
30
|
+
@socket = "#{options[:socket] || './tmp/sockets/rrails-'}#{@rails_env}.socket"
|
31
|
+
if (options[:host] || options[:port]) && !options[:socket]
|
32
|
+
@socket = nil
|
33
|
+
end
|
34
|
+
@app_path = File.expand_path('./config/application')
|
35
|
+
@logger = Logger.new(options[:logfile] ? options[:logfile] : (@background ? nil : STDERR))
|
36
|
+
end
|
37
|
+
|
38
|
+
def stop
|
39
|
+
pid = previous_instance
|
40
|
+
if pid
|
41
|
+
@logger.info "stopping previous instance #{pid}"
|
42
|
+
Process.kill :TERM, pid
|
43
|
+
FileUtils.rm_f [@socket, @pidfile]
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def restart
|
49
|
+
stop && sleep(1)
|
50
|
+
start
|
51
|
+
end
|
52
|
+
|
53
|
+
def reload
|
54
|
+
pid = previous_instance
|
55
|
+
Process.kill :HUP, pid
|
56
|
+
end
|
57
|
+
|
58
|
+
def alive?
|
59
|
+
previous_instance ? true : false
|
60
|
+
end
|
61
|
+
|
62
|
+
def status
|
63
|
+
pid = previous_instance
|
64
|
+
if pid
|
65
|
+
puts "running \tpid = #{pid}"
|
66
|
+
else
|
67
|
+
puts 'stopped'
|
68
|
+
end
|
29
69
|
end
|
30
70
|
|
31
71
|
def start
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
exit
|
72
|
+
# check previous process
|
73
|
+
raise RuntimeError.new('RRails is already running') if alive?
|
74
|
+
|
75
|
+
if @background
|
76
|
+
pid = Process.fork do
|
77
|
+
@background = false
|
78
|
+
start
|
40
79
|
end
|
80
|
+
Process.detach(pid)
|
81
|
+
return
|
41
82
|
end
|
42
83
|
|
43
|
-
|
44
|
-
|
45
|
-
|
84
|
+
# make 'bundle exec' not necessary for most time.
|
85
|
+
require 'bundler/setup'
|
86
|
+
|
87
|
+
begin
|
88
|
+
[@pidfile, @socket].compact.each do |path|
|
89
|
+
FileUtils.rm_f path
|
90
|
+
FileUtils.mkdir_p File.dirname(path)
|
91
|
+
end
|
92
|
+
|
93
|
+
File.write(@pidfile, $$)
|
94
|
+
server = if @socket
|
95
|
+
UNIXServer.open(@socket)
|
96
|
+
else
|
97
|
+
TCPServer.open(@host, @port)
|
98
|
+
end
|
99
|
+
server.close_on_exec = true
|
100
|
+
|
101
|
+
@logger.info("starting rrails server: #{@socket || "#{@host}:#{@port}"}")
|
102
|
+
|
103
|
+
[:INT, :TERM].each do |sig|
|
104
|
+
trap(sig) do
|
105
|
+
@logger.info("SIG#{sig} recieved. shutdown...")
|
106
|
+
exit
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
trap(:HUP) do
|
111
|
+
@logger.info("SIGHUP recieved. reload...")
|
112
|
+
ActionDispatch::Callbacks.new(Proc.new {}).call({})
|
113
|
+
self.boot_rails
|
114
|
+
end
|
115
|
+
|
46
116
|
self.boot_rails
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
status =
|
117
|
+
|
118
|
+
Thread.abort_on_exception = true
|
119
|
+
|
120
|
+
loop do
|
121
|
+
Thread.start(server.accept) do |s|
|
122
|
+
@logger.debug("accepted")
|
123
|
+
begin
|
124
|
+
line = s.gets.chomp
|
125
|
+
pty, line = (line[0] == 'P'), line[1..-1]
|
126
|
+
@logger.info("invoke: #{line} (pty=#{pty})")
|
127
|
+
status = nil
|
128
|
+
time = Benchmark.realtime do
|
129
|
+
status = dispatch(s, line, pty)
|
130
|
+
end
|
131
|
+
exitcode = status ? status.exitstatus || (status.termsig + 128) : 0
|
132
|
+
s.puts("EXIT\t#{exitcode}")
|
133
|
+
s.flush
|
134
|
+
@logger.info("finished: #{line} (#{time} seconds)")
|
135
|
+
rescue Errno::EPIPE
|
136
|
+
@logger.info("disconnected: #{line}")
|
58
137
|
end
|
59
|
-
exitcode = status ? status.exitstatus || (status.termsig + 128) : 0
|
60
|
-
s.puts("EXIT\t#{exitcode}")
|
61
|
-
@logger.info("finished: #{line} (#{time} seconds)")
|
62
|
-
rescue Errno::EPIPE
|
63
|
-
@logger.info("disconnected: #{line}")
|
64
138
|
end
|
65
139
|
end
|
140
|
+
ensure
|
141
|
+
server.close unless server.closed?
|
142
|
+
@logger.info("cleaning pid and socket files...")
|
143
|
+
FileUtils.rm_f [@socket, @pidfile].compact
|
66
144
|
end
|
67
145
|
end
|
68
146
|
|
69
147
|
def boot_rails
|
70
148
|
@logger.info("prepare rails environment (#{@rails_env})")
|
71
149
|
ENV["RAILS_ENV"] = @rails_env
|
150
|
+
|
151
|
+
# make IRB = Pry hacks (https://gist.github.com/941174) work:
|
152
|
+
# pre-require all irb compoments needed in rails/commands
|
153
|
+
# otherwise 'module IRB' will cause 'IRB is not a module' error.
|
154
|
+
require 'irb'
|
155
|
+
require 'irb/completion'
|
156
|
+
|
72
157
|
require File.expand_path('./config/environment')
|
73
158
|
|
74
159
|
unless Rails.application.config.cache_classes
|
@@ -79,7 +164,6 @@ module RemoteRails
|
|
79
164
|
end
|
80
165
|
|
81
166
|
def dispatch(sock, line, pty=false)
|
82
|
-
|
83
167
|
if pty
|
84
168
|
m_out, c_out = PTY.open
|
85
169
|
c_in = c_err = c_out
|
@@ -96,6 +180,8 @@ module RemoteRails
|
|
96
180
|
end
|
97
181
|
|
98
182
|
running = true
|
183
|
+
heartbeat = 0
|
184
|
+
|
99
185
|
pid = fork do
|
100
186
|
m_fds.map(&:close) if not pty
|
101
187
|
STDIN.reopen(c_in)
|
@@ -143,11 +229,15 @@ module RemoteRails
|
|
143
229
|
end
|
144
230
|
|
145
231
|
# send heartbeat so that we got EPIPE immediately when client dies
|
146
|
-
|
147
|
-
|
232
|
+
heartbeat += 1
|
233
|
+
if heartbeat > 20
|
234
|
+
sock.puts("PING")
|
235
|
+
sock.flush
|
236
|
+
heartbeat = 0
|
237
|
+
end
|
148
238
|
|
149
239
|
# do not make CPU hot
|
150
|
-
sleep 0.
|
240
|
+
sleep 0.025
|
151
241
|
end
|
152
242
|
ensure
|
153
243
|
running = false
|
@@ -163,24 +253,36 @@ module RemoteRails
|
|
163
253
|
thread.kill if thread
|
164
254
|
end
|
165
255
|
|
256
|
+
private
|
257
|
+
|
166
258
|
def execute(cmd, *args)
|
167
259
|
ARGV.clear
|
168
260
|
ARGV.concat(args)
|
261
|
+
$0 = cmd
|
169
262
|
case cmd
|
170
263
|
when 'rails'
|
171
264
|
require 'rails/commands'
|
172
265
|
when 'rake'
|
266
|
+
# full path of rake
|
267
|
+
$0 = Gem.bin_path('rake')
|
173
268
|
::Rake.application.run
|
174
|
-
when 'pry'
|
175
|
-
begin
|
176
|
-
::Pry::CLI.parse_options
|
177
|
-
rescue NameError
|
178
|
-
STDERR.puts "if you want to use pry. you should add 'pry' to Gemfile."
|
179
|
-
end
|
180
269
|
else
|
181
270
|
STDERR.puts "#{cmd} is not supported in RRails."
|
182
271
|
end
|
183
272
|
end
|
184
273
|
|
274
|
+
def previous_instance
|
275
|
+
begin
|
276
|
+
previous_pid = File.read(@pidfile).to_i
|
277
|
+
|
278
|
+
if previous_pid > 0 && Process.kill(0, previous_pid)
|
279
|
+
return previous_pid
|
280
|
+
end
|
281
|
+
return false
|
282
|
+
rescue Errno::ESRCH, Errno::ENOENT
|
283
|
+
return false
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
185
287
|
end
|
186
288
|
end
|
data/rrails.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "rrails"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "1.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Keiji, Yoshimi"]
|
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.email = "walf443@gmail.com"
|
15
15
|
s.executables = ["rrails", "rrails-server"]
|
16
16
|
s.extra_rdoc_files = [
|
17
|
+
"Changes.md",
|
17
18
|
"LICENSE.txt",
|
18
19
|
"README.md"
|
19
20
|
]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rrails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -98,6 +98,7 @@ executables:
|
|
98
98
|
- rrails-server
|
99
99
|
extensions: []
|
100
100
|
extra_rdoc_files:
|
101
|
+
- Changes.md
|
101
102
|
- LICENSE.txt
|
102
103
|
- README.md
|
103
104
|
files:
|
@@ -132,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
133
|
version: '0'
|
133
134
|
segments:
|
134
135
|
- 0
|
135
|
-
hash:
|
136
|
+
hash: 4515075186478304892
|
136
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
138
|
none: false
|
138
139
|
requirements:
|