duoconsole 0.1.0
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/bin/duoconsole +12 -0
- data/lib/duoconsole.rb +162 -0
- metadata +81 -0
data/bin/duoconsole
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
APP_PATH = File.join(Dir.pwd, 'config', 'application')
|
4
|
+
|
5
|
+
begin
|
6
|
+
require File.join(Dir.pwd, 'config', 'boot')
|
7
|
+
rescue LoadError
|
8
|
+
abort "Duoconsole must be run from the root directory of a Rails project."
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'duoconsole'
|
12
|
+
Duoconsole.start
|
data/lib/duoconsole.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
class Duoconsole
|
4
|
+
|
5
|
+
def self.start
|
6
|
+
new.start
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :child_socket, :parent_socket
|
10
|
+
|
11
|
+
def start
|
12
|
+
preload_gems
|
13
|
+
create_socket_pair
|
14
|
+
fork_child
|
15
|
+
load_application
|
16
|
+
initialize_command_client
|
17
|
+
start_console
|
18
|
+
end
|
19
|
+
|
20
|
+
def preload_gems
|
21
|
+
require 'rails/all'
|
22
|
+
|
23
|
+
if defined?(Bundler)
|
24
|
+
Bundler.require(:default, :assets)
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'commands'
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_socket_pair
|
31
|
+
self.child_socket, self.parent_socket = Socket.pair(:UNIX, :DGRAM, 0)
|
32
|
+
end
|
33
|
+
|
34
|
+
def fork_child
|
35
|
+
child_pid = fork do
|
36
|
+
ENV['RAILS_ENV'] = 'test'
|
37
|
+
|
38
|
+
if defined?(Rails)
|
39
|
+
Rails.env = 'test'
|
40
|
+
end
|
41
|
+
|
42
|
+
load_application
|
43
|
+
monkeypatch_test_environment
|
44
|
+
|
45
|
+
trap(:INT) {
|
46
|
+
# Ignore. This process needs to stay alive until the parent process exits
|
47
|
+
}
|
48
|
+
|
49
|
+
CommandServer.new(child_socket).start
|
50
|
+
end
|
51
|
+
|
52
|
+
# cleanup before exiting
|
53
|
+
at_exit {
|
54
|
+
Process.kill(:QUIT, child_pid)
|
55
|
+
parent_socket.close
|
56
|
+
child_socket.close
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_application
|
61
|
+
require APP_PATH
|
62
|
+
Rails.application.require_environment!
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize_command_client
|
66
|
+
ConsoleDelegation.command_client = CommandClient.new(parent_socket)
|
67
|
+
end
|
68
|
+
|
69
|
+
def start_console
|
70
|
+
require 'rails/commands/console'
|
71
|
+
require 'rails/console/app'
|
72
|
+
Rails::ConsoleMethods.send :include, ConsoleDelegation
|
73
|
+
Rails::Console.start(Rails.application)
|
74
|
+
end
|
75
|
+
|
76
|
+
def monkeypatch_test_environment
|
77
|
+
Rails::Commands::TestEnvironment.module_eval do
|
78
|
+
# Overriding this method to add the following behavior:
|
79
|
+
# 1. fix issue with Postgres adapter and forking behavior
|
80
|
+
# 2. trap INT signal and exit
|
81
|
+
def fork
|
82
|
+
ActiveRecord::Base.clear_active_connections!
|
83
|
+
Rails::Commands::Environment.fork do
|
84
|
+
setup_for_test
|
85
|
+
trap(:INT) { exit(1) }
|
86
|
+
|
87
|
+
yield
|
88
|
+
ActiveRecord::Base.clear_active_connections!
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
class CommandClient
|
96
|
+
attr_reader :socket
|
97
|
+
|
98
|
+
def initialize socket
|
99
|
+
@socket = socket
|
100
|
+
end
|
101
|
+
|
102
|
+
def send msg
|
103
|
+
socket.write(msg)
|
104
|
+
socket.recv(1000)
|
105
|
+
end
|
106
|
+
|
107
|
+
def method_missing(m, *args, &block)
|
108
|
+
send "#{m} #{args.join(' ')}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
class CommandServer
|
114
|
+
attr_reader :socket
|
115
|
+
|
116
|
+
def initialize socket
|
117
|
+
@socket = socket
|
118
|
+
end
|
119
|
+
|
120
|
+
def start
|
121
|
+
loop do
|
122
|
+
msg = socket.recv(1000)
|
123
|
+
command, args = get_command_and_args msg
|
124
|
+
|
125
|
+
retval = if commander.respond_to?(command)
|
126
|
+
commander.send(command, args)
|
127
|
+
else
|
128
|
+
'Unrecognized command'
|
129
|
+
end
|
130
|
+
|
131
|
+
socket.write(retval)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_command_and_args msg
|
136
|
+
parts = msg.split(' ')
|
137
|
+
command = parts.shift
|
138
|
+
args = parts.join(' ')
|
139
|
+
args = nil unless args.match(/\S/)
|
140
|
+
[command, args]
|
141
|
+
end
|
142
|
+
|
143
|
+
def commander
|
144
|
+
@commander ||= Rails::Commands::Commander.new
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
module ConsoleDelegation
|
150
|
+
def self.command_client= client
|
151
|
+
@@command_client = client
|
152
|
+
end
|
153
|
+
|
154
|
+
def testenv
|
155
|
+
@@command_client
|
156
|
+
end
|
157
|
+
|
158
|
+
def test *args
|
159
|
+
testenv.test *args
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: duoconsole
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Geoff Buesing
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: commands
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.2.1
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.2.1
|
46
|
+
description:
|
47
|
+
email: gbuesing@gmail.com
|
48
|
+
executables:
|
49
|
+
- duoconsole
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/duoconsole.rb
|
54
|
+
- bin/duoconsole
|
55
|
+
homepage: https://github.com/gbuesing/duoconsole
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.8.23
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Launch Rails development console with test environment as a child process
|
80
|
+
test_files: []
|
81
|
+
has_rdoc:
|