spring-jruby 1.4.3

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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +364 -0
  4. data/bin/spring +49 -0
  5. data/lib/spring-jruby/application.rb +283 -0
  6. data/lib/spring-jruby/application/boot.rb +19 -0
  7. data/lib/spring-jruby/binstub.rb +13 -0
  8. data/lib/spring-jruby/boot.rb +9 -0
  9. data/lib/spring-jruby/client.rb +46 -0
  10. data/lib/spring-jruby/client/binstub.rb +188 -0
  11. data/lib/spring-jruby/client/command.rb +18 -0
  12. data/lib/spring-jruby/client/help.rb +62 -0
  13. data/lib/spring-jruby/client/rails.rb +34 -0
  14. data/lib/spring-jruby/client/run.rb +167 -0
  15. data/lib/spring-jruby/client/status.rb +30 -0
  16. data/lib/spring-jruby/client/stop.rb +22 -0
  17. data/lib/spring-jruby/client/version.rb +11 -0
  18. data/lib/spring-jruby/command_wrapper.rb +82 -0
  19. data/lib/spring-jruby/commands.rb +51 -0
  20. data/lib/spring-jruby/commands/rails.rb +112 -0
  21. data/lib/spring-jruby/commands/rake.rb +30 -0
  22. data/lib/spring-jruby/configuration.rb +60 -0
  23. data/lib/spring-jruby/env.rb +109 -0
  24. data/lib/spring-jruby/errors.rb +36 -0
  25. data/lib/spring-jruby/impl/application.rb +7 -0
  26. data/lib/spring-jruby/impl/application_manager.rb +7 -0
  27. data/lib/spring-jruby/impl/fork/application.rb +69 -0
  28. data/lib/spring-jruby/impl/fork/application_manager.rb +137 -0
  29. data/lib/spring-jruby/impl/fork/run.rb +47 -0
  30. data/lib/spring-jruby/impl/pool/application.rb +47 -0
  31. data/lib/spring-jruby/impl/pool/application_manager.rb +226 -0
  32. data/lib/spring-jruby/impl/pool/run.rb +27 -0
  33. data/lib/spring-jruby/impl/run.rb +7 -0
  34. data/lib/spring-jruby/io_helpers.rb +92 -0
  35. data/lib/spring-jruby/json.rb +626 -0
  36. data/lib/spring-jruby/platform.rb +23 -0
  37. data/lib/spring-jruby/process_title_updater.rb +65 -0
  38. data/lib/spring-jruby/server.rb +130 -0
  39. data/lib/spring-jruby/sid.rb +42 -0
  40. data/lib/spring-jruby/test.rb +18 -0
  41. data/lib/spring-jruby/test/acceptance_test.rb +371 -0
  42. data/lib/spring-jruby/test/application.rb +217 -0
  43. data/lib/spring-jruby/test/application_generator.rb +134 -0
  44. data/lib/spring-jruby/test/rails_version.rb +40 -0
  45. data/lib/spring-jruby/test/watcher_test.rb +167 -0
  46. data/lib/spring-jruby/version.rb +3 -0
  47. data/lib/spring-jruby/watcher.rb +30 -0
  48. data/lib/spring-jruby/watcher/abstract.rb +86 -0
  49. data/lib/spring-jruby/watcher/polling.rb +61 -0
  50. metadata +137 -0
@@ -0,0 +1,30 @@
1
+ module Spring
2
+ module Client
3
+ class Status < Command
4
+ def self.description
5
+ "Show current status."
6
+ end
7
+
8
+ def call
9
+ if env.server_running?
10
+ puts "Spring is running:"
11
+ puts
12
+ print_process env.pid
13
+ application_pids.each { |pid| print_process pid }
14
+ else
15
+ puts "Spring is not running."
16
+ end
17
+ end
18
+
19
+ def print_process(pid)
20
+ puts `ps -p #{pid} -o pid= -o command=`
21
+ end
22
+
23
+ def application_pids
24
+ candidates = `ps -ax -o ppid= -o pid=`.lines
25
+ candidates.select { |l| l =~ /^(\s+)?#{env.pid} / }
26
+ .map { |l| l.split(" ").last }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ require "spring-jruby/version"
2
+
3
+ module Spring
4
+ module Client
5
+ class Stop < Command
6
+ def self.description
7
+ "Stop all spring processes for this project."
8
+ end
9
+
10
+ def call
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
17
+ puts "Spring is not running"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ require "spring-jruby/version"
2
+
3
+ module Spring
4
+ module Client
5
+ class Version < Command
6
+ def call
7
+ puts "Spring version #{Spring::VERSION}"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,82 @@
1
+ require "spring-jruby/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
@@ -0,0 +1,51 @@
1
+ require "spring-jruby/watcher"
2
+ require "spring-jruby/command_wrapper"
3
+
4
+ module Spring
5
+ @commands = {}
6
+
7
+ class << self
8
+ attr_reader :commands
9
+ end
10
+
11
+ def self.register_command(name, command = nil)
12
+ commands[name] = CommandWrapper.new(name, command)
13
+ end
14
+
15
+ def self.command?(name)
16
+ commands.include? name
17
+ end
18
+
19
+ def self.command(name)
20
+ commands.fetch name
21
+ end
22
+
23
+ require "spring-jruby/commands/rails"
24
+ require "spring-jruby/commands/rake"
25
+
26
+ # Load custom commands, if any.
27
+ # needs to be at the end to allow modification of existing commands.
28
+ config = File.expand_path("~/.spring.rb")
29
+ require config if File.exist?(config)
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"
34
+
35
+ # Auto-require any spring extensions which are in the Gemfile
36
+ Gem::Specification.map(&:name).grep(/^spring-/).each do |command|
37
+ next if command.end_with?("-jruby")
38
+ begin
39
+ require command
40
+ rescue LoadError => error
41
+ if error.message.include?(command)
42
+ require command.gsub("-", "/")
43
+ else
44
+ raise
45
+ end
46
+ end
47
+ end
48
+
49
+ config = File.expand_path("./config/spring.rb")
50
+ require config if File.exist?(config)
51
+ end
@@ -0,0 +1,112 @@
1
+ module Spring
2
+ module Commands
3
+ class Rails
4
+ def call
5
+ ARGV.unshift command_name
6
+ load Dir.glob(::Rails.root.join("{bin,script}/rails")).first
7
+ end
8
+
9
+ def description
10
+ nil
11
+ end
12
+ end
13
+
14
+ class RailsConsole < Rails
15
+ def env(args)
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
29
+ end
30
+
31
+ def command_name
32
+ "console"
33
+ end
34
+ end
35
+
36
+ class RailsGenerate < Rails
37
+ def command_name
38
+ "generate"
39
+ end
40
+ end
41
+
42
+ class RailsDestroy < Rails
43
+ def command_name
44
+ "destroy"
45
+ end
46
+ end
47
+
48
+ class RailsRunner < Rails
49
+ def call
50
+ ARGV.replace extract_environment(ARGV).first
51
+ super
52
+ end
53
+
54
+ def env(args)
55
+ extract_environment(args).last
56
+ end
57
+
58
+ def command_name
59
+ "runner"
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
84
+ end
85
+
86
+ class RailsTest < Rails
87
+ def env(args)
88
+ environment = "test"
89
+
90
+ args.each.with_index do |arg, i|
91
+ if arg =~ /--environment=(\w+)/
92
+ environment = $1
93
+ elsif i > 0 && args[i - 1] == "-e"
94
+ environment = arg
95
+ end
96
+ end
97
+
98
+ environment
99
+ end
100
+
101
+ def command_name
102
+ "test"
103
+ end
104
+ end
105
+
106
+ Spring.register_command "rails_console", RailsConsole.new
107
+ Spring.register_command "rails_generate", RailsGenerate.new
108
+ Spring.register_command "rails_destroy", RailsDestroy.new
109
+ Spring.register_command "rails_runner", RailsRunner.new
110
+ Spring.register_command "rails_test", RailsTest.new
111
+ end
112
+ end
@@ -0,0 +1,30 @@
1
+ module Spring
2
+ module Commands
3
+ class Rake
4
+ class << self
5
+ attr_accessor :environment_matchers
6
+ end
7
+
8
+ self.environment_matchers = {
9
+ :default => "test",
10
+ /^test($|:)/ => "test"
11
+ }
12
+
13
+ def env(args)
14
+ # This is an adaption of the matching that Rake itself does.
15
+ # See: https://github.com/jimweirich/rake/blob/3754a7639b3f42c2347857a0878beb3523542aee/lib/rake/application.rb#L691-L692
16
+ if env = args.grep(/^(RAILS|RACK)_ENV=(.*)$/m).last
17
+ return env.split("=").last
18
+ end
19
+
20
+ self.class.environment_matchers.each do |matcher, environment|
21
+ return environment if matcher === (args.first || :default)
22
+ end
23
+
24
+ nil
25
+ end
26
+ end
27
+
28
+ Spring.register_command "rake", Rake.new
29
+ end
30
+ end
@@ -0,0 +1,60 @@
1
+ require "spring-jruby/errors"
2
+
3
+ module Spring
4
+ class << self
5
+ attr_accessor :application_root
6
+
7
+ def gemfile
8
+ ENV['BUNDLE_GEMFILE'] || "Gemfile"
9
+ end
10
+
11
+ def after_fork_callbacks
12
+ @after_fork_callbacks ||= []
13
+ end
14
+
15
+ def after_fork(&block)
16
+ after_fork_callbacks << block
17
+ end
18
+
19
+ def verify_environment
20
+ application_root_path
21
+ end
22
+
23
+ def application_root_path
24
+ @application_root_path ||= begin
25
+ if application_root
26
+ path = Pathname.new(File.expand_path(application_root))
27
+ else
28
+ path = project_root_path
29
+ end
30
+
31
+ raise MissingApplication.new(path) unless path.join("config/application.rb").exist?
32
+ path
33
+ end
34
+ end
35
+
36
+ def project_root_path
37
+ @project_root_path ||= find_project_root(Pathname.new(File.expand_path(Dir.pwd)))
38
+ end
39
+
40
+ def pool_min_free_workers
41
+ 2
42
+ end
43
+
44
+ def pool_spawn_parallel
45
+ true
46
+ end
47
+
48
+ private
49
+
50
+ def find_project_root(current_dir)
51
+ if current_dir.join(gemfile).exist?
52
+ current_dir
53
+ elsif current_dir.root?
54
+ raise UnknownProject.new(Dir.pwd)
55
+ else
56
+ find_project_root(current_dir.parent)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,109 @@
1
+ require "pathname"
2
+ require "fileutils"
3
+ require "digest/md5"
4
+ require "tmpdir"
5
+
6
+ require "spring-jruby/version"
7
+ require "spring-jruby/sid"
8
+ require "spring-jruby/configuration"
9
+ require "spring-jruby/platform"
10
+
11
+ module Spring
12
+ STOP_TIMEOUT = 2 # seconds
13
+
14
+ class Env
15
+ attr_reader :log_file
16
+
17
+ def initialize(root = nil)
18
+ @root = root
19
+ @project_root = root
20
+ @log_file = File.open(ENV["SPRING_LOG"] || File::NULL, "a")
21
+ end
22
+
23
+ def root
24
+ @root ||= Spring.application_root_path
25
+ end
26
+
27
+ def project_root
28
+ @project_root ||= Spring.project_root_path
29
+ end
30
+
31
+ def version
32
+ Spring::VERSION
33
+ end
34
+
35
+ def tmp_path
36
+ path = Pathname.new(File.join(ENV['XDG_RUNTIME_DIR'] || Dir.tmpdir, "spring"))
37
+ FileUtils.mkdir_p(path) unless path.exist?
38
+ path
39
+ end
40
+
41
+ def application_id
42
+ Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)
43
+ end
44
+
45
+ def socket_path
46
+ tmp_path.join(application_id)
47
+ end
48
+
49
+ def socket_name
50
+ socket_path.to_s
51
+ end
52
+
53
+ def pidfile_path
54
+ tmp_path.join("#{application_id}.pid")
55
+ end
56
+
57
+ def pid
58
+ pidfile_path.exist? ? pidfile_path.read.to_i : nil
59
+ rescue Errno::ENOENT
60
+ # This can happen if the pidfile is removed after we check it
61
+ # exists
62
+ end
63
+
64
+ def app_name
65
+ root.basename
66
+ end
67
+
68
+ def server_running?
69
+ pidfile = pidfile_path.open('r+')
70
+ !pidfile.flock(File::LOCK_EX | File::LOCK_NB)
71
+ rescue Errno::ENOENT
72
+ false
73
+ ensure
74
+ if pidfile
75
+ pidfile.flock(File::LOCK_UN)
76
+ pidfile.close
77
+ end
78
+ end
79
+
80
+ def log(message)
81
+ log_file.puts "[#{Time.now}] [#{Process.pid}] #{message}"
82
+ log_file.flush
83
+ end
84
+
85
+ def stop
86
+ if server_running?
87
+ timeout = Time.now + STOP_TIMEOUT
88
+ kill 'TERM'
89
+ sleep 0.1 until !server_running? || Time.now >= timeout
90
+
91
+ if server_running?
92
+ kill 'KILL'
93
+ :killed
94
+ else
95
+ :stopped
96
+ end
97
+ else
98
+ :not_running
99
+ end
100
+ end
101
+
102
+ def kill(sig)
103
+ pid = self.pid
104
+ Process.kill(sig, pid) if pid
105
+ rescue Errno::ESRCH
106
+ # already dead
107
+ end
108
+ end
109
+ end