zeus 0.4.6 → 0.10.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -4
- data/Rakefile +52 -8
- data/bin/zeus +14 -6
- data/build/fsevents-wrapper +0 -0
- data/build/zeus-darwin-amd64 +0 -0
- data/build/zeus-linux-386 +0 -0
- data/build/zeus-linux-amd64 +0 -0
- data/examples/zeus.json +22 -0
- data/ext/fsevents-wrapper/fsevents-wrapper +0 -0
- data/ext/inotify-wrapper/extconf.rb +24 -0
- data/ext/inotify-wrapper/inotify-wrapper.cpp +86 -0
- data/lib/zeus.rb +123 -35
- data/lib/zeus/{server/load_tracking.rb → load_tracking.rb} +1 -3
- data/lib/zeus/rails.rb +141 -0
- data/man/build/zeus +49 -0
- data/man/build/zeus-init +13 -0
- data/man/build/zeus-init.txt +17 -0
- data/man/build/zeus-start +16 -0
- data/man/build/zeus-start.txt +18 -0
- data/man/build/zeus.txt +50 -0
- data/zeus.gemspec +17 -6
- metadata +27 -58
- data/.gitignore +0 -17
- data/.travis.yml +0 -5
- data/.zeus.rb +0 -11
- data/README.md +0 -73
- data/docs/acceptor_registration.md +0 -14
- data/docs/client_server_handshake.md +0 -25
- data/ext/fsevents-wrapper/main.m +0 -118
- data/lib/thrud.rb +0 -97
- data/lib/zeus/cli.rb +0 -80
- data/lib/zeus/client.rb +0 -114
- data/lib/zeus/client/winsize.rb +0 -28
- data/lib/zeus/error_printer.rb +0 -16
- data/lib/zeus/plan.rb +0 -18
- data/lib/zeus/plan/acceptor.rb +0 -38
- data/lib/zeus/plan/node.rb +0 -66
- data/lib/zeus/plan/stage.rb +0 -50
- data/lib/zeus/server.rb +0 -103
- data/lib/zeus/server/acceptor.rb +0 -79
- data/lib/zeus/server/acceptor_registration_monitor.rb +0 -75
- data/lib/zeus/server/client_handler.rb +0 -106
- data/lib/zeus/server/command_runner.rb +0 -70
- data/lib/zeus/server/file_monitor.rb +0 -8
- data/lib/zeus/server/file_monitor/fsevent.rb +0 -102
- data/lib/zeus/server/process_tree_monitor.rb +0 -89
- data/lib/zeus/server/stage.rb +0 -88
- data/lib/zeus/server/stage/error_state.rb +0 -42
- data/lib/zeus/server/stage/feature_notifier.rb +0 -38
- data/lib/zeus/templates/rails.rb +0 -133
- data/lib/zeus/ui.rb +0 -57
- data/lib/zeus/version.rb +0 -3
- data/spec/cli_spec.rb +0 -95
- data/spec/error_printer_spec.rb +0 -27
- data/spec/integration_spec.rb +0 -106
- data/spec/server/file_monitor/fsevent_spec.rb +0 -88
- data/spec/server/load_tracking_spec.rb +0 -67
- data/spec/server/process_tree_monitor_spec.rb +0 -50
- data/spec/spec_helper.rb +0 -38
- data/spec/ui_spec.rb +0 -54
@@ -1,42 +0,0 @@
|
|
1
|
-
module Zeus
|
2
|
-
class Server
|
3
|
-
class Stage
|
4
|
-
|
5
|
-
module ErrorState
|
6
|
-
def handle_load_error(e)
|
7
|
-
errored_file = full_path_of_file_from_error(e)
|
8
|
-
|
9
|
-
# register all the decendent acceptors as stubs with errors
|
10
|
-
register_acceptors_as_errors(e)
|
11
|
-
|
12
|
-
feature_notifier.notify_feature(errored_file)
|
13
|
-
feature_notifier.notify_new_features
|
14
|
-
|
15
|
-
# we do not need to do anything. We wait, until a dependency changes.
|
16
|
-
# At that point, we get killed and restarted.
|
17
|
-
sleep
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def full_path_of_file_from_error(e)
|
23
|
-
errored_file = e.backtrace[0].scan(/(.+?):\d+:in/)[0][0]
|
24
|
-
|
25
|
-
# handle relative paths
|
26
|
-
unless errored_file =~ /^\//
|
27
|
-
errored_file = File.expand_path(errored_file, Dir.pwd)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def register_acceptors_as_errors(e)
|
32
|
-
descendent_acceptors.each do |acc|
|
33
|
-
acc = acc.extend(Acceptor::ErrorState)
|
34
|
-
acc.error = e
|
35
|
-
acc.run
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module Zeus
|
2
|
-
class Server
|
3
|
-
class Stage
|
4
|
-
class FeatureNotifier
|
5
|
-
|
6
|
-
def initialize(server, stage_name)
|
7
|
-
@server = server
|
8
|
-
@stage_name = stage_name
|
9
|
-
end
|
10
|
-
|
11
|
-
def notify_new_features
|
12
|
-
new_features = newly_loaded_features()
|
13
|
-
$previously_loaded_features ||= []
|
14
|
-
$previously_loaded_features |= new_features
|
15
|
-
Thread.new {
|
16
|
-
new_features.each { |f| notify_feature(f) }
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
def notify_feature(feature)
|
21
|
-
@server.__CHILD__stage_has_feature(@stage_name, feature)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def newly_loaded_features
|
27
|
-
old_features = defined?($previously_loaded_features) ? $previously_loaded_features : []
|
28
|
-
($LOADED_FEATURES + @server.extra_features) - old_features
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
data/lib/zeus/templates/rails.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
require 'socket'
|
2
|
-
begin
|
3
|
-
require 'testrbl' # before bundler is setup so it does not need to be in the Gemfile
|
4
|
-
rescue LoadError
|
5
|
-
end
|
6
|
-
|
7
|
-
ROOT_PATH = File.expand_path(Dir.pwd)
|
8
|
-
|
9
|
-
Zeus::Server.define! do
|
10
|
-
stage :boot do
|
11
|
-
|
12
|
-
action do
|
13
|
-
ENV_PATH = File.expand_path('config/environment', ROOT_PATH)
|
14
|
-
BOOT_PATH = File.expand_path('config/boot', ROOT_PATH)
|
15
|
-
APP_PATH = File.expand_path('config/application', ROOT_PATH)
|
16
|
-
|
17
|
-
require BOOT_PATH
|
18
|
-
require 'rails/all'
|
19
|
-
end
|
20
|
-
|
21
|
-
stage :default_bundle do
|
22
|
-
action { Bundler.require(:default) }
|
23
|
-
|
24
|
-
stage :development_environment do
|
25
|
-
action do
|
26
|
-
Bundler.require(:development)
|
27
|
-
Rails.env = ENV['RAILS_ENV'] = "development"
|
28
|
-
require APP_PATH
|
29
|
-
Rails.application.require_environment!
|
30
|
-
end
|
31
|
-
|
32
|
-
command :generate, :g do
|
33
|
-
begin
|
34
|
-
require 'rails/generators'
|
35
|
-
Rails.application.load_generators
|
36
|
-
rescue LoadError # Rails 3.0 doesn't require this block to be run, but 3.2+ does
|
37
|
-
end
|
38
|
-
require 'rails/commands/generate'
|
39
|
-
end
|
40
|
-
|
41
|
-
command :runner, :r do
|
42
|
-
require 'rails/commands/runner'
|
43
|
-
end
|
44
|
-
|
45
|
-
command :console, :c do
|
46
|
-
require 'rails/commands/console'
|
47
|
-
Rails::Console.start(Rails.application)
|
48
|
-
end
|
49
|
-
|
50
|
-
command :server, :s do
|
51
|
-
require 'rails/commands/server'
|
52
|
-
server = Rails::Server.new
|
53
|
-
Dir.chdir(Rails.application.root)
|
54
|
-
server.start
|
55
|
-
end
|
56
|
-
|
57
|
-
stage :prerake do
|
58
|
-
action do
|
59
|
-
require 'rake'
|
60
|
-
load 'Rakefile'
|
61
|
-
end
|
62
|
-
|
63
|
-
command :rake do
|
64
|
-
Rake.application.run
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
stage :test_environment do
|
71
|
-
action do
|
72
|
-
Bundler.require(:test)
|
73
|
-
|
74
|
-
Rails.env = ENV['RAILS_ENV'] = 'test'
|
75
|
-
require APP_PATH
|
76
|
-
|
77
|
-
$rails_rake_task = 'yup' # lie to skip eager loading
|
78
|
-
Rails.application.require_environment!
|
79
|
-
$rails_rake_task = nil
|
80
|
-
$LOAD_PATH.unshift(ROOT_PATH) unless $LOAD_PATH.include?(ROOT_PATH)
|
81
|
-
|
82
|
-
if Dir.exist?(ROOT_PATH + "/test")
|
83
|
-
test = File.join(ROOT_PATH, 'test')
|
84
|
-
$LOAD_PATH.unshift(test) unless $LOAD_PATH.include?(test)
|
85
|
-
end
|
86
|
-
|
87
|
-
if Dir.exist?(ROOT_PATH + "/spec")
|
88
|
-
spec = File.join(ROOT_PATH, 'spec')
|
89
|
-
$LOAD_PATH.unshift(spec) unless $LOAD_PATH.include?(spec)
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
|
94
|
-
if Dir.exist?(ROOT_PATH + "/test")
|
95
|
-
stage :test_helper do
|
96
|
-
action { require 'test_helper' }
|
97
|
-
|
98
|
-
command :testrb do
|
99
|
-
argv = ARGV
|
100
|
-
|
101
|
-
# try to find patter by line using testrbl
|
102
|
-
if defined?(Testrbl) && argv.size == 1 and argv.first =~ /^\S+:\d+$/
|
103
|
-
file, line = argv.first.split(':')
|
104
|
-
argv = [file, '-n', "/#{Testrbl.send(:pattern_from_file, File.readlines(file), line)}/"]
|
105
|
-
puts "using -n '#{argv[2]}'" # let users copy/paste or adjust the pattern
|
106
|
-
end
|
107
|
-
|
108
|
-
runner = Test::Unit::AutoRunner.new(true)
|
109
|
-
if runner.process_args(argv)
|
110
|
-
exit runner.run
|
111
|
-
else
|
112
|
-
abort runner.options.banner + " tests..."
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
if Dir.exist?(ROOT_PATH + "/spec")
|
119
|
-
stage :spec_helper do
|
120
|
-
action { require 'spec_helper' }
|
121
|
-
|
122
|
-
command :rspec do
|
123
|
-
exit RSpec::Core::Runner.run(ARGV)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
data/lib/zeus/ui.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
module Zeus
|
2
|
-
class UI
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@quiet = false
|
6
|
-
@debug = ENV['DEBUG']
|
7
|
-
end
|
8
|
-
|
9
|
-
def info(msg)
|
10
|
-
tell_me(msg, :magenta) if !@quiet
|
11
|
-
end
|
12
|
-
|
13
|
-
def warn(msg)
|
14
|
-
tell_me(msg, :yellow)
|
15
|
-
end
|
16
|
-
|
17
|
-
def error(msg)
|
18
|
-
tell_me(msg, :red)
|
19
|
-
end
|
20
|
-
|
21
|
-
def debug(msg)
|
22
|
-
tell_me(msg, nil) if debug?
|
23
|
-
end
|
24
|
-
|
25
|
-
def be_quiet!
|
26
|
-
@quiet = true
|
27
|
-
end
|
28
|
-
|
29
|
-
def debug!
|
30
|
-
@debug = true
|
31
|
-
end
|
32
|
-
|
33
|
-
def debug?
|
34
|
-
!!@debug && !@quiet
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def tell_me(msg, color = nil)
|
40
|
-
puts make_message(msg, color)
|
41
|
-
end
|
42
|
-
|
43
|
-
def make_message(msg, color)
|
44
|
-
msg = case color
|
45
|
-
when :red ; "\x1b[31m#{msg}\x1b[0m"
|
46
|
-
when :green ; "\x1b[32m#{msg}\x1b[0m"
|
47
|
-
when :yellow ; "\x1b[33m#{msg}\x1b[0m"
|
48
|
-
when :magenta ; "\x1b[35m#{msg}\x1b[0m"
|
49
|
-
else ; msg
|
50
|
-
end
|
51
|
-
msg[-1] == "\n" ? msg : "#{msg}\n"
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
data/lib/zeus/version.rb
DELETED
data/spec/cli_spec.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Zeus
|
4
|
-
describe CLI do
|
5
|
-
let(:ui) { stub(debug!: nil) }
|
6
|
-
|
7
|
-
before do
|
8
|
-
Zeus::UI.stub(new: ui)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "fails with unknown command" do
|
12
|
-
ui.should_receive(:error).with(/Could not find task/m)
|
13
|
-
Thrud.should_receive(:exit).with(1).and_raise(SystemExit)
|
14
|
-
begin
|
15
|
-
run_with_args("foo")
|
16
|
-
rescue SystemExit
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "#help" do
|
21
|
-
it "prints a generic help menu" do
|
22
|
-
ui.should_receive(:info).with(/Global Commands.*zeus help.*show this help menu/m)
|
23
|
-
run_with_args("help")
|
24
|
-
end
|
25
|
-
|
26
|
-
it "prints a usage menu per command" do
|
27
|
-
ui.should_receive(:info).with(/Usage:.*zeus version.*version information/m)
|
28
|
-
run_with_args(["help", "version"])
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "#start" do
|
33
|
-
it "fails to start the zeus server in a non-rails project without a config" do
|
34
|
-
ui.should_receive(:error).with(/is missing a config file.*rails project.*zeus init/m)
|
35
|
-
run_with_args("start", :exit => 1)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "uses the rails template file if the project is missing a config file but looks like rails"
|
39
|
-
it "prints an error and exits if there is no config file and the project doesn't look like rails"
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "#version" do
|
43
|
-
STRING_INCLUDING_VERSION = %r{#{Regexp.escape Zeus::VERSION}}
|
44
|
-
|
45
|
-
it "prints the version and exits" do
|
46
|
-
ui.should_receive(:info).with(STRING_INCLUDING_VERSION)
|
47
|
-
run_with_args("version")
|
48
|
-
end
|
49
|
-
|
50
|
-
it "has aliases" do
|
51
|
-
ui.should_receive(:info).with(STRING_INCLUDING_VERSION).twice
|
52
|
-
run_with_args("--version")
|
53
|
-
run_with_args("-v")
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe "#init" do
|
58
|
-
it "currently only generates a rails file, even if the project doesn't look like rails" do
|
59
|
-
ui.should_receive(:info).with(/Writing new .zeus.rb/m)
|
60
|
-
run_with_args("init")
|
61
|
-
read(".zeus.rb").should include("config/application")
|
62
|
-
end
|
63
|
-
|
64
|
-
it "prints an error and exits if the project already has a zeus config" do
|
65
|
-
write(".zeus.rb", "FOO")
|
66
|
-
ui.should_receive(:error).with(/.zeus.rb already exists /m)
|
67
|
-
run_with_args("init", :exit => 1)
|
68
|
-
read(".zeus.rb").should == "FOO"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "generated tasks" do
|
73
|
-
it "displays generated tasks in the help menu" do
|
74
|
-
ui.should_receive(:info).with(/spec/)
|
75
|
-
run_with_args("help")
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
def run_with_args(args, options={})
|
82
|
-
ARGV.replace([*args])
|
83
|
-
if options[:exit]
|
84
|
-
Zeus::CLI.any_instance.should_receive(:exit).with(options[:exit]).and_raise(SystemExit)
|
85
|
-
begin
|
86
|
-
Zeus::CLI.start
|
87
|
-
rescue SystemExit
|
88
|
-
end
|
89
|
-
else
|
90
|
-
Zeus::CLI.start
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
data/spec/error_printer_spec.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'stringio'
|
4
|
-
|
5
|
-
module Zeus
|
6
|
-
describe ErrorPrinter do
|
7
|
-
|
8
|
-
let(:error) {
|
9
|
-
begin
|
10
|
-
raise
|
11
|
-
rescue => e
|
12
|
-
e
|
13
|
-
end
|
14
|
-
}
|
15
|
-
|
16
|
-
it 'prints an error just like ruby does by default' do
|
17
|
-
io = StringIO.new
|
18
|
-
ErrorPrinter.new(error).write_to(io)
|
19
|
-
io.rewind
|
20
|
-
lines = io.readlines
|
21
|
-
lines[0].should =~ /^[^\s]*error_printer_spec.rb:\d+:in `.+': \(RuntimeError\)$/
|
22
|
-
lines[1].should =~ /^\tfrom .*\.rb:\d+:in `.*'$/
|
23
|
-
lines.size.should > 5
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
data/spec/integration_spec.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe "Integration" do
|
4
|
-
after do
|
5
|
-
kill_all_children
|
6
|
-
end
|
7
|
-
|
8
|
-
context "in a non-rails project with a .zeus.rb" do
|
9
|
-
it "starts the zeus server and responds to commands" do
|
10
|
-
bar_setup("puts 'YES'")
|
11
|
-
start, run = start_and_run("bar")
|
12
|
-
start.should include "spawner `foo`"
|
13
|
-
start.should include "acceptor `bar`"
|
14
|
-
run.should == ["YES\r\n"]
|
15
|
-
end
|
16
|
-
|
17
|
-
it "receives ARGV after command" do
|
18
|
-
bar_setup("puts ARGV.join(', ')")
|
19
|
-
start, run = start_and_run("bar 1 '2 3 4' --123")
|
20
|
-
run.should == ["1, 2 3 4, --123\r\n"]
|
21
|
-
end
|
22
|
-
|
23
|
-
it "cam exist with 0" do
|
24
|
-
bar_setup("exit 0")
|
25
|
-
start_and_run("bar")
|
26
|
-
end
|
27
|
-
|
28
|
-
it "can exist with non-0" do
|
29
|
-
bar_setup("exit 1")
|
30
|
-
start_and_run("bar", :fail => true)
|
31
|
-
end
|
32
|
-
|
33
|
-
it "can run via command alias" do
|
34
|
-
write ".zeus.rb", <<-RUBY
|
35
|
-
Zeus::Server.define! do
|
36
|
-
stage :foo do
|
37
|
-
command :bar, :b do
|
38
|
-
puts "YES"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
RUBY
|
43
|
-
|
44
|
-
start, run = start_and_run("b")
|
45
|
-
start.should include "spawner `foo`"
|
46
|
-
start.should include "acceptor `bar`"
|
47
|
-
run.should == ["YES\r\n"]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def bar_setup(inner)
|
54
|
-
write ".zeus.rb", <<-RUBY
|
55
|
-
Zeus::Server.define! do
|
56
|
-
stage :foo do
|
57
|
-
command :bar do
|
58
|
-
#{inner}
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
RUBY
|
63
|
-
end
|
64
|
-
|
65
|
-
def zeus(command, options={})
|
66
|
-
command = zeus_command(command)
|
67
|
-
result = `#{command}`
|
68
|
-
raise "FAILED #{command}\n#{result}" if $?.success? == !!options[:fail]
|
69
|
-
result
|
70
|
-
end
|
71
|
-
|
72
|
-
def zeus_command(command)
|
73
|
-
"ruby -I #{root}/lib #{root}/bin/zeus #{command} 2>&1"
|
74
|
-
end
|
75
|
-
|
76
|
-
def record_start(output)
|
77
|
-
IO.popen(zeus_command("start")) do |pipe|
|
78
|
-
while str = pipe.readpartial(100)
|
79
|
-
output << str
|
80
|
-
end rescue EOFError
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def start_and_run(commands, options={})
|
85
|
-
start_output = ""
|
86
|
-
t1 = Thread.new { record_start(start_output) }
|
87
|
-
sleep 0.1
|
88
|
-
run_output = [*commands].map{ |cmd| zeus(cmd, options) }
|
89
|
-
sleep 0.2
|
90
|
-
t1.kill
|
91
|
-
[start_output, run_output]
|
92
|
-
end
|
93
|
-
|
94
|
-
def kill_all_children
|
95
|
-
`kill -9 #{child_pids.join(" ")}`
|
96
|
-
end
|
97
|
-
|
98
|
-
def child_pids
|
99
|
-
pid = Process.pid
|
100
|
-
pipe = IO.popen("ps -ef | grep #{pid}")
|
101
|
-
pipe.readlines.map do |line|
|
102
|
-
parts = line.split(/\s+/)
|
103
|
-
parts[2] if parts[3] == pid.to_s and parts[2] != pipe.pid.to_s
|
104
|
-
end.compact
|
105
|
-
end
|
106
|
-
end
|