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.
Files changed (3) hide show
  1. data/bin/duoconsole +12 -0
  2. data/lib/duoconsole.rb +162 -0
  3. 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: