zeus 0.4.1 → 0.4.4
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.
- data/ext/fsevents-wrapper/fsevents-wrapper +0 -0
- data/ext/fsevents-wrapper/main.m +7 -20
- data/lib/zeus/server/file_monitor/fsevent.rb +13 -3
- data/lib/zeus/server/load_tracking.rb +21 -8
- data/lib/zeus/server/process_tree_monitor.rb +8 -2
- data/lib/zeus/version.rb +1 -1
- data/spec/cli_spec.rb +39 -11
- data/spec/integration_spec.rb +68 -0
- data/spec/spec_helper.rb +38 -0
- metadata +6 -2
Binary file
|
data/ext/fsevents-wrapper/main.m
CHANGED
@@ -1,14 +1,7 @@
|
|
1
|
-
//
|
2
|
-
// main.m
|
3
|
-
// fsevents-wrapper
|
4
|
-
//
|
5
|
-
// Created by Burke Libbey on 2012-07-30.
|
6
|
-
// Copyright (c) 2012 Burke Libbey. All rights reserved.
|
7
|
-
//
|
8
|
-
|
9
1
|
#import <Foundation/Foundation.h>
|
10
2
|
#include <CoreServices/CoreServices.h>
|
11
3
|
#include <sys/stat.h>
|
4
|
+
#include <fcntl.h>
|
12
5
|
|
13
6
|
|
14
7
|
static CFMutableArrayRef _watchedFiles;
|
@@ -87,21 +80,11 @@ void handleInputFiles()
|
|
87
80
|
|
88
81
|
char line[2048];
|
89
82
|
|
90
|
-
|
91
|
-
|
92
|
-
FD_ZERO(&fdset);
|
93
|
-
FD_SET(STDIN_FILENO, &fdset);
|
94
|
-
struct timeval timeout;
|
95
|
-
timeout.tv_sec = 0;
|
96
|
-
timeout.tv_usec = 0;
|
97
|
-
|
98
|
-
select(STDIN_FILENO+1, &fdset, NULL, NULL, &timeout);
|
99
|
-
while (FD_ISSET(STDIN_FILENO, &fdset) && fgets(line, 2048, stdin) != NULL) {
|
83
|
+
while (fgets(line, sizeof(line), stdin) != NULL) {
|
100
84
|
line[strlen(line)-1] = 0;
|
101
85
|
anyChanges |= maybeAddFileToWatchList(line);
|
102
|
-
select(STDIN_FILENO+1, &fdset, NULL, NULL, &timeout);
|
103
86
|
}
|
104
|
-
|
87
|
+
|
105
88
|
if (anyChanges) {
|
106
89
|
configureStream();
|
107
90
|
}
|
@@ -123,6 +106,10 @@ void configureTimerAndRun()
|
|
123
106
|
|
124
107
|
int main(int argc, const char * argv[])
|
125
108
|
{
|
109
|
+
int flags = fcntl(0, F_GETFL);
|
110
|
+
flags |= O_NONBLOCK;
|
111
|
+
fcntl(STDIN_FILENO, F_SETFL, flags);
|
112
|
+
|
126
113
|
_watchedFiles = CFArrayCreateMutable(NULL, 0, NULL);
|
127
114
|
_fileIsWatched = [[NSMutableDictionary alloc] initWithCapacity:500];
|
128
115
|
|
@@ -34,7 +34,7 @@ module Zeus
|
|
34
34
|
@realpath_to_givenpath[real] ||= []
|
35
35
|
@realpath_to_givenpath[real] << given
|
36
36
|
|
37
|
-
@io_in.
|
37
|
+
@io_in.write("#{real}\n")
|
38
38
|
true
|
39
39
|
end
|
40
40
|
|
@@ -52,11 +52,21 @@ module Zeus
|
|
52
52
|
|
53
53
|
def handle_changed_files
|
54
54
|
50.times { read_and_notify_files }
|
55
|
-
rescue
|
55
|
+
rescue Stop
|
56
56
|
end
|
57
57
|
|
58
|
+
Stop = Class.new(Exception)
|
59
|
+
|
58
60
|
def read_and_notify_files
|
59
|
-
|
61
|
+
begin
|
62
|
+
lines = @io_out.read_nonblock(1000)
|
63
|
+
rescue Errno::EAGAIN
|
64
|
+
raise Stop
|
65
|
+
rescue EOFError
|
66
|
+
Zeus.ui.error("fsevents-wrapper crashed.")
|
67
|
+
Process.kill("INT", 0)
|
68
|
+
end
|
69
|
+
File.open("fse-out.log", "a") { |f|f.write lines }
|
60
70
|
files = lines.split("\n")
|
61
71
|
files[0] = "#{@buffer}#{files[0]}" unless @buffer == ""
|
62
72
|
unless lines[-1] == "\n"
|
@@ -3,14 +3,7 @@ module Zeus
|
|
3
3
|
class LoadTracking
|
4
4
|
|
5
5
|
def self.inject!(server)
|
6
|
-
$
|
7
|
-
class << Kernel
|
8
|
-
alias_method :__original_load, :load
|
9
|
-
def load(file, *a)
|
10
|
-
LoadTracking.add_feature($server, file)
|
11
|
-
__original_load(file, *a)
|
12
|
-
end
|
13
|
-
end
|
6
|
+
$zeus_file_monitor_server = server
|
14
7
|
end
|
15
8
|
|
16
9
|
def self.add_feature(server, file)
|
@@ -36,3 +29,23 @@ module Zeus
|
|
36
29
|
end
|
37
30
|
end
|
38
31
|
end
|
32
|
+
|
33
|
+
module Kernel
|
34
|
+
|
35
|
+
def load(file, *a)
|
36
|
+
Kernel.load(file, *a)
|
37
|
+
end
|
38
|
+
|
39
|
+
class << self
|
40
|
+
alias_method :__original_load, :load
|
41
|
+
def load(file, *a)
|
42
|
+
if defined?($zeus_file_monitor_server)
|
43
|
+
Zeus::Server::LoadTracking.add_feature($zeus_file_monitor_server, file)
|
44
|
+
end
|
45
|
+
__original_load(file, *a)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
|
@@ -44,11 +44,17 @@ module Zeus
|
|
44
44
|
|
45
45
|
def handle_messages
|
46
46
|
50.times { handle_message }
|
47
|
-
rescue
|
47
|
+
rescue Stop
|
48
48
|
end
|
49
49
|
|
50
|
+
Stop = Class.new(Exception)
|
51
|
+
|
50
52
|
def handle_message
|
51
|
-
|
53
|
+
begin
|
54
|
+
data = @sock.recv_nonblock(4096)
|
55
|
+
rescue Errno::EAGAIN
|
56
|
+
raise Stop
|
57
|
+
end
|
52
58
|
case data[0]
|
53
59
|
when STARTING_MARKER
|
54
60
|
handle_starting_message(data[1..-1])
|
data/lib/zeus/version.rb
CHANGED
data/spec/cli_spec.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module Zeus
|
4
4
|
describe CLI do
|
5
|
-
|
6
5
|
let(:ui) { stub(debug!: nil) }
|
7
6
|
|
8
7
|
before do
|
9
8
|
Zeus::UI.stub(new: ui)
|
10
9
|
end
|
11
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
|
+
|
12
20
|
describe "#help" do
|
13
21
|
it "prints a generic help menu" do
|
14
22
|
ui.should_receive(:info).with(/Global Commands.*zeus help.*show this help menu/m)
|
@@ -17,12 +25,16 @@ module Zeus
|
|
17
25
|
|
18
26
|
it "prints a usage menu per command" do
|
19
27
|
ui.should_receive(:info).with(/Usage:.*zeus version.*version information/m)
|
20
|
-
run_with_args("help", "version")
|
28
|
+
run_with_args(["help", "version"])
|
21
29
|
end
|
22
30
|
end
|
23
31
|
|
24
32
|
describe "#start" do
|
25
|
-
it "
|
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
|
+
|
26
38
|
it "uses the rails template file if the project is missing a config file but looks like rails"
|
27
39
|
it "prints an error and exits if there is no config file and the project doesn't look like rails"
|
28
40
|
end
|
@@ -40,12 +52,21 @@ module Zeus
|
|
40
52
|
run_with_args("--version")
|
41
53
|
run_with_args("-v")
|
42
54
|
end
|
43
|
-
|
44
55
|
end
|
45
56
|
|
46
57
|
describe "#init" do
|
47
|
-
it "currently only generates a rails file, even if the project doesn't look like rails"
|
48
|
-
|
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
|
49
70
|
end
|
50
71
|
|
51
72
|
describe "generated tasks" do
|
@@ -57,11 +78,18 @@ module Zeus
|
|
57
78
|
|
58
79
|
private
|
59
80
|
|
60
|
-
def run_with_args(
|
61
|
-
ARGV.replace(args)
|
62
|
-
|
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
|
63
92
|
end
|
64
|
-
|
65
93
|
end
|
66
94
|
end
|
67
95
|
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Integration" do
|
4
|
+
after do
|
5
|
+
kill_all_children
|
6
|
+
end
|
7
|
+
|
8
|
+
it "starts the zeus server in a non-rails project with a config and responds to commands" do
|
9
|
+
write ".zeus.rb", <<-RUBY
|
10
|
+
Zeus::Server.define! do
|
11
|
+
stage :foo do
|
12
|
+
command :bar do
|
13
|
+
puts "YES"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
RUBY
|
18
|
+
|
19
|
+
start, run = start_and_run("bar")
|
20
|
+
start.should include "spawner `foo`"
|
21
|
+
start.should include "acceptor `bar`"
|
22
|
+
run.should == ["YES\r\n"]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def zeus(command, options={})
|
28
|
+
command = zeus_command(command)
|
29
|
+
result = `#{command}`
|
30
|
+
raise "FAILED #{command}\n#{result}" if $?.success? == !!options[:fail]
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
def zeus_command(command)
|
35
|
+
"ruby -I #{root}/lib #{root}/bin/zeus #{command} 2>&1"
|
36
|
+
end
|
37
|
+
|
38
|
+
def record_start(output)
|
39
|
+
IO.popen(zeus_command("start")) do |pipe|
|
40
|
+
while str = pipe.readpartial(100)
|
41
|
+
output << str
|
42
|
+
end rescue EOFError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def start_and_run(commands)
|
47
|
+
start_output = ""
|
48
|
+
t1 = Thread.new { record_start(start_output) }
|
49
|
+
sleep 0.1
|
50
|
+
run_output = [*commands].map{ |cmd| zeus(cmd) }
|
51
|
+
sleep 0.2
|
52
|
+
t1.kill
|
53
|
+
[start_output, run_output]
|
54
|
+
end
|
55
|
+
|
56
|
+
def kill_all_children
|
57
|
+
`kill -9 #{child_pids.join(" ")}`
|
58
|
+
end
|
59
|
+
|
60
|
+
def child_pids
|
61
|
+
pid = Process.pid
|
62
|
+
pipe = IO.popen("ps -ef | grep #{pid}")
|
63
|
+
pipe.readlines.map do |line|
|
64
|
+
parts = line.split(/\s+/)
|
65
|
+
parts[2] if parts[3] == pid.to_s and parts[2] != pipe.pid.to_s
|
66
|
+
end.compact
|
67
|
+
end
|
68
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'zeus'
|
2
|
+
|
3
|
+
module FolderHelpers
|
4
|
+
def write(file, content)
|
5
|
+
ensure_folder File.dirname(file)
|
6
|
+
File.open(file, 'w'){|f| f.write content }
|
7
|
+
end
|
8
|
+
|
9
|
+
def read(file)
|
10
|
+
File.read file
|
11
|
+
end
|
12
|
+
|
13
|
+
def delete(file)
|
14
|
+
`rm #{file}`
|
15
|
+
end
|
16
|
+
|
17
|
+
def ensure_folder(folder)
|
18
|
+
`mkdir -p #{folder}` unless File.exist?(folder)
|
19
|
+
end
|
20
|
+
|
21
|
+
def root
|
22
|
+
File.expand_path '../..', __FILE__
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
config.include FolderHelpers
|
28
|
+
|
29
|
+
config.around do |example|
|
30
|
+
folder = File.expand_path("../tmp", __FILE__)
|
31
|
+
`rm -rf #{folder}`
|
32
|
+
ensure_folder folder
|
33
|
+
Dir.chdir folder do
|
34
|
+
example.call
|
35
|
+
end
|
36
|
+
`rm -rf #{folder}`
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zeus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Boot any rails app in under a second
|
15
15
|
email:
|
@@ -48,8 +48,10 @@ files:
|
|
48
48
|
- lib/zeus/ui.rb
|
49
49
|
- lib/zeus/version.rb
|
50
50
|
- spec/cli_spec.rb
|
51
|
+
- spec/integration_spec.rb
|
51
52
|
- spec/server/file_monitor/fsevent_spec.rb
|
52
53
|
- spec/server/process_tree_monitor_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
53
55
|
- spec/ui_spec.rb
|
54
56
|
- zeus.gemspec
|
55
57
|
homepage: https://github.com/burke/zeus
|
@@ -80,7 +82,9 @@ summary: Zeus is an intelligent preloader for ruby applications. It allows norma
|
|
80
82
|
development tasks to be run in a fraction of a second.
|
81
83
|
test_files:
|
82
84
|
- spec/cli_spec.rb
|
85
|
+
- spec/integration_spec.rb
|
83
86
|
- spec/server/file_monitor/fsevent_spec.rb
|
84
87
|
- spec/server/process_tree_monitor_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
85
89
|
- spec/ui_spec.rb
|
86
90
|
has_rdoc:
|