spring 2.0.2 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,9 +1,7 @@
1
- require "set"
2
-
3
1
  module Spring
4
2
  module Client
5
3
  class Rails < Command
6
- COMMANDS = Set.new %w(console runner generate destroy test)
4
+ COMMANDS = %w(console runner generate destroy test)
7
5
 
8
6
  ALIASES = {
9
7
  "c" => "console",
@@ -14,7 +12,7 @@ module Spring
14
12
  }
15
13
 
16
14
  def self.description
17
- "Run a rails command. The following sub commands will use spring: #{COMMANDS.to_a.join ', '}."
15
+ "Run a rails command. The following sub commands will use Spring: #{COMMANDS.to_a.join ', '}."
18
16
  end
19
17
 
20
18
  def call
@@ -22,6 +20,8 @@ module Spring
22
20
 
23
21
  if COMMANDS.include?(command_name)
24
22
  Run.call(["rails_#{command_name}", *args.drop(2)])
23
+ elsif command_name&.start_with?("db:") && !command_name.start_with?("db:system")
24
+ Run.call(["rake", *args.drop(1)])
25
25
  else
26
26
  require "spring/configuration"
27
27
  ARGV.shift
@@ -44,7 +44,7 @@ module Spring
44
44
  require "spring/commands"
45
45
 
46
46
  if Spring.command?(args.first)
47
- # Command installed since spring started
47
+ # Command installed since Spring started
48
48
  stop_server
49
49
  cold_run
50
50
  else
@@ -116,7 +116,7 @@ module Spring
116
116
  def verify_server_version
117
117
  server_version = server.gets.chomp
118
118
  if server_version != env.version
119
- $stderr.puts "There is a version mismatch between the spring client " \
119
+ $stderr.puts "There is a version mismatch between the Spring client " \
120
120
  "(#{env.version}) and the server (#{server_version})."
121
121
 
122
122
  if server_booted?
@@ -142,12 +142,17 @@ module Spring
142
142
  end
143
143
 
144
144
  def run_command(client, application)
145
- log "sending command"
146
-
147
145
  application.send_io STDOUT
148
146
  application.send_io STDERR
149
147
  application.send_io STDIN
150
148
 
149
+ log "waiting for the application to be preloaded"
150
+ preload_status = application.gets
151
+ preload_status = preload_status.chomp if preload_status
152
+ log "app preload status: #{preload_status}"
153
+ exit 1 if preload_status == "1"
154
+
155
+ log "sending command"
151
156
  send_json application, "args" => args, "env" => ENV.to_hash
152
157
 
153
158
  pid = server.gets
@@ -161,6 +166,8 @@ module Spring
161
166
  if pid && !pid.empty?
162
167
  log "got pid: #{pid}"
163
168
 
169
+ suspend_resume_on_tstp_cont(pid)
170
+
164
171
  forward_signals(application)
165
172
  status = application.read.to_i
166
173
 
@@ -181,6 +188,18 @@ module Spring
181
188
  end
182
189
  end
183
190
 
191
+ def suspend_resume_on_tstp_cont(pid)
192
+ trap("TSTP") {
193
+ log "suspended"
194
+ Process.kill("STOP", pid.to_i)
195
+ Process.kill("STOP", Process.pid)
196
+ }
197
+ trap("CONT") {
198
+ log "resumed"
199
+ Process.kill("CONT", pid.to_i)
200
+ }
201
+ end
202
+
184
203
  def forward_signals(application)
185
204
  @signal_queue.each { |sig| kill sig, application }
186
205
 
@@ -4,7 +4,7 @@ module Spring
4
4
  module Client
5
5
  class Stop < Command
6
6
  def self.description
7
- "Stop all spring processes for this project."
7
+ "Stop all Spring processes for this project."
8
8
  end
9
9
 
10
10
  def call
@@ -28,11 +28,18 @@ module Spring
28
28
  config = File.expand_path("~/.spring.rb")
29
29
  require config if File.exist?(config)
30
30
 
31
- # If the config/spring.rb contains requires for commands from other gems,
32
- # then we need to be under bundler.
33
- require "bundler/setup"
31
+ # We force the TTY so bundler doesn't show a backtrace in case gems are missing.
32
+ old_env = ENV["BUNDLER_FORCE_TTY"]
33
+ ENV["BUNDLER_FORCE_TTY"] = "true"
34
+ begin
35
+ # If the config/spring.rb contains requires for commands from other gems,
36
+ # then we need to be under bundler.
37
+ require "bundler/setup"
38
+ ensure
39
+ ENV["BUNDLER_FORCE_TTY"] = old_env
40
+ end
34
41
 
35
- # Auto-require any spring extensions which are in the Gemfile
42
+ # Auto-require any Spring extensions which are in the Gemfile
36
43
  Gem::Specification.map(&:name).grep(/^spring-/).each do |command|
37
44
  begin
38
45
  require command
@@ -2,10 +2,26 @@ require "spring/errors"
2
2
 
3
3
  module Spring
4
4
  class << self
5
- attr_accessor :application_root, :quiet
5
+ attr_accessor :application_root
6
+ attr_writer :quiet
6
7
 
7
8
  def gemfile
8
- ENV['BUNDLE_GEMFILE'] || "Gemfile"
9
+ require "bundler"
10
+
11
+ if /\s1.9.[0-9]/ === Bundler.ruby_scope.gsub(/[\/\s]+/,'')
12
+ Pathname.new(ENV["BUNDLE_GEMFILE"] || "Gemfile").expand_path
13
+ else
14
+ Bundler.default_gemfile
15
+ end
16
+ end
17
+
18
+ def gemfile_lock
19
+ case gemfile.to_s
20
+ when /\bgems\.rb\z/
21
+ gemfile.sub_ext('.locked')
22
+ else
23
+ gemfile.sub_ext('.lock')
24
+ end
9
25
  end
10
26
 
11
27
  def after_fork_callbacks
@@ -37,6 +53,10 @@ module Spring
37
53
  @project_root_path ||= find_project_root(Pathname.new(File.expand_path(Dir.pwd)))
38
54
  end
39
55
 
56
+ def quiet
57
+ @quiet || ENV.key?('SPRING_QUIET')
58
+ end
59
+
40
60
  private
41
61
 
42
62
  def find_project_root(current_dir)
data/lib/spring/env.rb CHANGED
@@ -1,10 +1,6 @@
1
1
  require "pathname"
2
- require "fileutils"
3
- require "digest/md5"
4
- require "tmpdir"
5
2
 
6
3
  require "spring/version"
7
- require "spring/sid"
8
4
  require "spring/configuration"
9
5
 
10
6
  module Spring
@@ -33,15 +29,18 @@ module Spring
33
29
  end
34
30
 
35
31
  def tmp_path
32
+ require "tmpdir"
36
33
  path = Pathname.new(
37
34
  ENV["SPRING_TMP_PATH"] ||
38
35
  File.join(ENV['XDG_RUNTIME_DIR'] || Dir.tmpdir, "spring-#{Process.uid}")
39
36
  )
37
+ require "fileutils"
40
38
  FileUtils.mkdir_p(path) unless path.exist?
41
39
  path
42
40
  end
43
41
 
44
42
  def application_id
43
+ require "digest/md5"
45
44
  ENV["SPRING_APPLICATION_ID"] || Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)
46
45
  end
47
46
 
data/lib/spring/errors.rb CHANGED
@@ -24,7 +24,7 @@ module Spring
24
24
 
25
25
  def message
26
26
  "Spring was unable to find your config/application.rb file. " \
27
- "Your project root was detected at #{project_root}, so spring " \
27
+ "Your project root was detected at #{project_root}, so Spring " \
28
28
  "looked for #{project_root}/config/application.rb but it doesn't exist. You can " \
29
29
  "configure the root of your application by setting Spring.application_root in " \
30
30
  "config/spring.rb."
data/lib/spring/json.rb CHANGED
@@ -46,11 +46,9 @@ end
46
46
 
47
47
  # See https://github.com/kr/okjson for updates.
48
48
 
49
- require 'stringio'
50
-
51
49
  # Some parts adapted from
52
- # http://golang.org/src/pkg/json/decode.go and
53
- # http://golang.org/src/pkg/utf8/utf8.go
50
+ # https://golang.org/src/pkg/json/decode.go and
51
+ # https://golang.org/src/pkg/utf8/utf8.go
54
52
  module Spring
55
53
  module OkJson
56
54
  Upstream = '43'
@@ -468,19 +466,18 @@ private
468
466
 
469
467
 
470
468
  def strenc(s)
471
- t = StringIO.new
472
- t.putc(?")
469
+ t = '"'.b
473
470
  r = 0
474
471
 
475
472
  while r < s.length
476
473
  case s[r]
477
- when ?" then t.print('\\"')
478
- when ?\\ then t.print('\\\\')
479
- when ?\b then t.print('\\b')
480
- when ?\f then t.print('\\f')
481
- when ?\n then t.print('\\n')
482
- when ?\r then t.print('\\r')
483
- when ?\t then t.print('\\t')
474
+ when ?" then t << '\\"'
475
+ when ?\\ then t << '\\\\'
476
+ when ?\b then t << '\\b'
477
+ when ?\f then t << '\\f'
478
+ when ?\n then t << '\\n'
479
+ when ?\r then t << '\\r'
480
+ when ?\t then t << '\\t'
484
481
  else
485
482
  c = s[r]
486
483
  # In ruby >= 1.9, s[r] is a codepoint, not a byte.
@@ -490,14 +487,14 @@ private
490
487
  if c.ord < Spc.ord
491
488
  c = "\\u%04x" % [c.ord]
492
489
  end
493
- t.write(c)
490
+ t << c
494
491
  rescue
495
- t.write(Ustrerr)
492
+ t << Ustrerr
496
493
  end
497
494
  elsif c < Spc
498
- t.write("\\u%04x" % c)
495
+ t << "\\u%04x" % c
499
496
  elsif Spc <= c && c <= ?~
500
- t.putc(c)
497
+ t << c
501
498
  else
502
499
  n = ucharcopy(t, s, r) # ensure valid UTF-8 output
503
500
  r += n - 1 # r is incremented below
@@ -505,8 +502,8 @@ private
505
502
  end
506
503
  r += 1
507
504
  end
508
- t.putc(?")
509
- t.string
505
+ t << '"'
506
+ t
510
507
  end
511
508
 
512
509
 
@@ -531,7 +528,7 @@ private
531
528
 
532
529
  # 1-byte, 7-bit sequence?
533
530
  if c0 < Utagx
534
- t.putc(c0)
531
+ t << c0
535
532
  return 1
536
533
  end
537
534
 
@@ -544,8 +541,8 @@ private
544
541
  # 2-byte, 11-bit sequence?
545
542
  if c0 < Utag3
546
543
  raise Utf8Error if ((c0&Umask2)<<6 | (c1&Umaskx)) <= Uchar1max
547
- t.putc(c0)
548
- t.putc(c1)
544
+ t << c0
545
+ t << c1
549
546
  return 2
550
547
  end
551
548
 
@@ -559,9 +556,9 @@ private
559
556
  if c0 < Utag4
560
557
  u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
561
558
  raise Utf8Error if u <= Uchar2max
562
- t.putc(c0)
563
- t.putc(c1)
564
- t.putc(c2)
559
+ t << c0
560
+ t << c1
561
+ t << c2
565
562
  return 3
566
563
  end
567
564
 
@@ -574,16 +571,16 @@ private
574
571
  if c0 < Utag5
575
572
  u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
576
573
  raise Utf8Error if u <= Uchar3max
577
- t.putc(c0)
578
- t.putc(c1)
579
- t.putc(c2)
580
- t.putc(c3)
574
+ t << c0
575
+ t << c1
576
+ t << c2
577
+ t << c3
581
578
  return 4
582
579
  end
583
580
 
584
581
  raise Utf8Error
585
582
  rescue Utf8Error
586
- t.write(Ustrerr)
583
+ t << Ustrerr
587
584
  return 1
588
585
  end
589
586
 
@@ -1,6 +1,6 @@
1
1
  module Spring
2
2
  # Yes, I know this reimplements a bunch of stuff in Active Support, but
3
- # I don't want the spring client to depend on AS, in order to keep its
3
+ # I don't want the Spring client to depend on AS, in order to keep its
4
4
  # load time down.
5
5
  class ProcessTitleUpdater
6
6
  SECOND = 1
data/lib/spring/server.rb CHANGED
@@ -81,7 +81,8 @@ module Spring
81
81
  # This will cause it to be automatically killed once the session
82
82
  # ends (i.e. when the user closes their terminal).
83
83
  def set_pgid
84
- Process.setpgid(0, SID.pgid)
84
+ pgid = Process.getpgid(Process.getsid)
85
+ Process.setpgid(0, pgid)
85
86
  end
86
87
 
87
88
  # Ignore SIGINT and SIGQUIT otherwise the user typing ^C or ^\ on the command line
@@ -1,3 +1,3 @@
1
1
  module Spring
2
- VERSION = "2.0.2"
2
+ VERSION = "4.1.1"
3
3
  end
@@ -1,4 +1,3 @@
1
- require "set"
2
1
  require "pathname"
3
2
  require "mutex_m"
4
3
 
@@ -19,8 +18,8 @@ module Spring
19
18
 
20
19
  @root = File.realpath(root)
21
20
  @latency = latency
22
- @files = Set.new
23
- @directories = Set.new
21
+ @files = {}
22
+ @directories = {}
24
23
  @stale = false
25
24
  @listeners = []
26
25
 
@@ -63,10 +62,10 @@ module Spring
63
62
  synchronize {
64
63
  items.each do |item|
65
64
  if item.directory?
66
- directories << item.realpath.to_s
65
+ directories[item.realpath.to_s] = true
67
66
  else
68
67
  begin
69
- files << item.realpath.to_s
68
+ files[item.realpath.to_s] = true
70
69
  rescue Errno::ENOENT
71
70
  # Race condition. Ignore symlinks whose target was removed
72
71
  # since the check above, or are deeply chained.
@@ -91,7 +91,7 @@ module Spring
91
91
  end
92
92
 
93
93
  def expanded_files
94
- files + Dir["{#{directories.map { |d| "#{d}/**/*" }.join(",")}}"]
94
+ (files.keys + Dir["{#{directories.keys.map { |d| "#{d}/**/*" }.join(",")}}"]).uniq
95
95
  end
96
96
  end
97
97
  end
metadata CHANGED
@@ -1,31 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 4.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Leighton
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-21 00:00:00.000000000 Z
11
+ date: 2023-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
20
- type: :runtime
19
+ version: '0'
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
- version: '4.2'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: bump
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bump
42
+ name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -90,13 +90,6 @@ files:
90
90
  - lib/spring/json.rb
91
91
  - lib/spring/process_title_updater.rb
92
92
  - lib/spring/server.rb
93
- - lib/spring/sid.rb
94
- - lib/spring/test.rb
95
- - lib/spring/test/acceptance_test.rb
96
- - lib/spring/test/application.rb
97
- - lib/spring/test/application_generator.rb
98
- - lib/spring/test/rails_version.rb
99
- - lib/spring/test/watcher_test.rb
100
93
  - lib/spring/version.rb
101
94
  - lib/spring/watcher.rb
102
95
  - lib/spring/watcher/abstract.rb
@@ -104,8 +97,9 @@ files:
104
97
  homepage: https://github.com/rails/spring
105
98
  licenses:
106
99
  - MIT
107
- metadata: {}
108
- post_install_message:
100
+ metadata:
101
+ rubygems_mfa_required: 'true'
102
+ post_install_message:
109
103
  rdoc_options: []
110
104
  require_paths:
111
105
  - lib
@@ -113,16 +107,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
107
  requirements:
114
108
  - - ">="
115
109
  - !ruby/object:Gem::Version
116
- version: '0'
110
+ version: 2.7.0
117
111
  required_rubygems_version: !ruby/object:Gem::Requirement
118
112
  requirements:
119
113
  - - ">="
120
114
  - !ruby/object:Gem::Version
121
115
  version: '0'
122
116
  requirements: []
123
- rubyforge_project:
124
- rubygems_version: 2.6.8
125
- signing_key:
117
+ rubygems_version: 3.1.2
118
+ signing_key:
126
119
  specification_version: 4
127
120
  summary: Rails application preloader
128
121
  test_files: []
data/lib/spring/sid.rb DELETED
@@ -1,42 +0,0 @@
1
- begin
2
- # If rubygems is present, keep it out of the way when loading fiddle,
3
- # otherwise if fiddle is not installed then rubygems will load all
4
- # gemspecs in its (futile) search for fiddle, which is slow.
5
- if respond_to?(:gem_original_require, true)
6
- gem_original_require 'fiddle'
7
- else
8
- require 'fiddle'
9
- end
10
- rescue LoadError
11
- end
12
-
13
- module Spring
14
- module SID
15
- def self.fiddle_func
16
- @fiddle_func ||= Fiddle::Function.new(
17
- DL::Handle::DEFAULT['getsid'],
18
- [Fiddle::TYPE_INT],
19
- Fiddle::TYPE_INT
20
- )
21
- end
22
-
23
- def self.sid
24
- @sid ||= begin
25
- if Process.respond_to?(:getsid)
26
- # Ruby 2
27
- Process.getsid
28
- elsif defined?(Fiddle) and defined?(DL)
29
- # Ruby 1.9.3 compiled with libffi support
30
- fiddle_func.call(0)
31
- else
32
- # last resort: shell out
33
- `ps -p #{Process.pid} -o sess=`.to_i
34
- end
35
- end
36
- end
37
-
38
- def self.pgid
39
- Process.getpgid(sid)
40
- end
41
- end
42
- end