ruby-fsevent 0.1.0 → 0.2.0
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/History.md +21 -0
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/examples/print_changes.rb +5 -3
- data/examples/restart.rb +26 -0
- data/ext/fsevent.c +37 -14
- data/lib/fsevent/signal_ext.rb +48 -0
- data/ruby-fsevent.gemspec +13 -7
- data/spec/fsevent_spec.rb +3 -1
- data/spec/signal_ext_spec.rb +76 -0
- data/spec/spec_helper.rb +3 -2
- metadata +10 -3
data/History.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
History
|
2
|
+
=======
|
3
|
+
|
4
|
+
0.2.0 2009-10-23
|
5
|
+
----------------
|
6
|
+
|
7
|
+
**enhancements**
|
8
|
+
|
9
|
+
- No More Forking! The event loop used to fork to ensure signal handlers would be observed.
|
10
|
+
A custom signal handling solution has replaced the need to fork.
|
11
|
+
- The Event listener can now be stopped and restarted using FSEvent#stop and FSEvent#restart
|
12
|
+
|
13
|
+
**deprecations**
|
14
|
+
|
15
|
+
- FSEvent#run now FSEvent#start
|
16
|
+
|
17
|
+
|
18
|
+
0.1.0 2009-10-15
|
19
|
+
----------------
|
20
|
+
- Listen for events using OSX's FSEvents API
|
21
|
+
|
data/Rakefile
CHANGED
@@ -12,7 +12,8 @@ begin
|
|
12
12
|
gem.email = "sandro.turriate@gmail.com"
|
13
13
|
gem.homepage = "http://github.com/sandro/ruby-fsevent"
|
14
14
|
gem.authors = ["Sandro Turriate"]
|
15
|
-
gem.add_development_dependency "rspec"
|
15
|
+
gem.add_development_dependency "rspec", '>=1.2.8'
|
16
|
+
gem.require_paths = %w(lib ext)
|
16
17
|
gem.extensions << 'ext/extconf.rb'
|
17
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
19
|
end
|
@@ -37,6 +38,10 @@ task :spec => :check_dependencies
|
|
37
38
|
|
38
39
|
task :default => :spec
|
39
40
|
|
41
|
+
task :make do
|
42
|
+
system "cd ext && ruby extconf.rb && make"
|
43
|
+
end
|
44
|
+
|
40
45
|
require 'rake/rdoctask'
|
41
46
|
Rake::RDocTask.new do |rdoc|
|
42
47
|
if File.exist?('VERSION')
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/examples/print_changes.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../ext')
|
3
|
+
require 'fsevent'
|
2
4
|
|
3
5
|
class PrintChange < FSEvent
|
4
6
|
def on_change(directories)
|
5
7
|
puts "Detected change in: #{directories.inspect}"
|
6
8
|
end
|
7
9
|
|
8
|
-
def
|
10
|
+
def start
|
9
11
|
puts "watching #{registered_directories.join(", ")} for changes"
|
10
12
|
super
|
11
13
|
end
|
@@ -14,4 +16,4 @@ end
|
|
14
16
|
printer = PrintChange.new
|
15
17
|
printer.latency = 0.2
|
16
18
|
printer.watch_directories %W(#{Dir.pwd} /tmp)
|
17
|
-
printer.
|
19
|
+
printer.start
|
data/examples/restart.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../ext')
|
3
|
+
require 'fsevent'
|
4
|
+
|
5
|
+
class Restart < FSEvent
|
6
|
+
def on_change(directories)
|
7
|
+
puts "Detected change in: #{directories.inspect}"
|
8
|
+
unless @restarted
|
9
|
+
self.stop
|
10
|
+
@restarted = true
|
11
|
+
self.watch_directories "#{Dir.pwd}/spec"
|
12
|
+
self.start
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
puts "watching #{registered_directories.join(", ")} for changes"
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Signal.trap("INT"){ puts "\nCustom INT handler called."; exit }
|
23
|
+
|
24
|
+
restarter = Restart.new
|
25
|
+
restarter.watch_directories "#{Dir.pwd}/examples"
|
26
|
+
restarter.start
|
data/ext/fsevent.c
CHANGED
@@ -10,6 +10,8 @@
|
|
10
10
|
* http://github.com/alandipert/fswatch
|
11
11
|
*/
|
12
12
|
|
13
|
+
FSEventStreamRef stream;
|
14
|
+
VALUE fsevent_class;
|
13
15
|
|
14
16
|
void callback(
|
15
17
|
ConstFSEventStreamRef streamRef,
|
@@ -54,7 +56,6 @@ void watch_directory(VALUE self) {
|
|
54
56
|
context.release = NULL;
|
55
57
|
context.copyDescription = NULL;
|
56
58
|
|
57
|
-
FSEventStreamRef stream;
|
58
59
|
stream = FSEventStreamCreate(NULL,
|
59
60
|
&callback,
|
60
61
|
&context,
|
@@ -89,36 +90,58 @@ static VALUE t_watch_directories(VALUE self, VALUE directories) {
|
|
89
90
|
return rb_registered_directories;
|
90
91
|
}
|
91
92
|
|
92
|
-
|
93
|
-
static VALUE t_run(VALUE self) {
|
93
|
+
static VALUE t_start(VALUE self) {
|
94
94
|
VALUE rb_registered_directories = rb_iv_get(self, "@registered_directories");
|
95
95
|
Check_Type(rb_registered_directories, T_ARRAY);
|
96
|
-
|
97
|
-
|
96
|
+
|
97
|
+
watch_directory(self);
|
98
|
+
return self;
|
99
|
+
}
|
100
|
+
|
101
|
+
static VALUE t_stop(VALUE self) {
|
102
|
+
FSEventStreamStop(stream);
|
103
|
+
FSEventStreamInvalidate(stream);
|
104
|
+
FSEventStreamRelease(stream);
|
105
|
+
CFRunLoopStop(CFRunLoopGetCurrent());
|
106
|
+
return self;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE t_restart(VALUE self) {
|
110
|
+
t_stop(self);
|
111
|
+
watch_directory(self);
|
112
|
+
return self;
|
113
|
+
}
|
114
|
+
|
115
|
+
void delegate_signal_to_ruby(int signal) {
|
116
|
+
VALUE signal_mod = rb_const_get(rb_cObject, rb_intern("Signal"));
|
117
|
+
if (rb_funcall(signal_mod, rb_intern("handles?"), 1, INT2FIX(signal)) == Qtrue) {
|
118
|
+
rb_funcall(signal_mod, rb_intern("handle"), 1, INT2FIX(signal));
|
98
119
|
}
|
99
120
|
else {
|
100
|
-
|
121
|
+
ruby_default_signal(signal);
|
101
122
|
}
|
102
|
-
return self;
|
103
123
|
}
|
104
124
|
|
105
|
-
void
|
106
|
-
|
107
|
-
|
108
|
-
|
125
|
+
void register_signal_delegation() {
|
126
|
+
int i;
|
127
|
+
for(i = 0; i < 33; i++) { // Signal.list.values.size yields 32 different signals
|
128
|
+
(void) signal(i, delegate_signal_to_ruby);
|
109
129
|
}
|
110
130
|
}
|
111
131
|
|
112
|
-
VALUE fsevent_class;
|
113
132
|
void Init_fsevent() {
|
133
|
+
rb_require("fsevent/signal_ext");
|
134
|
+
|
114
135
|
fsevent_class = rb_define_class("FSEvent", rb_cObject);
|
115
136
|
rb_define_method(fsevent_class, "initialize", t_init, 0);
|
116
137
|
rb_define_method(fsevent_class, "on_change", t_on_change, 1);
|
117
138
|
rb_define_method(fsevent_class, "watch_directories", t_watch_directories, 1);
|
118
|
-
rb_define_method(fsevent_class, "
|
139
|
+
rb_define_method(fsevent_class, "start", t_start, 0);
|
140
|
+
rb_define_method(fsevent_class, "stop", t_stop, 0);
|
141
|
+
rb_define_method(fsevent_class, "restart", t_restart, 0);
|
119
142
|
|
120
143
|
rb_define_attr(fsevent_class, "latency", 1, 1);
|
121
144
|
rb_define_attr(fsevent_class, "registered_directories", 1, 1);
|
122
145
|
|
123
|
-
|
146
|
+
register_signal_delegation();
|
124
147
|
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Signal
|
2
|
+
class << self
|
3
|
+
alias trap_without_custom_handlers trap
|
4
|
+
|
5
|
+
def handlers
|
6
|
+
@handlers ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def trap(signal, &block)
|
10
|
+
handlers[int_for_signal(signal)] = block
|
11
|
+
end
|
12
|
+
|
13
|
+
def handles?(signal)
|
14
|
+
handlers.has_key? int_for_signal(signal)
|
15
|
+
end
|
16
|
+
|
17
|
+
def handle(signal)
|
18
|
+
if handler = handlers[int_for_signal(signal)]
|
19
|
+
handler.call
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def int_for_signal(signal)
|
26
|
+
error_msg = "Check Signal.list for a list of valid signals."
|
27
|
+
case signal
|
28
|
+
when Numeric
|
29
|
+
list.values.include?(signal) ? signal : raise(ArgumentError, "Invalid signal number. #{error_msg}")
|
30
|
+
when String
|
31
|
+
signal = signal.upcase
|
32
|
+
list.keys.include?(signal) ? list[signal] : raise(ArgumentError, "Invalid signal identifier. #{error_msg}")
|
33
|
+
else
|
34
|
+
raise ArgumentError, error_msg
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module Kernel
|
41
|
+
def self.trap(signal, &block)
|
42
|
+
Signal.trap(signal, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def trap(signal, &block)
|
47
|
+
Signal.trap(signal, &block)
|
48
|
+
end
|
data/ruby-fsevent.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ruby-fsevent}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Sandro Turriate"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-24}
|
13
13
|
s.description = %q{
|
14
14
|
A native extension exposing the OS X FSEvent API. Register directories you want to watch and a callback will fire whenever a change occurs in the registered directories.
|
15
15
|
}
|
@@ -21,26 +21,32 @@ Gem::Specification.new do |s|
|
|
21
21
|
]
|
22
22
|
s.files = [
|
23
23
|
".gitignore",
|
24
|
+
"History.md",
|
24
25
|
"LICENSE",
|
25
26
|
"README.md",
|
26
27
|
"Rakefile",
|
27
28
|
"VERSION",
|
28
29
|
"examples/print_changes.rb",
|
30
|
+
"examples/restart.rb",
|
29
31
|
"ext/extconf.rb",
|
30
32
|
"ext/fsevent.c",
|
33
|
+
"lib/fsevent/signal_ext.rb",
|
31
34
|
"ruby-fsevent.gemspec",
|
32
35
|
"spec/fsevent_spec.rb",
|
36
|
+
"spec/signal_ext_spec.rb",
|
33
37
|
"spec/spec_helper.rb"
|
34
38
|
]
|
35
39
|
s.homepage = %q{http://github.com/sandro/ruby-fsevent}
|
36
40
|
s.rdoc_options = ["--charset=UTF-8"]
|
37
|
-
s.require_paths = ["lib"]
|
41
|
+
s.require_paths = ["lib", "ext"]
|
38
42
|
s.rubygems_version = %q{1.3.5}
|
39
43
|
s.summary = %q{A native extension exposing the OS X FSEvent API.}
|
40
44
|
s.test_files = [
|
41
45
|
"spec/fsevent_spec.rb",
|
46
|
+
"spec/signal_ext_spec.rb",
|
42
47
|
"spec/spec_helper.rb",
|
43
|
-
"examples/print_changes.rb"
|
48
|
+
"examples/print_changes.rb",
|
49
|
+
"examples/restart.rb"
|
44
50
|
]
|
45
51
|
|
46
52
|
if s.respond_to? :specification_version then
|
@@ -48,11 +54,11 @@ Gem::Specification.new do |s|
|
|
48
54
|
s.specification_version = 3
|
49
55
|
|
50
56
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
51
|
-
s.add_development_dependency(%q<rspec>, [">=
|
57
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.8"])
|
52
58
|
else
|
53
|
-
s.add_dependency(%q<rspec>, [">=
|
59
|
+
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
54
60
|
end
|
55
61
|
else
|
56
|
-
s.add_dependency(%q<rspec>, [">=
|
62
|
+
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
57
63
|
end
|
58
64
|
end
|
data/spec/fsevent_spec.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Signal do
|
4
|
+
describe "#trap" do
|
5
|
+
it "captures the block argument as the signal handler" do
|
6
|
+
Signal.trap(2) { :int }
|
7
|
+
Signal.handlers[2].call.should == :int
|
8
|
+
end
|
9
|
+
|
10
|
+
it "converts the signal name into an integer when storing the handler" do
|
11
|
+
Signal.trap('INT')
|
12
|
+
Signal.handlers.should include(Signal.list['INT'])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "allows lowercase signal names" do
|
16
|
+
Signal.trap('int')
|
17
|
+
Signal.handlers.should include(Signal.list['INT'])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "does not allow unknown signal names" do
|
21
|
+
expect {
|
22
|
+
Signal.trap('interrupt')
|
23
|
+
}.to raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "does not allow unknown signal numbers" do
|
27
|
+
expect {
|
28
|
+
Signal.trap(12111211221)
|
29
|
+
}.to raise_error(ArgumentError)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not allow unknown data types" do
|
33
|
+
expect {
|
34
|
+
Signal.trap(['int'])
|
35
|
+
}.to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#handles?" do
|
40
|
+
it "returns true when a handler is registered for the signal" do
|
41
|
+
Signal.trap('INT')
|
42
|
+
Signal.handles?('INT').should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns false when no handler was registered for the signal" do
|
46
|
+
Signal.handles?('EXIT').should be_false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#handle" do
|
51
|
+
it "does not raise when trying to call a non-existant handler" do
|
52
|
+
expect do
|
53
|
+
Signal.handle('EXIT')
|
54
|
+
end.should_not raise_error
|
55
|
+
end
|
56
|
+
|
57
|
+
it "calls the handler" do
|
58
|
+
Signal.trap('INT') { :int }
|
59
|
+
Signal.handle('INT').should == :int
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe Kernel do
|
65
|
+
it "delegates .trap to Signal" do
|
66
|
+
Signal.should_receive(:trap).with('INT')
|
67
|
+
Kernel.trap('INT')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "global" do
|
72
|
+
it "delegates .trap to Signal" do
|
73
|
+
Signal.should_receive(:trap).with('INT')
|
74
|
+
trap('INT')
|
75
|
+
end
|
76
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../ext')
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
3
3
|
require 'fsevent'
|
4
|
+
require 'fsevent/signal_ext'
|
4
5
|
require 'spec/autorun'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-fsevent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sandro Turriate
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-24 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 1.2.8
|
24
24
|
version:
|
25
25
|
description: "\n A native extension exposing the OS X FSEvent API. Register directories you want to watch and a callback will fire whenever a change occurs in the registered directories.\n "
|
26
26
|
email: sandro.turriate@gmail.com
|
@@ -33,15 +33,19 @@ extra_rdoc_files:
|
|
33
33
|
- README.md
|
34
34
|
files:
|
35
35
|
- .gitignore
|
36
|
+
- History.md
|
36
37
|
- LICENSE
|
37
38
|
- README.md
|
38
39
|
- Rakefile
|
39
40
|
- VERSION
|
40
41
|
- examples/print_changes.rb
|
42
|
+
- examples/restart.rb
|
41
43
|
- ext/extconf.rb
|
42
44
|
- ext/fsevent.c
|
45
|
+
- lib/fsevent/signal_ext.rb
|
43
46
|
- ruby-fsevent.gemspec
|
44
47
|
- spec/fsevent_spec.rb
|
48
|
+
- spec/signal_ext_spec.rb
|
45
49
|
- spec/spec_helper.rb
|
46
50
|
has_rdoc: true
|
47
51
|
homepage: http://github.com/sandro/ruby-fsevent
|
@@ -52,6 +56,7 @@ rdoc_options:
|
|
52
56
|
- --charset=UTF-8
|
53
57
|
require_paths:
|
54
58
|
- lib
|
59
|
+
- ext
|
55
60
|
required_ruby_version: !ruby/object:Gem::Requirement
|
56
61
|
requirements:
|
57
62
|
- - ">="
|
@@ -73,5 +78,7 @@ specification_version: 3
|
|
73
78
|
summary: A native extension exposing the OS X FSEvent API.
|
74
79
|
test_files:
|
75
80
|
- spec/fsevent_spec.rb
|
81
|
+
- spec/signal_ext_spec.rb
|
76
82
|
- spec/spec_helper.rb
|
77
83
|
- examples/print_changes.rb
|
84
|
+
- examples/restart.rb
|