paulanthonywilson-osx_watchfolder 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,7 +19,7 @@ Only works on OSX 10.5+ (Leopard), obviously.
19
19
 
20
20
  To run a the method 'run_tests' when a change is detected in a couple of folders:
21
21
 
22
- OsxWatchFolder::FolderWatcher.new ("lib", "test") { run_tests}
22
+ OsxWatchfolder::FolderWatcher.new("lib", "test") { run_tests}.start
23
23
 
24
24
  == REQUIREMENTS:
25
25
 
@@ -2,7 +2,7 @@
2
2
  module OsxWatchfolder
3
3
 
4
4
  # :stopdoc:
5
- VERSION = '1.0.0'
5
+ VERSION = '1.0.1'
6
6
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
7
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
8
  # :startdoc:
@@ -3,33 +3,38 @@ OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Framewo
3
3
 
4
4
  module OsxWatchfolder
5
5
 
6
+ # To run a the method 'run_tests' when a change is detected in a couple of folders:
7
+ #
8
+ # folder_watcher = OsxWatchfolder::FolderWatcher.new("lib", "test") { run_tests}
9
+ # folder_wacher.start
10
+ #
6
11
  class FolderWatcher
7
-
8
- attr_accessor :latency, :runloop_interval
12
+
13
+ # directory update notification latency in seconds. Defaults to 1
14
+ attr_accessor :latency
15
+
16
+ # runloop timeout in seconds - on all but the 1st interrupt for the script it will take a maximum of
17
+ # this long for interrupts to be noticed. Defaults to 5
18
+ attr_accessor :runloop_interval
19
+
20
+ # how many times has this been interrupted?
21
+ attr_reader :interrupted_count
9
22
 
10
23
 
11
24
  def stop
25
+ @running = false
12
26
  OSX::CFRunLoopStop(@runloop)
13
27
  end
14
28
 
15
29
  def start
16
30
  raise "May only be started from main thread" unless Thread.current == Thread.main
17
- callback = lambda do |streamRef, clientCallBackInfo, numEvents,eventPaths, eventFlags,eventIds|
18
- @block.call
19
- end
20
- stream = OSX::FSEventStreamCreate(nil,
21
- callback,
22
- nil,
23
- @folders,
24
- OSX::KFSEventStreamEventIdSinceNow,
25
- @latency,
26
- OSX::KFSEventStreamCreateFlagNone)
27
-
28
- @runloop = OSX::CFRunLoopGetCurrent()
29
-
30
- OSX::FSEventStreamScheduleWithRunLoop(stream, @runloop, OSX::KCFRunLoopDefaultMode)
31
- OSX::FSEventStreamStart(stream)
32
- OSX::CFRunLoopRun()
31
+ prepare_stream
32
+ enter_run_loop
33
+ rescue Interrupt
34
+ stop
35
+ @interrupted_count += 1
36
+ ensure
37
+ cleanup_stream
33
38
  end
34
39
 
35
40
 
@@ -38,7 +43,40 @@ module OsxWatchfolder
38
43
  @block = block
39
44
  @running = true
40
45
  @latency = 1
46
+ @runloop_interval = 5
47
+ @interrupted_count = 0
41
48
  end
42
49
 
50
+ private
51
+
52
+
53
+ def enter_run_loop
54
+ @running = true
55
+ OSX::CFRunLoopRunInMode(OSX::KCFRunLoopDefaultMode, @runloop_interval, true) while @running
56
+ end
57
+
58
+ def cleanup_stream
59
+ if (@stream)
60
+ OSX::FSEventStreamStop(@stream)
61
+ OSX::FSEventStreamInvalidate(@stream)
62
+ OSX::FSEventStreamRelease(@stream)
63
+ end
64
+ @stream = nil
65
+ end
66
+
67
+ def prepare_stream
68
+ callback = lambda do |streamRef, clientCallBackInfo, numEvents,eventPaths, eventFlags,eventIds|
69
+ @block.call
70
+ end
71
+ @stream = OSX::FSEventStreamCreate(nil,callback,nil,@folders,OSX::KFSEventStreamEventIdSinceNow, @latency,OSX::KFSEventStreamCreateFlagNone)
72
+
73
+ @runloop = OSX::CFRunLoopGetCurrent()
74
+
75
+ OSX::FSEventStreamScheduleWithRunLoop(@stream, @runloop, OSX::KCFRunLoopDefaultMode)
76
+ OSX::FSEventStreamStart(@stream)
77
+ end
78
+
79
+
80
+
43
81
  end
44
82
  end
Binary file
@@ -4,8 +4,8 @@ require 'fileutils'
4
4
  require File.expand_path(File.dirname(__FILE__) + '/../lib/osx_watchfolder')
5
5
 
6
6
  class TestFolderWatch < Test::Unit::TestCase
7
- include FileUtils
8
- include OsxWatchfolder
7
+ include FileUtils
8
+ include OsxWatchfolder
9
9
 
10
10
  def setup
11
11
  @some_folders = [Dir.tmpdir + "/folder_watch_test1", Dir.tmpdir + "/folder_watch_test2"]
@@ -13,11 +13,11 @@ include OsxWatchfolder
13
13
  @some_folders.each {|dir| mkdir dir}
14
14
  @folder_changed = false
15
15
  end
16
-
16
+
17
17
  def teardown
18
18
  @some_folders.each {|dir| rm_rf dir}
19
19
  end
20
-
20
+
21
21
  def test_nothing_happens_if_a_watched_folder_does_not_change
22
22
  in_a_second_yield_and_stop_watcher
23
23
  watch_folders
@@ -29,20 +29,20 @@ include OsxWatchfolder
29
29
  assert_equal @some_folders, FolderWatcher.new(@some_folders).instance_variable_get(:@folders)
30
30
  end
31
31
 
32
-
32
+
33
33
  def test_notified_if_first_watched_folder_changes
34
34
  in_a_second_write_file_and_stop_watcher @some_folders.first + "/somefile"
35
35
  watch_folders
36
36
  assert @folder_changed
37
37
  end
38
-
38
+
39
39
 
40
40
  def test_notified_if_another_watched_folder_changes
41
41
  in_a_second_write_file_and_stop_watcher @some_folders.last + "/somefile"
42
42
  watch_folders
43
43
  assert @folder_changed
44
44
  end
45
-
45
+
46
46
  def test_must_be_started_in_main_thread
47
47
  @testee = FolderWatcher.new(*@some_folders) {}
48
48
  t = Thread.new do
@@ -50,8 +50,20 @@ include OsxWatchfolder
50
50
  end
51
51
  t.join
52
52
  end
53
-
54
-
53
+
54
+ def test_handles_interrupts
55
+ @testee = FolderWatcher.new(*@some_folders) {}
56
+ assert_equal 0, @testee.interrupted_count
57
+ class << @testee
58
+ def enter_run_loop
59
+ raise Interrupt, "stopped!"
60
+ end
61
+ end
62
+ @testee.start
63
+ assert_equal 1, @testee.interrupted_count
64
+ end
65
+
66
+
55
67
  def in_a_second_yield_and_stop_watcher
56
68
  Thread.new do
57
69
  yield if block_given?
@@ -59,19 +71,19 @@ include OsxWatchfolder
59
71
  @testee.stop
60
72
  end
61
73
  end
62
-
74
+
63
75
  def in_a_second_write_file_and_stop_watcher(file)
64
76
  in_a_second_yield_and_stop_watcher do
65
77
  File.open(file, "w"){|f| f.write "hello"}
66
78
  end
67
79
  end
68
-
80
+
69
81
  def watch_folders
70
82
  @testee = FolderWatcher.new(*@some_folders) {@folder_changed = true}
71
83
  @testee.latency = 0.1
72
84
  @testee.runloop_interval = 0.5
73
85
  @testee.start
74
86
  end
75
-
76
-
87
+
88
+
77
89
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paulanthonywilson-osx_watchfolder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Wilson
@@ -38,7 +38,6 @@ files:
38
38
  - Rakefile
39
39
  - lib/osx_watchfolder.rb
40
40
  - lib/osx_watchfolder/folder_watcher.rb
41
- - osx_watchfolder-1.0.0.gem
42
41
  - osx_watchfolder.gemspec
43
42
  - test/test_folder_watch.rb
44
43
  has_rdoc: true