spring 1.0.0 → 1.3.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +6 -1
- data/CHANGELOG.md +81 -0
- data/CONTRIBUTING.md +52 -0
- data/Gemfile +0 -2
- data/README.md +137 -54
- data/Rakefile +1 -1
- data/bin/spring +17 -0
- data/lib/spring/application/boot.rb +18 -0
- data/lib/spring/application.rb +183 -76
- data/lib/spring/application_manager.rb +54 -40
- data/lib/spring/binstub.rb +13 -0
- data/lib/spring/boot.rb +8 -0
- data/lib/spring/client/binstub.rb +150 -39
- data/lib/spring/client/help.rb +4 -12
- data/lib/spring/client/rails.rb +2 -3
- data/lib/spring/client/run.rb +69 -11
- data/lib/spring/client/status.rb +2 -2
- data/lib/spring/client/stop.rb +6 -21
- data/lib/spring/client/version.rb +11 -0
- data/lib/spring/client.rb +8 -5
- data/lib/spring/command_wrapper.rb +82 -0
- data/lib/spring/commands/rails.rb +44 -13
- data/lib/spring/commands/rake.rb +0 -4
- data/lib/spring/commands.rb +14 -4
- data/lib/spring/configuration.rb +11 -2
- data/lib/spring/env.rb +36 -10
- data/lib/spring/server.rb +9 -35
- data/lib/spring/sid.rb +1 -1
- data/lib/spring/test/acceptance_test.rb +346 -0
- data/lib/spring/test/application.rb +217 -0
- data/lib/spring/test/application_generator.rb +121 -0
- data/lib/spring/test/rails_version.rb +40 -0
- data/lib/spring/test/watcher_test.rb +167 -0
- data/lib/spring/test.rb +18 -0
- data/lib/spring/version.rb +1 -1
- data/lib/spring/watcher/abstract.rb +7 -8
- data/lib/spring/watcher/polling.rb +2 -0
- data/lib/spring/watcher.rb +4 -8
- data/spring.gemspec +2 -2
- data/test/acceptance_test.rb +4 -0
- data/test/helper.rb +2 -2
- data/test/unit/client/version_test.rb +14 -0
- data/test/unit/commands_test.rb +23 -1
- data/test/unit/watcher_test.rb +2 -184
- metadata +30 -17
- data/lib/spring/watcher/listen.rb +0 -52
- data/test/acceptance/app_test.rb +0 -511
|
@@ -1,46 +1,164 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
1
3
|
module Spring
|
|
2
4
|
module Client
|
|
3
5
|
class Binstub < Command
|
|
4
|
-
|
|
6
|
+
SHEBANG = /\#\!.*\n/
|
|
7
|
+
|
|
8
|
+
# If loading the bin/spring file works, it'll run spring which will
|
|
9
|
+
# eventually call Kernel.exit. This means that in the client process
|
|
10
|
+
# we will never execute the lines after this block. But if the spring
|
|
11
|
+
# client is not invoked for whatever reason, then the Kernel.exit won't
|
|
12
|
+
# happen, and so we'll fall back to the lines after this block, which
|
|
13
|
+
# should cause the "unsprung" version of the command to run.
|
|
14
|
+
LOADER = <<CODE
|
|
15
|
+
begin
|
|
16
|
+
load File.expand_path("../spring", __FILE__)
|
|
17
|
+
rescue LoadError
|
|
18
|
+
end
|
|
19
|
+
CODE
|
|
20
|
+
|
|
21
|
+
# The defined? check ensures these lines don't execute when we load the
|
|
22
|
+
# binstub from the application process. Which means that in the application
|
|
23
|
+
# process we'll execute the lines which come after the LOADER block, which
|
|
24
|
+
# is what we want.
|
|
25
|
+
#
|
|
26
|
+
# Parsing the lockfile in this way is pretty nasty but reliable enough
|
|
27
|
+
# The regex ensures that the match must be between a GEM line and an empty
|
|
28
|
+
# line, so it won't go on to the next section.
|
|
29
|
+
SPRING = <<'CODE'
|
|
30
|
+
#!/usr/bin/env ruby
|
|
31
|
+
|
|
32
|
+
# This file loads spring without using Bundler, in order to be fast
|
|
33
|
+
# It gets overwritten when you run the `spring binstub` command
|
|
34
|
+
|
|
35
|
+
unless defined?(Spring)
|
|
36
|
+
require "rubygems"
|
|
37
|
+
require "bundler"
|
|
38
|
+
|
|
39
|
+
if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)
|
|
40
|
+
ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR)
|
|
41
|
+
ENV["GEM_HOME"] = nil
|
|
42
|
+
Gem.paths = ENV
|
|
43
|
+
|
|
44
|
+
gem "spring", match[1]
|
|
45
|
+
require "spring/binstub"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
CODE
|
|
49
|
+
|
|
50
|
+
OLD_BINSTUB = %{if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?}
|
|
51
|
+
|
|
52
|
+
class Item
|
|
53
|
+
attr_reader :command, :existing
|
|
54
|
+
|
|
55
|
+
def initialize(command)
|
|
56
|
+
@command = command
|
|
57
|
+
|
|
58
|
+
if command.binstub.exist?
|
|
59
|
+
@existing = command.binstub.read
|
|
60
|
+
elsif command.name == "rails"
|
|
61
|
+
scriptfile = Spring.application_root_path.join("script/rails")
|
|
62
|
+
@existing = scriptfile.read if scriptfile.exist?
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def status(text, stream = $stdout)
|
|
67
|
+
stream.puts "* #{command.binstub_name}: #{text}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def add
|
|
71
|
+
if existing
|
|
72
|
+
if existing.include?(OLD_BINSTUB)
|
|
73
|
+
fallback = existing.match(/#{Regexp.escape OLD_BINSTUB}\n(.*)else/m)[1]
|
|
74
|
+
fallback.gsub!(/^ /, "")
|
|
75
|
+
fallback = nil if fallback.include?("exec")
|
|
76
|
+
generate(fallback)
|
|
77
|
+
status "upgraded"
|
|
78
|
+
elsif existing =~ /load .*spring/
|
|
79
|
+
status "spring already present"
|
|
80
|
+
else
|
|
81
|
+
head, shebang, tail = existing.partition(SHEBANG)
|
|
82
|
+
|
|
83
|
+
if shebang.include?("ruby")
|
|
84
|
+
unless command.binstub.exist?
|
|
85
|
+
FileUtils.touch command.binstub
|
|
86
|
+
command.binstub.chmod 0755
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
File.write(command.binstub, "#{head}#{shebang}#{LOADER}#{tail}")
|
|
90
|
+
status "spring inserted"
|
|
91
|
+
else
|
|
92
|
+
status "doesn't appear to be ruby, so cannot use spring", $stderr
|
|
93
|
+
exit 1
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
else
|
|
97
|
+
generate
|
|
98
|
+
status "generated with spring"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def generate(fallback = nil)
|
|
103
|
+
unless fallback
|
|
104
|
+
fallback = "require 'bundler/setup'\n" \
|
|
105
|
+
"load Gem.bin_path('#{command.gem_name}', '#{command.exec_name}')\n"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
File.write(command.binstub, "#!/usr/bin/env ruby\n#{LOADER}#{fallback}")
|
|
109
|
+
command.binstub.chmod 0755
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def remove
|
|
113
|
+
if existing
|
|
114
|
+
File.write(command.binstub, existing.sub(LOADER, ""))
|
|
115
|
+
status "spring removed"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
attr_reader :bindir, :items
|
|
5
121
|
|
|
6
122
|
def self.description
|
|
7
123
|
"Generate spring based binstubs. Use --all to generate a binstub for all known commands."
|
|
8
124
|
end
|
|
9
125
|
|
|
126
|
+
def self.rails_command
|
|
127
|
+
@rails_command ||= CommandWrapper.new("rails")
|
|
128
|
+
end
|
|
129
|
+
|
|
10
130
|
def self.call(args)
|
|
11
131
|
require "spring/commands"
|
|
12
132
|
super
|
|
13
133
|
end
|
|
14
134
|
|
|
15
|
-
class RailsCommand
|
|
16
|
-
def fallback
|
|
17
|
-
<<CODE
|
|
18
|
-
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
19
|
-
require_relative '../config/boot'
|
|
20
|
-
require 'rails/commands'
|
|
21
|
-
CODE
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
135
|
def initialize(args)
|
|
26
136
|
super
|
|
27
137
|
|
|
28
|
-
@bindir
|
|
29
|
-
@
|
|
138
|
+
@bindir = env.root.join("bin")
|
|
139
|
+
@all = false
|
|
140
|
+
@mode = :add
|
|
141
|
+
@items = args.drop(1)
|
|
142
|
+
.map { |name| find_commands name }
|
|
143
|
+
.inject(Set.new, :|)
|
|
144
|
+
.map { |command| Item.new(command) }
|
|
30
145
|
end
|
|
31
146
|
|
|
32
147
|
def find_commands(name)
|
|
33
148
|
case name
|
|
34
149
|
when "--all"
|
|
35
|
-
|
|
150
|
+
@all = true
|
|
151
|
+
commands = Spring.commands.dup
|
|
36
152
|
commands.delete_if { |name, _| name.start_with?("rails_") }
|
|
37
|
-
commands
|
|
38
|
-
|
|
153
|
+
commands.values + [self.class.rails_command]
|
|
154
|
+
when "--remove"
|
|
155
|
+
@mode = :remove
|
|
156
|
+
[]
|
|
39
157
|
when "rails"
|
|
40
|
-
|
|
158
|
+
[self.class.rails_command]
|
|
41
159
|
else
|
|
42
160
|
if command = Spring.commands[name]
|
|
43
|
-
|
|
161
|
+
[command]
|
|
44
162
|
else
|
|
45
163
|
$stderr.puts "The '#{name}' command is not known to spring."
|
|
46
164
|
exit 1
|
|
@@ -49,32 +167,25 @@ CODE
|
|
|
49
167
|
end
|
|
50
168
|
|
|
51
169
|
def call
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def generate_binstub(name, command)
|
|
57
|
-
File.write(bindir.join(name), <<CODE)
|
|
58
|
-
#!/usr/bin/env ruby
|
|
170
|
+
case @mode
|
|
171
|
+
when :add
|
|
172
|
+
bindir.mkdir unless bindir.exist?
|
|
59
173
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
else
|
|
63
|
-
ARGV.unshift "#{name}"
|
|
64
|
-
load Gem.bin_path("spring", "spring")
|
|
65
|
-
end
|
|
66
|
-
CODE
|
|
67
|
-
|
|
68
|
-
bindir.join(name).chmod 0755
|
|
69
|
-
end
|
|
174
|
+
File.write(spring_binstub, SPRING)
|
|
175
|
+
spring_binstub.chmod 0755
|
|
70
176
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
177
|
+
items.each(&:add)
|
|
178
|
+
when :remove
|
|
179
|
+
spring_binstub.delete if @all
|
|
180
|
+
items.each(&:remove)
|
|
74
181
|
else
|
|
75
|
-
|
|
182
|
+
raise ArgumentError
|
|
76
183
|
end
|
|
77
184
|
end
|
|
185
|
+
|
|
186
|
+
def spring_binstub
|
|
187
|
+
bindir.join("spring")
|
|
188
|
+
end
|
|
78
189
|
end
|
|
79
190
|
end
|
|
80
191
|
end
|
data/lib/spring/client/help.rb
CHANGED
|
@@ -20,6 +20,8 @@ module Spring
|
|
|
20
20
|
@spring_commands = spring_commands || Spring::Client::COMMANDS.dup
|
|
21
21
|
@application_commands = application_commands || Spring.commands.dup
|
|
22
22
|
|
|
23
|
+
@spring_commands.delete_if { |k, v| k.start_with?("-") }
|
|
24
|
+
|
|
23
25
|
@application_commands["rails"] = @spring_commands.delete("rails")
|
|
24
26
|
end
|
|
25
27
|
|
|
@@ -46,19 +48,9 @@ module Spring
|
|
|
46
48
|
spring_commands.merge application_commands
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
def description_for_command(command)
|
|
50
|
-
if command.respond_to?(:description)
|
|
51
|
-
command.description
|
|
52
|
-
elsif command.respond_to?(:exec_name)
|
|
53
|
-
"Runs the #{command.exec_name} command"
|
|
54
|
-
else
|
|
55
|
-
"No description given."
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
51
|
def display(name, command)
|
|
60
|
-
if description
|
|
61
|
-
" #{name.ljust(max_name_width)} #{description}"
|
|
52
|
+
if command.description
|
|
53
|
+
" #{name.ljust(max_name_width)} #{command.description}"
|
|
62
54
|
end
|
|
63
55
|
end
|
|
64
56
|
|
data/lib/spring/client/rails.rb
CHANGED
|
@@ -24,9 +24,8 @@ module Spring
|
|
|
24
24
|
else
|
|
25
25
|
require "spring/configuration"
|
|
26
26
|
ARGV.shift
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
require "rails/commands"
|
|
27
|
+
load Dir.glob(Spring.application_root_path.join("{bin,script}/rails")).first
|
|
28
|
+
exit
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
end
|
data/lib/spring/client/run.rb
CHANGED
|
@@ -5,6 +5,12 @@ module Spring
|
|
|
5
5
|
module Client
|
|
6
6
|
class Run < Command
|
|
7
7
|
FORWARDED_SIGNALS = %w(INT QUIT USR1 USR2 INFO) & Signal.list.keys
|
|
8
|
+
TIMEOUT = 1
|
|
9
|
+
|
|
10
|
+
def initialize(args)
|
|
11
|
+
super
|
|
12
|
+
@signal_queue = []
|
|
13
|
+
end
|
|
8
14
|
|
|
9
15
|
def log(message)
|
|
10
16
|
env.log "[client] #{message}"
|
|
@@ -15,26 +21,54 @@ module Spring
|
|
|
15
21
|
end
|
|
16
22
|
|
|
17
23
|
def call
|
|
18
|
-
|
|
24
|
+
if env.server_running?
|
|
25
|
+
warm_run
|
|
26
|
+
else
|
|
27
|
+
cold_run
|
|
28
|
+
end
|
|
29
|
+
rescue Errno::ECONNRESET
|
|
30
|
+
exit 1
|
|
31
|
+
ensure
|
|
32
|
+
server.close if @server
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def warm_run
|
|
36
|
+
run
|
|
37
|
+
rescue CommandNotFound
|
|
38
|
+
require "spring/commands"
|
|
39
|
+
|
|
40
|
+
if Spring.command?(args.first)
|
|
41
|
+
# Command installed since spring started
|
|
42
|
+
stop_server
|
|
43
|
+
cold_run
|
|
44
|
+
else
|
|
45
|
+
raise
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def cold_run
|
|
50
|
+
boot_server
|
|
51
|
+
run
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def run
|
|
19
55
|
verify_server_version
|
|
20
56
|
|
|
21
57
|
application, client = UNIXSocket.pair
|
|
22
58
|
|
|
59
|
+
queue_signals
|
|
23
60
|
connect_to_application(client)
|
|
24
61
|
run_command(client, application)
|
|
25
|
-
rescue Errno::ECONNRESET
|
|
26
|
-
exit 1
|
|
27
|
-
ensure
|
|
28
|
-
server.close if @server
|
|
29
62
|
end
|
|
30
63
|
|
|
31
64
|
def boot_server
|
|
32
65
|
env.socket_path.unlink if env.socket_path.exist?
|
|
33
66
|
|
|
34
|
-
pid =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
67
|
+
pid = Process.spawn(
|
|
68
|
+
"ruby",
|
|
69
|
+
"-r", "spring/server",
|
|
70
|
+
"-e", "Spring::Server.boot"
|
|
71
|
+
)
|
|
38
72
|
|
|
39
73
|
until env.socket_path.exist?
|
|
40
74
|
_, status = Process.waitpid2(pid, Process::WNOHANG)
|
|
@@ -43,6 +77,12 @@ module Spring
|
|
|
43
77
|
end
|
|
44
78
|
end
|
|
45
79
|
|
|
80
|
+
def stop_server
|
|
81
|
+
server.close
|
|
82
|
+
@server = nil
|
|
83
|
+
env.stop
|
|
84
|
+
end
|
|
85
|
+
|
|
46
86
|
def verify_server_version
|
|
47
87
|
server_version = server.gets.chomp
|
|
48
88
|
if server_version != env.version
|
|
@@ -59,7 +99,12 @@ ERROR
|
|
|
59
99
|
def connect_to_application(client)
|
|
60
100
|
server.send_io client
|
|
61
101
|
send_json server, "args" => args, "default_rails_env" => default_rails_env
|
|
62
|
-
|
|
102
|
+
|
|
103
|
+
if IO.select([server], [], [], TIMEOUT)
|
|
104
|
+
server.gets or raise CommandNotFound
|
|
105
|
+
else
|
|
106
|
+
raise "Error connecting to Spring server"
|
|
107
|
+
end
|
|
63
108
|
end
|
|
64
109
|
|
|
65
110
|
def run_command(client, application)
|
|
@@ -96,14 +141,23 @@ ERROR
|
|
|
96
141
|
application.close
|
|
97
142
|
end
|
|
98
143
|
|
|
144
|
+
def queue_signals
|
|
145
|
+
FORWARDED_SIGNALS.each do |sig|
|
|
146
|
+
trap(sig) { @signal_queue << sig }
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
99
150
|
def forward_signals(pid)
|
|
151
|
+
@signal_queue.each { |sig| kill sig, pid }
|
|
152
|
+
|
|
100
153
|
FORWARDED_SIGNALS.each do |sig|
|
|
101
154
|
trap(sig) { forward_signal sig, pid }
|
|
102
155
|
end
|
|
156
|
+
rescue Errno::ESRCH
|
|
103
157
|
end
|
|
104
158
|
|
|
105
159
|
def forward_signal(sig, pid)
|
|
106
|
-
|
|
160
|
+
kill(sig, pid)
|
|
107
161
|
rescue Errno::ESRCH
|
|
108
162
|
# If the application process is gone, then don't block the
|
|
109
163
|
# signal on this process.
|
|
@@ -111,6 +165,10 @@ ERROR
|
|
|
111
165
|
Process.kill(sig, Process.pid)
|
|
112
166
|
end
|
|
113
167
|
|
|
168
|
+
def kill(sig, pid)
|
|
169
|
+
Process.kill(sig, -Process.getpgid(pid))
|
|
170
|
+
end
|
|
171
|
+
|
|
114
172
|
def send_json(socket, data)
|
|
115
173
|
data = JSON.dump(data)
|
|
116
174
|
|
data/lib/spring/client/status.rb
CHANGED
|
@@ -17,11 +17,11 @@ module Spring
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def print_process(pid)
|
|
20
|
-
puts `ps -p #{pid} -o pid= -o
|
|
20
|
+
puts `ps -p #{pid} -o pid= -o command=`
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def application_pids
|
|
24
|
-
candidates = `ps -
|
|
24
|
+
candidates = `ps -ax -o ppid= -o pid=`.lines
|
|
25
25
|
candidates.select { |l| l =~ /^(\s+)?#{env.pid} / }
|
|
26
26
|
.map { |l| l.split(" ").last }
|
|
27
27
|
end
|
data/lib/spring/client/stop.rb
CHANGED
|
@@ -3,35 +3,20 @@ require "spring/version"
|
|
|
3
3
|
module Spring
|
|
4
4
|
module Client
|
|
5
5
|
class Stop < Command
|
|
6
|
-
TIMEOUT = 2 # seconds
|
|
7
|
-
|
|
8
6
|
def self.description
|
|
9
7
|
"Stop all spring processes for this project."
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
def call
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
$stderr.puts "Spring did not stop; killing forcibly."
|
|
20
|
-
kill 'KILL'
|
|
21
|
-
else
|
|
22
|
-
puts "Spring stopped."
|
|
23
|
-
end
|
|
24
|
-
else
|
|
11
|
+
case env.stop
|
|
12
|
+
when :stopped
|
|
13
|
+
puts "Spring stopped."
|
|
14
|
+
when :killed
|
|
15
|
+
$stderr.puts "Spring did not stop; killing forcibly."
|
|
16
|
+
when :not_running
|
|
25
17
|
puts "Spring is not running"
|
|
26
18
|
end
|
|
27
19
|
end
|
|
28
|
-
|
|
29
|
-
def kill(sig)
|
|
30
|
-
pid = env.pid
|
|
31
|
-
Process.kill(sig, pid) if pid
|
|
32
|
-
rescue Errno::ESRCH
|
|
33
|
-
# already dead
|
|
34
|
-
end
|
|
35
20
|
end
|
|
36
21
|
end
|
|
37
22
|
end
|
data/lib/spring/client.rb
CHANGED
|
@@ -8,15 +8,18 @@ require "spring/client/binstub"
|
|
|
8
8
|
require "spring/client/stop"
|
|
9
9
|
require "spring/client/status"
|
|
10
10
|
require "spring/client/rails"
|
|
11
|
+
require "spring/client/version"
|
|
11
12
|
|
|
12
13
|
module Spring
|
|
13
14
|
module Client
|
|
14
15
|
COMMANDS = {
|
|
15
|
-
"help"
|
|
16
|
-
"binstub"
|
|
17
|
-
"stop"
|
|
18
|
-
"status"
|
|
19
|
-
"rails"
|
|
16
|
+
"help" => Client::Help,
|
|
17
|
+
"binstub" => Client::Binstub,
|
|
18
|
+
"stop" => Client::Stop,
|
|
19
|
+
"status" => Client::Status,
|
|
20
|
+
"rails" => Client::Rails,
|
|
21
|
+
"-v" => Client::Version,
|
|
22
|
+
"--version" => Client::Version
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
def self.run(args)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require "spring/configuration"
|
|
2
|
+
|
|
3
|
+
module Spring
|
|
4
|
+
class CommandWrapper
|
|
5
|
+
attr_reader :name, :command
|
|
6
|
+
|
|
7
|
+
def initialize(name, command = nil)
|
|
8
|
+
@name = name
|
|
9
|
+
@command = command
|
|
10
|
+
@setup = false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def description
|
|
14
|
+
if command.respond_to?(:description)
|
|
15
|
+
command.description
|
|
16
|
+
else
|
|
17
|
+
"Runs the #{name} command"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def setup?
|
|
22
|
+
@setup
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def setup
|
|
26
|
+
if !setup? && command.respond_to?(:setup)
|
|
27
|
+
command.setup
|
|
28
|
+
@setup = true
|
|
29
|
+
return true
|
|
30
|
+
else
|
|
31
|
+
@setup = true
|
|
32
|
+
return false
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def call
|
|
37
|
+
if command.respond_to?(:call)
|
|
38
|
+
command.call
|
|
39
|
+
else
|
|
40
|
+
load exec
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def gem_name
|
|
45
|
+
if command.respond_to?(:gem_name)
|
|
46
|
+
command.gem_name
|
|
47
|
+
else
|
|
48
|
+
exec_name
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def exec_name
|
|
53
|
+
if command.respond_to?(:exec_name)
|
|
54
|
+
command.exec_name
|
|
55
|
+
else
|
|
56
|
+
name
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def binstub
|
|
61
|
+
Spring.application_root_path.join(binstub_name)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def binstub_name
|
|
65
|
+
"bin/#{name}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def exec
|
|
69
|
+
if binstub.exist?
|
|
70
|
+
binstub.to_s
|
|
71
|
+
else
|
|
72
|
+
Gem.bin_path(gem_name, exec_name)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def env(args)
|
|
77
|
+
if command.respond_to?(:env)
|
|
78
|
+
command.env(args)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -3,8 +3,7 @@ module Spring
|
|
|
3
3
|
class Rails
|
|
4
4
|
def call
|
|
5
5
|
ARGV.unshift command_name
|
|
6
|
-
|
|
7
|
-
require "rails/commands"
|
|
6
|
+
load Dir.glob(::Rails.root.join("{bin,script}/rails")).first
|
|
8
7
|
end
|
|
9
8
|
|
|
10
9
|
def description
|
|
@@ -14,7 +13,19 @@ module Spring
|
|
|
14
13
|
|
|
15
14
|
class RailsConsole < Rails
|
|
16
15
|
def env(args)
|
|
17
|
-
args.first if args.first && !args.first.index("-")
|
|
16
|
+
return args.first if args.first && !args.first.index("-")
|
|
17
|
+
|
|
18
|
+
environment = nil
|
|
19
|
+
|
|
20
|
+
args.each.with_index do |arg, i|
|
|
21
|
+
if arg =~ /--environment=(\w+)/
|
|
22
|
+
environment = $1
|
|
23
|
+
elsif i > 0 && args[i - 1] == "-e"
|
|
24
|
+
environment = arg
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
environment
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
def command_name
|
|
@@ -35,21 +46,41 @@ module Spring
|
|
|
35
46
|
end
|
|
36
47
|
|
|
37
48
|
class RailsRunner < Rails
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
previous_option = option
|
|
46
|
-
end
|
|
47
|
-
nil
|
|
49
|
+
def call
|
|
50
|
+
ARGV.replace extract_environment(ARGV).first
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def env(args)
|
|
55
|
+
extract_environment(args).last
|
|
48
56
|
end
|
|
49
57
|
|
|
50
58
|
def command_name
|
|
51
59
|
"runner"
|
|
52
60
|
end
|
|
61
|
+
|
|
62
|
+
def extract_environment(args)
|
|
63
|
+
environment = nil
|
|
64
|
+
|
|
65
|
+
args = args.select.with_index { |arg, i|
|
|
66
|
+
case arg
|
|
67
|
+
when "-e"
|
|
68
|
+
false
|
|
69
|
+
when /--environment=(\w+)/
|
|
70
|
+
environment = $1
|
|
71
|
+
false
|
|
72
|
+
else
|
|
73
|
+
if i > 0 && args[i - 1] == "-e"
|
|
74
|
+
environment = arg
|
|
75
|
+
false
|
|
76
|
+
else
|
|
77
|
+
true
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[args, environment]
|
|
83
|
+
end
|
|
53
84
|
end
|
|
54
85
|
|
|
55
86
|
Spring.register_command "rails_console", RailsConsole.new
|