zeus 0.4.1 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|