spring 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4095a71b95759b8a4ed6a71b5ddcb5048aad506
4
- data.tar.gz: 360837121b6655c0abc8fb88f28ce6b62f46a88e
3
+ metadata.gz: 6828395a6b2b9a2d02ec15c9baba9305f36dbec9
4
+ data.tar.gz: 62af73ac2056ca5a62ed440c0e9220f115c82830
5
5
  SHA512:
6
- metadata.gz: 255ec2bc4edd38b0c1d609e16b8cc6d7d9f8bccdddff14e482f98202260e1dae3f7d766a56b47cb846973c443e45b67bac0ae1c8c3c830c9c9c0ed64486c6025
7
- data.tar.gz: 3181e4b656a12b4094742647f6b7fe260d6f3f5acb0642bc39bfbfb83389a174a7434fa6ab355723a169cb2a2441793f02f46aa618a9ec87d7f9eccb9611ee71
6
+ metadata.gz: 73d982d8d66de05071338ea45fd59b042c5f05a5cb2eb32a10143777e0ec8e120a8b0ecd6d02e18570ee8515b4c18079dc67f12a74c5523f5f6586e93ba3b54c
7
+ data.tar.gz: 54cc11c7135f91337199ee65d4062516ceec762c87f943bdb823b58b646e10d16d48cc5248b33cabcf68b517319fb7397c469e1d3ce3f75a378152cca30256db
@@ -2,10 +2,10 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
- - 2.1.0
5
+ - 2.1.2
6
6
  env:
7
7
  - RAILS_VERSION="~> 3.2.0"
8
8
  - RAILS_VERSION="~> 4.0.0"
9
- - RAILS_VERSION="~> 4.1.0.rc1"
9
+ - RAILS_VERSION="~> 4.1.0"
10
10
  before_script:
11
11
  - travis_retry gem install rails --version "$RAILS_VERSION"
@@ -1,3 +1,10 @@
1
+ ## 1.1.3
2
+
3
+ * The `rails runner` command no longer passes environment switches to
4
+ files which it runs. Issue #272.
5
+ * Various issues solved to do with termination / processes hanging around
6
+ longer than they should. Issue #290.
7
+
1
8
  ## 1.1.2
2
9
 
3
10
  * Detect old binstubs generated with Spring 1.0 and exit with an error.
@@ -30,3 +30,18 @@ $ RAILS_VERSION="~> 3.2.0" rake test:acceptance
30
30
 
31
31
  The apps in `test/apps` will be named based on the rails version and the
32
32
  spring version.
33
+
34
+ ## Testing with your app
35
+
36
+ You cannot link to a git repo from your Gemfile. Spring doesn't support
37
+ this due to the way that it gets loaded (bypassing bundler for
38
+ performance reasons).
39
+
40
+ Therefore, to test changes with your app, run `rake install` to properly
41
+ install the gem on your system.
42
+
43
+ ## Submitting a pull request
44
+
45
+ If your change is a bugfix or feature, please make sure you add to
46
+ `CHANGELOG.md` under the "Next Release" heading (add the heading if
47
+ needed).
data/README.md CHANGED
@@ -19,7 +19,7 @@ boot it every time you run a test, rake task or migration.
19
19
  ## Compatibility
20
20
 
21
21
  * Ruby versions: MRI 1.9.3, MRI 2.0, MRI 2.1
22
- * Rails versions: 3.2, 4.0
22
+ * Rails versions: 3.2, 4.0 (in Rails 4.1 and up Spring is included by default)
23
23
 
24
24
  Spring makes extensive use of `Process.fork`, so won't be able to
25
25
  provide a speed up on platforms which don't support forking (Windows, JRuby).
@@ -34,6 +34,9 @@ Add spring to your Gemfile:
34
34
  gem "spring", group: :development
35
35
  ```
36
36
 
37
+ (Note: using `gem "spring", git: "..."` *won't* work and is not a
38
+ supported way of using spring.)
39
+
37
40
  It's recommended to 'springify' the executables in your `bin/`
38
41
  directory:
39
42
 
@@ -213,6 +216,7 @@ to pick up the changes):
213
216
  * [spring-commands-testunit](https://github.com/jonleighton/spring-commands-testunit) - useful for
214
217
  running `Test::Unit` tests on Rails 3, since only Rails 4 allows you
215
218
  to use `rake test path/to/test` to run a particular test/directory.
219
+ * [spring-commands-teaspoon](https://github.com/alejandrobabio/spring-commands-teaspoon.git)
216
220
 
217
221
  ## Use without adding to bundle
218
222
 
@@ -295,7 +299,7 @@ Spring.application_root = './test/dummy'
295
299
 
296
300
  There is no `Spring.before_fork` callback. To run something before the
297
301
  fork, you can place it in `~/.spring.rb` or `config/spring.rb` or in any of the files
298
- which get run when your application initializers, such as
302
+ which get run when your application initializes, such as
299
303
  `config/application.rb`, `config/environments/*.rb` or
300
304
  `config/initializers/*.rb`.
301
305
 
@@ -324,7 +328,7 @@ If there are additional files or directories which should trigger an
324
328
  application restart, you can specify them with `Spring.watch`:
325
329
 
326
330
  ```ruby
327
- Spring.watch "spec/factories"
331
+ Spring.watch "config/some_config_file.yml"
328
332
  ```
329
333
 
330
334
  By default Spring polls the filesystem for changes once every 0.2 seconds. This
@@ -11,7 +11,7 @@ module Spring
11
11
  @original_env = original_env
12
12
  @spring_env = Env.new
13
13
  @mutex = Mutex.new
14
- @waiting = 0
14
+ @waiting = Set.new
15
15
  @preloaded = false
16
16
  @state = :initialized
17
17
  @interrupt = IO.pipe
@@ -186,21 +186,7 @@ module Spring
186
186
  log "forked #{pid}"
187
187
  manager.puts pid
188
188
 
189
- # Wait in a separate thread so we can run multiple commands at once
190
- Thread.new {
191
- @mutex.synchronize { @waiting += 1 }
192
-
193
- _, status = Process.wait2 pid
194
- log "#{pid} exited with #{status.exitstatus}"
195
-
196
- streams.each(&:close)
197
- client.puts(status.exitstatus)
198
- client.close
199
-
200
- @mutex.synchronize { @waiting -= 1 }
201
- exit_if_finished
202
- }
203
-
189
+ wait pid, streams, client
204
190
  rescue Exception => e
205
191
  log "exception: #{e}"
206
192
  manager.puts unless pid
@@ -215,7 +201,14 @@ module Spring
215
201
  end
216
202
 
217
203
  def terminate
218
- state! :terminating
204
+ if exiting?
205
+ # Ensure that we do not ignore subsequent termination attempts
206
+ log "forced exit"
207
+ @waiting.each { |pid| Process.kill("TERM", pid) }
208
+ Kernel.exit
209
+ else
210
+ state! :terminating
211
+ end
219
212
  end
220
213
 
221
214
  def exit
@@ -227,7 +220,7 @@ module Spring
227
220
 
228
221
  def exit_if_finished
229
222
  @mutex.synchronize {
230
- Kernel.exit if exiting? && @waiting == 0
223
+ Kernel.exit if exiting? && @waiting.empty?
231
224
  }
232
225
  end
233
226
 
@@ -296,6 +289,25 @@ module Spring
296
289
  STDIN.reopen("/dev/null")
297
290
  end
298
291
 
292
+ def wait(pid, streams, client)
293
+ @mutex.synchronize { @waiting << pid }
294
+
295
+ # Wait in a separate thread so we can run multiple commands at once
296
+ Thread.new {
297
+ begin
298
+ _, status = Process.wait2 pid
299
+ log "#{pid} exited with #{status.exitstatus}"
300
+
301
+ streams.each(&:close)
302
+ client.puts(status.exitstatus)
303
+ client.close
304
+ ensure
305
+ @mutex.synchronize { @waiting.delete pid }
306
+ exit_if_finished
307
+ end
308
+ }
309
+ end
310
+
299
311
  private
300
312
 
301
313
  def active_record_configured?
@@ -76,6 +76,7 @@ module Spring
76
76
  end
77
77
 
78
78
  def stop
79
+ log "stopping"
79
80
  @state = :stopping
80
81
 
81
82
  if pid
@@ -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}"
@@ -20,6 +26,7 @@ module Spring
20
26
 
21
27
  application, client = UNIXSocket.pair
22
28
 
29
+ queue_signals
23
30
  connect_to_application(client)
24
31
  run_command(client, application)
25
32
  rescue Errno::ECONNRESET
@@ -59,7 +66,12 @@ ERROR
59
66
  def connect_to_application(client)
60
67
  server.send_io client
61
68
  send_json server, "args" => args, "default_rails_env" => default_rails_env
62
- server.gets or raise CommandNotFound
69
+
70
+ if IO.select([server], [], [], TIMEOUT)
71
+ server.gets or raise CommandNotFound
72
+ else
73
+ raise "Error connecting to Spring server"
74
+ end
63
75
  end
64
76
 
65
77
  def run_command(client, application)
@@ -96,14 +108,23 @@ ERROR
96
108
  application.close
97
109
  end
98
110
 
111
+ def queue_signals
112
+ FORWARDED_SIGNALS.each do |sig|
113
+ trap(sig) { @signal_queue << sig }
114
+ end
115
+ end
116
+
99
117
  def forward_signals(pid)
118
+ @signal_queue.each { |sig| kill sig, pid }
119
+
100
120
  FORWARDED_SIGNALS.each do |sig|
101
121
  trap(sig) { forward_signal sig, pid }
102
122
  end
123
+ rescue Errno::ESRCH
103
124
  end
104
125
 
105
126
  def forward_signal(sig, pid)
106
- Process.kill(sig, -Process.getpgid(pid))
127
+ kill(sig, pid)
107
128
  rescue Errno::ESRCH
108
129
  # If the application process is gone, then don't block the
109
130
  # signal on this process.
@@ -111,6 +132,10 @@ ERROR
111
132
  Process.kill(sig, Process.pid)
112
133
  end
113
134
 
135
+ def kill(sig, pid)
136
+ Process.kill(sig, -Process.getpgid(pid))
137
+ end
138
+
114
139
  def send_json(socket, data)
115
140
  data = JSON.dump(data)
116
141
 
@@ -34,21 +34,41 @@ module Spring
34
34
  end
35
35
 
36
36
  class RailsRunner < Rails
37
- def env(tail)
38
- previous_option = nil
39
- tail.reverse.each do |option|
40
- case option
41
- when /--environment=(\w+)/ then return $1
42
- when '-e' then return previous_option
43
- end
44
- previous_option = option
45
- end
46
- nil
37
+ def call
38
+ ARGV.replace extract_environment(ARGV).first
39
+ super
40
+ end
41
+
42
+ def env(args)
43
+ extract_environment(args).last
47
44
  end
48
45
 
49
46
  def command_name
50
47
  "runner"
51
48
  end
49
+
50
+ def extract_environment(args)
51
+ environment = nil
52
+
53
+ args = args.select.with_index { |arg, i|
54
+ case arg
55
+ when "-e"
56
+ false
57
+ when /--environment=(\w+)/
58
+ environment = $1
59
+ false
60
+ else
61
+ if i > 0 && args[i - 1] == "-e"
62
+ environment = arg
63
+ false
64
+ else
65
+ true
66
+ end
67
+ end
68
+ }
69
+
70
+ [args, environment]
71
+ end
52
72
  end
53
73
 
54
74
  Spring.register_command "rails_console", RailsConsole.new
@@ -16,7 +16,7 @@ module Spring
16
16
  def initialize(root = nil)
17
17
  @root = root
18
18
  @project_root = root
19
- @log_file = File.open(ENV["SPRING_LOG"] || "/dev/null", "a")
19
+ @log_file = File.open(ENV["SPRING_LOG"] || File::NULL, "a")
20
20
  end
21
21
 
22
22
  def root
@@ -92,6 +92,8 @@ module Spring
92
92
  end
93
93
 
94
94
  def shutdown
95
+ log "shutting down"
96
+
95
97
  [env.socket_path, env.pidfile_path].each do |path|
96
98
  if path.exist?
97
99
  path.unlink rescue nil
@@ -1,3 +1,3 @@
1
1
  module Spring
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
@@ -68,7 +68,7 @@ module Spring
68
68
  def env
69
69
  @env ||= {
70
70
  "GEM_HOME" => gem_home.to_s,
71
- "GEM_PATH" => "",
71
+ "GEM_PATH" => gem_home.to_s,
72
72
  "HOME" => user_home.to_s,
73
73
  "RAILS_ENV" => nil,
74
74
  "RACK_ENV" => nil,
@@ -27,6 +27,18 @@ class CommandsTest < ActiveSupport::TestCase
27
27
  assert_nil command.env(['puts 1+1'])
28
28
  end
29
29
 
30
+ test 'RailsRunner#extract_environment removes -e <env>' do
31
+ command = Spring::Commands::RailsRunner.new
32
+ args = ['-b', '-a', '-e', 'test', '-r']
33
+ assert_equal [['-b', '-a', '-r'], 'test'], command.extract_environment(args)
34
+ end
35
+
36
+ test 'RailsRunner#extract_environment removes --environment=<env>' do
37
+ command = Spring::Commands::RailsRunner.new
38
+ args = ['-b', '--environment=test', '-a', '-r']
39
+ assert_equal [['-b', '-a', '-r'], 'test'], command.extract_environment(args)
40
+ end
41
+
30
42
  test "rake command has configurable environments" do
31
43
  command = Spring::Commands::Rake.new
32
44
  assert_nil command.env(["foo"])
@@ -125,12 +125,12 @@ module WatcherTests
125
125
  file = "#{@dir}/omg"
126
126
  touch file, Time.now - 2.seconds
127
127
 
128
- watcher.add file
129
- watcher.start
130
-
131
128
  stale = false
132
129
  watcher.on_stale { stale = true }
133
130
 
131
+ watcher.add file
132
+ watcher.start
133
+
134
134
  touch file, Time.now
135
135
 
136
136
  Timeout.timeout(1) { sleep 0.01 until stale }
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Leighton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-26 00:00:00.000000000 Z
11
+ date: 2014-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  description: Rails application preloader
@@ -46,8 +46,8 @@ executables:
46
46
  extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
- - .gitignore
50
- - .travis.yml
49
+ - ".gitignore"
50
+ - ".travis.yml"
51
51
  - CHANGELOG.md
52
52
  - CONTRIBUTING.md
53
53
  - Gemfile
@@ -105,17 +105,17 @@ require_paths:
105
105
  - lib
106
106
  required_ruby_version: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - '>='
113
+ - - ">="
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.1.9
118
+ rubygems_version: 2.2.2
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: Rails application preloader
@@ -129,4 +129,3 @@ test_files:
129
129
  - test/unit/commands_test.rb
130
130
  - test/unit/process_title_updater_test.rb
131
131
  - test/unit/watcher_test.rb
132
- has_rdoc: