spring 1.1.2 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4095a71b95759b8a4ed6a71b5ddcb5048aad506
4
- data.tar.gz: 360837121b6655c0abc8fb88f28ce6b62f46a88e
3
+ metadata.gz: 0bae3c5f77134086e25e77df5d700895438e16ba
4
+ data.tar.gz: 882c5139fed3fe573bb75136e683ca8ee3744069
5
5
  SHA512:
6
- metadata.gz: 255ec2bc4edd38b0c1d609e16b8cc6d7d9f8bccdddff14e482f98202260e1dae3f7d766a56b47cb846973c443e45b67bac0ae1c8c3c830c9c9c0ed64486c6025
7
- data.tar.gz: 3181e4b656a12b4094742647f6b7fe260d6f3f5acb0642bc39bfbfb83389a174a7434fa6ab355723a169cb2a2441793f02f46aa618a9ec87d7f9eccb9611ee71
6
+ metadata.gz: c5d7a1655a09f56c5663024af741c3c58fe9542418603a59dddb0c19ee24203a1527911a4626f6a5eedd5daf5b6e19b1107582fdc2c7528563af1878034cf1a7
7
+ data.tar.gz: d143cad1d9b6f15440d80aa300b566a4fa19c0c90deada7fa627e3b230f9199ed56eae911c0005fa2ff83814bf3e66190777a42e0bb4cf5ee6d997df9d06b297
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
+ .ruby-version
data/.travis.yml CHANGED
@@ -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"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 1.2.0
2
+
3
+ * Accept -e and --environment options for `rails console`.
4
+ * Watch `config/secrets.yml` by default. #289 - @morgoth
5
+ * Change monkey-patched `Kernel.raise` from public to private (to match default Ruby behavior) #351 - @mattbrictson
6
+ * Let application_id also respect RUBY_VERSION for the use case of switching between Ruby versions for a given Rails app - @methodmissing
7
+ * Extract the 'listen' watcher to a separate `spring-watcher-listen`
8
+ gem. This allows it to be developed/maintained separately.
9
+
10
+ ## 1.1.3
11
+
12
+ * The `rails runner` command no longer passes environment switches to
13
+ files which it runs. Issue #272.
14
+ * Various issues solved to do with termination / processes hanging around
15
+ longer than they should. Issue #290.
16
+
1
17
  ## 1.1.2
2
18
 
3
19
  * Detect old binstubs generated with Spring 1.0 and exit with an error.
data/CONTRIBUTING.md CHANGED
@@ -1,3 +1,8 @@
1
+ # Don't use the issue tracker to ask questions
2
+
3
+ Please use Stack Overflow or similar. If you subsequently feel that the
4
+ documentation is inadequate then plase submit a pull request to fix it.
5
+
1
6
  # Contributing guide
2
7
 
3
8
  ## Getting set up
@@ -30,3 +35,18 @@ $ RAILS_VERSION="~> 3.2.0" rake test:acceptance
30
35
 
31
36
  The apps in `test/apps` will be named based on the rails version and the
32
37
  spring version.
38
+
39
+ ## Testing with your app
40
+
41
+ You cannot link to a git repo from your Gemfile. Spring doesn't support
42
+ this due to the way that it gets loaded (bypassing bundler for
43
+ performance reasons).
44
+
45
+ Therefore, to test changes with your app, run `rake install` to properly
46
+ install the gem on your system.
47
+
48
+ ## Submitting a pull request
49
+
50
+ If your change is a bugfix or feature, please make sure you add to
51
+ `CHANGELOG.md` under the "Next Release" heading (add the heading if
52
+ needed).
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in spring.gemspec
4
4
  gemspec
5
-
6
- gem 'listen', "~> 1.0", :require => false
data/README.md CHANGED
@@ -7,8 +7,6 @@ Spring is a Rails application preloader. It speeds up development by
7
7
  keeping your application running in the background so you don't need to
8
8
  boot it every time you run a test, rake task or migration.
9
9
 
10
- **Upgrading to 1.1? It's recommended to run `bundle exec spring binstub --all` to regenerate your binstubs.**
11
-
12
10
  ## Features
13
11
 
14
12
  * Totally automatic; no need to explicitly start and stop the background process
@@ -19,7 +17,7 @@ boot it every time you run a test, rake task or migration.
19
17
  ## Compatibility
20
18
 
21
19
  * Ruby versions: MRI 1.9.3, MRI 2.0, MRI 2.1
22
- * Rails versions: 3.2, 4.0
20
+ * Rails versions: 3.2, 4.0 (in Rails 4.1 and up Spring is included by default)
23
21
 
24
22
  Spring makes extensive use of `Process.fork`, so won't be able to
25
23
  provide a speed up on platforms which don't support forking (Windows, JRuby).
@@ -34,6 +32,9 @@ Add spring to your Gemfile:
34
32
  gem "spring", group: :development
35
33
  ```
36
34
 
35
+ (Note: using `gem "spring", git: "..."` *won't* work and is not a
36
+ supported way of using spring.)
37
+
37
38
  It's recommended to 'springify' the executables in your `bin/`
38
39
  directory:
39
40
 
@@ -58,8 +59,10 @@ will just be silently ignored and the lines after it will be executed as
58
59
  normal.
59
60
 
60
61
  If you don't want to prefix every command you type with `bin/`, you
61
- can [use direnv](https://github.com/zimbatm/direnv) to automatically add
62
- `./bin` to your `PATH` when you `cd` into your application.
62
+ can [use direnv](https://github.com/zimbatm/direnv#the-stdlib) to
63
+ automatically add `./bin` to your `PATH` when you `cd` into your application.
64
+ Simply create an `.envrc` file with the command `PATH_add bin` in your
65
+ Rails directory.
63
66
 
64
67
  ### Usage
65
68
 
@@ -176,6 +179,17 @@ To remove spring:
176
179
  * 'Unspring' your bin/ executables: `bin/spring binstub --remove --all`
177
180
  * Remove spring from your Gemfile
178
181
 
182
+ ### Deployment
183
+
184
+ You must not install Spring on your production environment. To prevent it from
185
+ being installed, provide the `--without development test` argument to the
186
+ `bundle install` command which is used to install gems on your production
187
+ machines:
188
+
189
+ ```
190
+ $ bundle install --without development test
191
+ ```
192
+
179
193
  ## Commands
180
194
 
181
195
  ### `rake`
@@ -213,6 +227,7 @@ to pick up the changes):
213
227
  * [spring-commands-testunit](https://github.com/jonleighton/spring-commands-testunit) - useful for
214
228
  running `Test::Unit` tests on Rails 3, since only Rails 4 allows you
215
229
  to use `rake test path/to/test` to run a particular test/directory.
230
+ * [spring-commands-teaspoon](https://github.com/alejandrobabio/spring-commands-teaspoon.git)
216
231
 
217
232
  ## Use without adding to bundle
218
233
 
@@ -295,7 +310,7 @@ Spring.application_root = './test/dummy'
295
310
 
296
311
  There is no `Spring.before_fork` callback. To run something before the
297
312
  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
313
+ which get run when your application initializes, such as
299
314
  `config/application.rb`, `config/environments/*.rb` or
300
315
  `config/initializers/*.rb`.
301
316
 
@@ -324,18 +339,15 @@ If there are additional files or directories which should trigger an
324
339
  application restart, you can specify them with `Spring.watch`:
325
340
 
326
341
  ```ruby
327
- Spring.watch "spec/factories"
342
+ Spring.watch "config/some_config_file.yml"
328
343
  ```
329
344
 
330
345
  By default Spring polls the filesystem for changes once every 0.2 seconds. This
331
346
  method requires zero configuration, but if you find that it's using too
332
- much CPU, then you can turn on event-based file system listening:
333
-
334
- ```ruby
335
- Spring.watch_method = :listen
336
- ```
337
-
338
- You may need to add the [`listen` gem](https://github.com/guard/listen) to your `Gemfile`.
347
+ much CPU, then you can use event-based file system listening by
348
+ installing the
349
+ [spring-watcher-listen](https://github.com/jonleighton/spring-watcher-listen)
350
+ gem.
339
351
 
340
352
  ## Troubleshooting
341
353
 
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ namespace :test do
10
10
 
11
11
  Rake::TestTask.new(:acceptance) do |t|
12
12
  t.libs << "test"
13
- t.test_files = FileList["test/acceptance/*_test.rb"]
13
+ t.test_files = FileList["test/acceptance_test.rb"]
14
14
  t.verbose = true
15
15
  end
16
16
 
@@ -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
@@ -108,6 +108,9 @@ module Spring
108
108
  if defined?(Rails) && Rails.application
109
109
  watcher.add Rails.application.paths["config/initializers"]
110
110
  watcher.add Rails.application.paths["config/database"]
111
+ if secrets_path = Rails.application.paths["config/secrets"]
112
+ watcher.add secrets_path
113
+ end
111
114
  end
112
115
  end
113
116
 
@@ -186,21 +189,7 @@ module Spring
186
189
  log "forked #{pid}"
187
190
  manager.puts pid
188
191
 
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
-
192
+ wait pid, streams, client
204
193
  rescue Exception => e
205
194
  log "exception: #{e}"
206
195
  manager.puts unless pid
@@ -215,7 +204,14 @@ module Spring
215
204
  end
216
205
 
217
206
  def terminate
218
- state! :terminating
207
+ if exiting?
208
+ # Ensure that we do not ignore subsequent termination attempts
209
+ log "forced exit"
210
+ @waiting.each { |pid| Process.kill("TERM", pid) }
211
+ Kernel.exit
212
+ else
213
+ state! :terminating
214
+ end
219
215
  end
220
216
 
221
217
  def exit
@@ -227,7 +223,7 @@ module Spring
227
223
 
228
224
  def exit_if_finished
229
225
  @mutex.synchronize {
230
- Kernel.exit if exiting? && @waiting == 0
226
+ Kernel.exit if exiting? && @waiting.empty?
231
227
  }
232
228
  end
233
229
 
@@ -274,6 +270,7 @@ module Spring
274
270
  end
275
271
  end
276
272
  end
273
+ private :raise
277
274
  end
278
275
  end
279
276
 
@@ -296,6 +293,25 @@ module Spring
296
293
  STDIN.reopen("/dev/null")
297
294
  end
298
295
 
296
+ def wait(pid, streams, client)
297
+ @mutex.synchronize { @waiting << pid }
298
+
299
+ # Wait in a separate thread so we can run multiple commands at once
300
+ Thread.new {
301
+ begin
302
+ _, status = Process.wait2 pid
303
+ log "#{pid} exited with #{status.exitstatus}"
304
+
305
+ streams.each(&:close)
306
+ client.puts(status.exitstatus)
307
+ client.close
308
+ ensure
309
+ @mutex.synchronize { @waiting.delete pid }
310
+ exit_if_finished
311
+ end
312
+ }
313
+ end
314
+
299
315
  private
300
316
 
301
317
  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
@@ -36,7 +36,7 @@ unless defined?(Spring)
36
36
  require "rubygems"
37
37
  require "bundler"
38
38
 
39
- if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ spring \((.*?)\)$.*?^$/m)
39
+ if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)
40
40
  ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR)
41
41
  ENV["GEM_HOME"] = ""
42
42
  Gem.paths = ENV
@@ -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
 
@@ -13,7 +13,19 @@ module Spring
13
13
 
14
14
  class RailsConsole < Rails
15
15
  def env(args)
16
- 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
17
29
  end
18
30
 
19
31
  def command_name
@@ -34,21 +46,41 @@ module Spring
34
46
  end
35
47
 
36
48
  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
49
+ def call
50
+ ARGV.replace extract_environment(ARGV).first
51
+ super
52
+ end
53
+
54
+ def env(args)
55
+ extract_environment(args).last
47
56
  end
48
57
 
49
58
  def command_name
50
59
  "runner"
51
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
52
84
  end
53
85
 
54
86
  Spring.register_command "rails_console", RailsConsole.new
@@ -32,8 +32,17 @@ module Spring
32
32
  # then we need to be under bundler.
33
33
  require "bundler/setup"
34
34
 
35
- Gem::Specification.map(&:name).grep(/^spring-commands-/).each do |command|
36
- require command
35
+ # Auto-require any spring extensions which are in the Gemfile
36
+ Gem::Specification.map(&:name).grep(/^spring-/).each do |command|
37
+ begin
38
+ require command
39
+ rescue LoadError => error
40
+ if error.message.include?(command)
41
+ require command.gsub("-", "/")
42
+ else
43
+ raise
44
+ end
45
+ end
37
46
  end
38
47
 
39
48
  config = File.expand_path("./config/spring.rb")
data/lib/spring/env.rb CHANGED
@@ -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
@@ -32,13 +32,13 @@ module Spring
32
32
  end
33
33
 
34
34
  def tmp_path
35
- path = Pathname.new(Dir.tmpdir + "/spring")
35
+ path = Pathname.new(File.join(ENV['XDG_RUNTIME_DIR'] || Dir.tmpdir, "spring"))
36
36
  FileUtils.mkdir_p(path) unless path.exist?
37
37
  path
38
38
  end
39
39
 
40
40
  def application_id
41
- Digest::MD5.hexdigest(project_root.to_s)
41
+ Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)
42
42
  end
43
43
 
44
44
  def socket_path
data/lib/spring/server.rb CHANGED
@@ -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
data/lib/spring/sid.rb CHANGED
@@ -25,7 +25,7 @@ module Spring
25
25
  if Process.respond_to?(:getsid)
26
26
  # Ruby 2
27
27
  Process.getsid
28
- elsif defined?(Fiddle)
28
+ elsif defined?(Fiddle) and defined?(DL)
29
29
  # Ruby 1.9.3 compiled with libffi support
30
30
  fiddle_func.call(0)
31
31
  else