rb-fsevent 0.2.1 → 0.3.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/README.rdoc CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  Very simple & usable Mac OSX FSEvents API
4
4
 
5
- - No compilation needed (FFI)
6
5
  - RubyCocoa not required!
7
6
  - Signals are working
8
7
  - Tested on Ruby 1.8.7 & 1.9.2
@@ -21,6 +20,10 @@ Very simple & usable Mac OSX FSEvents API
21
20
  end
22
21
  fsevent.run
23
22
 
23
+ == Not about FFI
24
+
25
+ rb-fsevent doesn't use {ruby-ffi}[http://github.com/ffi/ffi] anymore because it sadly doesn't allow to catch Signals, you can see the code in {ffi branch}[http://github.com/thibaudgg/rb-fsevent/tree/ffi].
26
+
24
27
  == Development
25
28
 
26
29
  - Source hosted at {GitHub}[http://github.com/thibaudgg/rb-fsevent]
data/ext/extconf.rb ADDED
@@ -0,0 +1,19 @@
1
+ # Workaround to make Rubygems believe it builds a native gem
2
+ require 'mkmf'
3
+ create_makefile('none')
4
+
5
+ raise "Only Darwin (Mac OS X) systems are supported" unless `uname -s`.chomp == 'Darwin'
6
+
7
+ gem_root = File.expand_path(File.join('..'))
8
+ darwin_verion = `uname -r`.to_i
9
+ sdk_verion = { 9 => '10.5', 10 => '10.6', 11 => '10.7' }[darwin_verion]
10
+
11
+ raise "Only Darwin systems greather than 8 (Mac OS X 10.5+) are supported" unless sdk_verion
12
+
13
+ # Compile the actual fsevent_watch binary
14
+ system "mkdir -p #{File.join(gem_root, 'bin')}"
15
+ system "CFLAGS='-isysroot /Developer/SDKs/MacOSX#{sdk_verion}.sdk -mmacosx-version-min=#{sdk_verion}' /usr/bin/gcc -framework CoreServices -o '#{gem_root}/bin/fsevent_watch' fsevent/fsevent_watch.c"
16
+
17
+ unless File.executable?("#{gem_root}/bin/fsevent_watch")
18
+ raise "Compilation of fsevent_watch failed (see README)"
19
+ end
@@ -0,0 +1,44 @@
1
+ #include <CoreServices/CoreServices.h>
2
+
3
+ void callback(ConstFSEventStreamRef streamRef,
4
+ void *clientCallBackInfo,
5
+ size_t numEvents,
6
+ void *eventPaths,
7
+ const FSEventStreamEventFlags eventFlags[],
8
+ const FSEventStreamEventId eventIds[]
9
+ ) {
10
+ // Print modified dirs
11
+ int i;
12
+ char **paths = eventPaths;
13
+ for (i = 0; i < numEvents; i++) {
14
+ printf("%s", paths[i]);
15
+ printf(":");
16
+ }
17
+ printf("\n");
18
+ fflush(stdout);
19
+ }
20
+
21
+ int main (int argc, const char * argv[]) {
22
+ // Create event stream
23
+ CFStringRef pathToWatch = CFStringCreateWithCString(kCFAllocatorDefault, argv[1], kCFStringEncodingUTF8);
24
+ CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)&pathToWatch, 1, NULL);
25
+ void *callbackInfo = NULL;
26
+ FSEventStreamRef stream;
27
+ CFAbsoluteTime latency = 0.5;
28
+ stream = FSEventStreamCreate(
29
+ kCFAllocatorDefault,
30
+ callback,
31
+ callbackInfo,
32
+ pathsToWatch,
33
+ kFSEventStreamEventIdSinceNow,
34
+ latency,
35
+ kFSEventStreamCreateFlagNone
36
+ );
37
+
38
+ // Add stream to run loop
39
+ FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
40
+ FSEventStreamStart(stream);
41
+ CFRunLoopRun();
42
+
43
+ return 2;
44
+ }
@@ -1,9 +1,8 @@
1
1
  class FSEvent
2
- attr_reader :path, :latency, :callback, :pipe
2
+ attr_reader :path, :callback, :pipe
3
3
 
4
- def watch(path, options = {}, &callback)
4
+ def watch(path, &callback)
5
5
  @path = path
6
- @latency = options[:latency] || 0.5
7
6
  @callback = callback
8
7
  end
9
8
 
@@ -13,7 +12,7 @@ class FSEvent
13
12
  end
14
13
 
15
14
  def stop
16
- Process.kill("KILL", pipe.pid) if pipe
15
+ Process.kill("HUP", pipe.pid) if pipe
17
16
  end
18
17
 
19
18
  private
@@ -23,16 +22,18 @@ private
23
22
  end
24
23
 
25
24
  def launch_bin
26
- @pipe = IO.popen("#{bin_path}/rb-fsevent #{path} #{latency}")
25
+ @pipe = IO.popen("#{bin_path}/fsevent_watch #{path}")
27
26
  end
28
27
 
29
28
  def listen
30
29
  while !pipe.eof?
31
30
  if line = pipe.readline
32
- modified_dir_paths = line.split(" ")
31
+ modified_dir_paths = line.split(":").select { |dir| dir != "\n" }
33
32
  callback.call(modified_dir_paths)
34
33
  end
35
34
  end
35
+ rescue Interrupt
36
+ stop
36
37
  end
37
38
 
38
39
  end
@@ -1,3 +1,3 @@
1
1
  module RbFSEvent
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rb-fsevent
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Thibaud Guillaume-Gentil
@@ -15,29 +15,13 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-16 00:00:00 +02:00
18
+ date: 2010-10-17 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: ffi
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 1
30
- segments:
31
- - 0
32
- - 6
33
- - 3
34
- version: 0.6.3
35
- type: :runtime
36
- version_requirements: *id001
37
21
  - !ruby/object:Gem::Dependency
38
22
  name: bundler
39
23
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ requirement: &id001 !ruby/object:Gem::Requirement
41
25
  none: false
42
26
  requirements:
43
27
  - - ~>
@@ -49,11 +33,11 @@ dependencies:
49
33
  - 2
50
34
  version: 1.0.2
51
35
  type: :development
52
- version_requirements: *id002
36
+ version_requirements: *id001
53
37
  - !ruby/object:Gem::Dependency
54
38
  name: rspec
55
39
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ requirement: &id002 !ruby/object:Gem::Requirement
57
41
  none: false
58
42
  requirements:
59
43
  - - ~>
@@ -65,11 +49,11 @@ dependencies:
65
49
  - 0
66
50
  version: 2.0.0
67
51
  type: :development
68
- version_requirements: *id003
52
+ version_requirements: *id002
69
53
  - !ruby/object:Gem::Dependency
70
54
  name: guard-rspec
71
55
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ requirement: &id003 !ruby/object:Gem::Requirement
73
57
  none: false
74
58
  requirements:
75
59
  - - ~>
@@ -81,21 +65,22 @@ dependencies:
81
65
  - 3
82
66
  version: 0.1.3
83
67
  type: :development
84
- version_requirements: *id004
85
- description: FSEvents API using FFI (without RubyCocoa)
68
+ version_requirements: *id003
69
+ description: FSEvents API with Signals catching (without RubyCocoa)
86
70
  email:
87
71
  - thibaud@thibaud.me
88
72
  executables: []
89
73
 
90
- extensions: []
91
-
74
+ extensions:
75
+ - ext/extconf.rb
92
76
  extra_rdoc_files: []
93
77
 
94
78
  files:
95
- - bin/rb-fsevent
96
79
  - lib/rb-fsevent/fsevent.rb
97
80
  - lib/rb-fsevent/version.rb
98
81
  - lib/rb-fsevent.rb
82
+ - ext/extconf.rb
83
+ - ext/fsevent/fsevent_watch.c
99
84
  - LICENSE
100
85
  - README.rdoc
101
86
  has_rdoc: true
data/bin/rb-fsevent DELETED
@@ -1,72 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'ffi'
4
-
5
- paths, latency = ARGV[0].split(','), ARGV[1].to_f
6
-
7
- module CarbonCore
8
- extend FFI::Library
9
- ffi_lib '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/Current/CarbonCore'
10
-
11
- attach_function :CFStringCreateWithCString, [:pointer, :string, :int], :pointer
12
- KCFStringEncodingUTF8 = 0x08000100
13
- attach_function :CFStringGetLength, [:pointer, :pointer, :int, :pointer, :pointer, :pointer], :int
14
-
15
- attach_function :CFArrayCreate, [:pointer, :pointer, :int, :pointer], :pointer
16
-
17
- attach_function :CFRunLoopRun, :CFRunLoopRun, [], :void
18
- attach_function :CFRunLoopGetCurrent, [], :pointer
19
- attach_variable :kCFRunLoopDefaultMode, :pointer
20
-
21
- callback :FSEventStreamCallback, [:pointer, :pointer, :int, :pointer, :pointer, :pointer], :void
22
-
23
- KFSEventStreamEventIdSinceNow = -1
24
- attach_function :FSEventStreamCreate, [:pointer, :FSEventStreamCallback, :pointer, :pointer, :long, :double, :int], :pointer
25
- attach_function :FSEventStreamScheduleWithRunLoop, [:pointer, :pointer, :pointer], :void
26
- attach_function :FSEventStreamStart, [:pointer], :void
27
- attach_function :FSEventStreamStop, [:pointer], :void
28
- end
29
-
30
- class FSEventStream
31
- KFSEventStreamEventFlagMustScanSubDirs = 0x1
32
-
33
- class StreamError < StandardError;
34
- end
35
-
36
- attr_accessor :stream
37
-
38
- def initialize(paths, latency)
39
- # Create array of paths to observe
40
- paths_ptr = FFI::MemoryPointer.new(:pointer)
41
- paths.each do |path|
42
- path_cfstring = CarbonCore.CFStringCreateWithCString(nil, path, CarbonCore::KCFStringEncodingUTF8)
43
- paths_ptr.write_pointer(path_cfstring)
44
- end
45
- paths_cfarray = CarbonCore.CFArrayCreate nil, paths_ptr, 1, nil
46
-
47
- # Create callback
48
- callback = lambda do |stream, client_callback_info, number_of_events, event_paths, event_flags, event_ids|
49
- if number_of_events > 0
50
- paths = event_paths.get_array_of_string(0, number_of_events)
51
- $stdout.puts paths.join(" ")
52
- $stdout.flush
53
- end
54
- end
55
-
56
- @stream = CarbonCore.FSEventStreamCreate(nil, callback, nil, paths_cfarray, CarbonCore::KFSEventStreamEventIdSinceNow, latency, 0)
57
-
58
- CarbonCore.FSEventStreamScheduleWithRunLoop(stream, CarbonCore.CFRunLoopGetCurrent, CarbonCore.kCFRunLoopDefaultMode)
59
- CarbonCore.FSEventStreamStart(stream)
60
- end
61
-
62
- def run_loop
63
- CarbonCore.CFRunLoopRun
64
- end
65
-
66
- def stop
67
- CarbonCore.FSEventStreamStop(stream)
68
- end
69
- end
70
-
71
- stream = FSEventStream.new(paths, latency)
72
- stream.run_loop