rb-fsevent 0.9.8 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -3
- data/README.md +20 -3
- data/Rakefile +2 -1
- data/bin/fsevent_watch +0 -0
- data/ext/fsevent_watch/cli.c +1 -2
- data/ext/fsevent_watch/compat.c +19 -3
- data/ext/fsevent_watch/compat.h +62 -9
- data/ext/fsevent_watch/main.c +45 -6
- data/ext/rakefile.rb +5 -3
- data/lib/otnetstring.rb +85 -0
- data/lib/rb-fsevent/fsevent.rb +38 -4
- data/lib/rb-fsevent/version.rb +1 -1
- data/rb-fsevent.gemspec +6 -1
- metadata +22 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61d076a09964b861d80f4724752654bd1e03d7b1
|
4
|
+
data.tar.gz: 549a175bc931f6e247d09e87bc4a0e805a8715b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e124acb15e091aae6d754e00dde77dde57a267c3c209cab827735f527abce5800d4b16066adaeacdbadc4fa8311b1622bda29bf300de8a1a4c3c4d1033e7f1d4
|
7
|
+
data.tar.gz: d27912bb5ea1822547af03aeabb819a6aabf39b1cae25289e0132ac768d68d7751f1895ccd97bdbf9026c2c1fe787d8d0612708a725fcef6c9882fa4a91e1082
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,8 +7,8 @@ Very simple & usable Mac OSX FSEvents API
|
|
7
7
|
|
8
8
|
* RubyCocoa not required!
|
9
9
|
* Signals are working (really)
|
10
|
-
* Tested on MRI 2.1, RBX
|
11
|
-
* Tested on 10.
|
10
|
+
* Tested on MRI 2.4.1, RBX 3.72, JRuby 1.7.26 and 9.1.8.0
|
11
|
+
* Tested on 10.8
|
12
12
|
|
13
13
|
## HFS+ filename corruption bug
|
14
14
|
|
@@ -131,6 +131,23 @@ end
|
|
131
131
|
fsevent.run
|
132
132
|
```
|
133
133
|
|
134
|
+
### Using _full_ event information
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
require 'rb-fsevent'
|
138
|
+
fsevent = FSEvent.new
|
139
|
+
fsevent.watch Dir.pwd do |paths, event_meta|
|
140
|
+
event_meta.events.each do |event|
|
141
|
+
puts "event ID: #{event.id}"
|
142
|
+
puts "path: #{event.path}"
|
143
|
+
puts "c flags: #{event.cflags}"
|
144
|
+
puts "named flags: #{event.flags.join(', ')}"
|
145
|
+
# named flags will include strings such as `ItemInodeMetaMod` or `OwnEvent`
|
146
|
+
end
|
147
|
+
end
|
148
|
+
fsevent.run
|
149
|
+
```
|
150
|
+
|
134
151
|
## Options
|
135
152
|
|
136
153
|
When defining options using a hash or hash-like object, it gets checked for validity and converted to the appropriate fsevent\_watch commandline arguments array when the FSEvent class is instantiated. This is obviously the safest and preferred method of passing in options.
|
@@ -233,7 +250,7 @@ Pull requests are quite welcome! Please ensure that your commits are in a topic
|
|
233
250
|
|
234
251
|
The list of tested targets is currently:
|
235
252
|
|
236
|
-
%w[2.
|
253
|
+
%w[2.4.1 rbx-3.72 jruby-1.7.26 jruby-9.1.8.0]
|
237
254
|
|
238
255
|
## Authors
|
239
256
|
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ task :default => :spec
|
|
9
9
|
namespace(:spec) do
|
10
10
|
desc "Run all specs on multiple ruby versions"
|
11
11
|
task(:portability) do
|
12
|
-
versions = %w[2.
|
12
|
+
versions = %w[2.4.1 rbx-3.72 jruby-1.7.26 jruby-9.1.8.0]
|
13
13
|
versions.each do |version|
|
14
14
|
# system <<-BASH
|
15
15
|
# bash -c 'source ~/.rvm/scripts/rvm;
|
@@ -24,6 +24,7 @@ namespace(:spec) do
|
|
24
24
|
[[ ! -a $HOME/.rbenv/versions/#{version} ]] && rbenv install #{version};
|
25
25
|
rbenv shell #{version};
|
26
26
|
rbenv which bundle 2> /dev/null || gem install bundler;
|
27
|
+
rm Gemfile.lock;
|
27
28
|
bundle install;
|
28
29
|
rake spec;'
|
29
30
|
BASH
|
data/bin/fsevent_watch
CHANGED
Binary file
|
data/ext/fsevent_watch/cli.c
CHANGED
@@ -27,7 +27,7 @@ static void default_args (struct cli_info* args_info)
|
|
27
27
|
args_info->ignore_self_flag = false;
|
28
28
|
args_info->file_events_flag = false;
|
29
29
|
args_info->mark_self_flag = false;
|
30
|
-
args_info->format_arg =
|
30
|
+
args_info->format_arg = kFSEventWatchOutputFormatOTNetstring;
|
31
31
|
}
|
32
32
|
|
33
33
|
static void cli_parser_release (struct cli_info* args_info)
|
@@ -199,4 +199,3 @@ int cli_parser (int argc, const char** argv, struct cli_info* args_info)
|
|
199
199
|
|
200
200
|
return EXIT_SUCCESS;
|
201
201
|
}
|
202
|
-
|
data/ext/fsevent_watch/compat.c
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
#include "compat.h"
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6) || \
|
5
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
|
4
6
|
FSEventStreamCreateFlags kFSEventStreamCreateFlagIgnoreSelf = 0x00000008;
|
5
7
|
#endif
|
6
8
|
|
7
|
-
#if MAC_OS_X_VERSION_MAX_ALLOWED <
|
9
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7) || \
|
10
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
|
8
11
|
FSEventStreamCreateFlags kFSEventStreamCreateFlagFileEvents = 0x00000010;
|
9
12
|
FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated = 0x00000100;
|
10
13
|
FSEventStreamEventFlags kFSEventStreamEventFlagItemRemoved = 0x00000200;
|
@@ -19,7 +22,20 @@ FSEventStreamEventFlags kFSEventStreamEventFlagItemIsDir = 0x00020000
|
|
19
22
|
FSEventStreamEventFlags kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
|
20
23
|
#endif
|
21
24
|
|
22
|
-
#if MAC_OS_X_VERSION_MAX_ALLOWED <
|
25
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9) || \
|
26
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
|
23
27
|
FSEventStreamCreateFlags kFSEventStreamCreateFlagMarkSelf = 0x00000020;
|
24
28
|
FSEventStreamEventFlags kFSEventStreamEventFlagOwnEvent = 0x00080000;
|
25
29
|
#endif
|
30
|
+
|
31
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10) || \
|
32
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0)
|
33
|
+
FSEventStreamEventFlags kFSEventStreamEventFlagItemIsHardlink = 0x00100000;
|
34
|
+
FSEventStreamEventFlags kFSEventStreamEventFlagItemIsLastHardlink = 0x00200000;
|
35
|
+
#endif
|
36
|
+
|
37
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_13) || \
|
38
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0)
|
39
|
+
FSEventStreamCreateFlags kFSEventStreamCreateFlagUseExtendedData = 0x00000040;
|
40
|
+
FSEventStreamEventFlags kFSEventStreamEventFlagItemCloned = 0x00400000;
|
41
|
+
#endif
|
data/ext/fsevent_watch/compat.h
CHANGED
@@ -9,20 +9,57 @@
|
|
9
9
|
*/
|
10
10
|
|
11
11
|
|
12
|
-
#ifndef
|
13
|
-
#define
|
12
|
+
#ifndef listen_fsevents_compat_h
|
13
|
+
#define listen_fsevents_compat_h
|
14
14
|
|
15
15
|
#ifndef __CORESERVICES__
|
16
16
|
#include <CoreServices/CoreServices.h>
|
17
17
|
#endif // __CORESERVICES__
|
18
18
|
|
19
|
-
#
|
20
|
-
|
19
|
+
#ifndef __AVAILABILITY__
|
20
|
+
#include <Availability.h>
|
21
|
+
#endif // __AVAILABILITY__
|
22
|
+
|
23
|
+
#ifndef __MAC_10_6
|
24
|
+
#define __MAC_10_6 1060
|
25
|
+
#endif
|
26
|
+
#ifndef __MAC_10_7
|
27
|
+
#define __MAC_10_7 1070
|
28
|
+
#endif
|
29
|
+
#ifndef __MAC_10_9
|
30
|
+
#define __MAC_10_9 1090
|
31
|
+
#endif
|
32
|
+
#ifndef __MAC_10_10
|
33
|
+
#define __MAC_10_10 101000
|
34
|
+
#endif
|
35
|
+
#ifndef __MAC_10_13
|
36
|
+
#define __MAC_10_13 101300
|
37
|
+
#endif
|
38
|
+
#ifndef __IPHONE_6_0
|
39
|
+
#define __IPHONE_6_0 60000
|
40
|
+
#endif
|
41
|
+
#ifndef __IPHONE_7_0
|
42
|
+
#define __IPHONE_7_0 70000
|
43
|
+
#endif
|
44
|
+
#ifndef __IPHONE_9_0
|
45
|
+
#define __IPHONE_9_0 90000
|
46
|
+
#endif
|
47
|
+
#ifndef __IPHONE_11_0
|
48
|
+
#define __IPHONE_11_0 110000
|
49
|
+
#endif
|
50
|
+
|
51
|
+
#ifdef __cplusplus
|
52
|
+
extern "C" {
|
53
|
+
#endif
|
54
|
+
|
55
|
+
|
56
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6) || \
|
57
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
|
21
58
|
extern FSEventStreamCreateFlags kFSEventStreamCreateFlagIgnoreSelf;
|
22
59
|
#endif
|
23
60
|
|
24
|
-
#if MAC_OS_X_VERSION_MAX_ALLOWED <
|
25
|
-
|
61
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7) || \
|
62
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
|
26
63
|
extern FSEventStreamCreateFlags kFSEventStreamCreateFlagFileEvents;
|
27
64
|
extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated,
|
28
65
|
kFSEventStreamEventFlagItemRemoved,
|
@@ -37,11 +74,27 @@ extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated,
|
|
37
74
|
kFSEventStreamEventFlagItemIsSymlink;
|
38
75
|
#endif
|
39
76
|
|
40
|
-
#if MAC_OS_X_VERSION_MAX_ALLOWED <
|
41
|
-
|
77
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9) || \
|
78
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
|
42
79
|
extern FSEventStreamCreateFlags kFSEventStreamCreateFlagMarkSelf;
|
43
80
|
extern FSEventStreamEventFlags kFSEventStreamEventFlagOwnEvent;
|
44
81
|
#endif
|
45
82
|
|
83
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10) || \
|
84
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0)
|
85
|
+
extern FSEventStreamEventFlags kFSEventStreamEventFlagItemIsHardlink,
|
86
|
+
kFSEventStreamEventFlagItemIsLastHardlink;
|
87
|
+
#endif
|
88
|
+
|
89
|
+
#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_13) || \
|
90
|
+
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0)
|
91
|
+
extern FSEventStreamCreateFlags kFSEventStreamCreateFlagUseExtendedData;
|
92
|
+
extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCloned;
|
93
|
+
#endif
|
94
|
+
|
95
|
+
|
96
|
+
#ifdef __cplusplus
|
97
|
+
}
|
98
|
+
#endif
|
46
99
|
|
47
|
-
#endif //
|
100
|
+
#endif // listen_fsevents_compat_h
|
data/ext/fsevent_watch/main.c
CHANGED
@@ -24,7 +24,7 @@ static struct {
|
|
24
24
|
(double) 0.3,
|
25
25
|
(CFOptionFlags) kFSEventStreamCreateFlagNone,
|
26
26
|
NULL,
|
27
|
-
|
27
|
+
kFSEventWatchOutputFormatOTNetstring
|
28
28
|
};
|
29
29
|
|
30
30
|
// Prototypes
|
@@ -350,18 +350,54 @@ static void tstring_output_format(size_t numEvents,
|
|
350
350
|
false);
|
351
351
|
CFDictionarySetValue(event, CFSTR("path"), path);
|
352
352
|
|
353
|
-
CFNumberRef flags = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &eventFlags[i]);
|
354
|
-
CFDictionarySetValue(event, CFSTR("flags"), flags);
|
355
|
-
|
356
353
|
CFNumberRef ident = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &eventIds[i]);
|
357
354
|
CFDictionarySetValue(event, CFSTR("id"), ident);
|
358
355
|
|
356
|
+
CFNumberRef cflags = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &eventFlags[i]);
|
357
|
+
CFDictionarySetValue(event, CFSTR("cflags"), cflags);
|
358
|
+
|
359
|
+
CFMutableArrayRef flags = CFArrayCreateMutable(kCFAllocatorDefault,
|
360
|
+
0, &kCFTypeArrayCallBacks);
|
361
|
+
|
362
|
+
#define FLAG_ADD_NAME(flagsnum, flagnum, flagname, flagarray) \
|
363
|
+
do { \
|
364
|
+
if (FLAG_CHECK(flagsnum, flagnum)) { \
|
365
|
+
CFArrayAppendValue(flagarray, CFSTR(flagname)); } } \
|
366
|
+
while(0)
|
367
|
+
|
368
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagMustScanSubDirs, "MustScanSubDirs", flags);
|
369
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagUserDropped, "UserDropped", flags);
|
370
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagKernelDropped, "KernelDropped", flags);
|
371
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagEventIdsWrapped, "EventIdsWrapped", flags);
|
372
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagHistoryDone, "HistoryDone", flags);
|
373
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagRootChanged, "RootChanged", flags);
|
374
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagMount, "Mount", flags);
|
375
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagUnmount, "Unmount", flags);
|
376
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemCreated, "ItemCreated", flags);
|
377
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemRemoved, "ItemRemoved", flags);
|
378
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemInodeMetaMod, "ItemInodeMetaMod", flags);
|
379
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemRenamed, "ItemRenamed", flags);
|
380
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemModified, "ItemModified", flags);
|
381
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemFinderInfoMod, "ItemFinderInfoMod", flags);
|
382
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemChangeOwner, "ItemChangeOwner", flags);
|
383
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemXattrMod, "ItemXattrMod", flags);
|
384
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsFile, "ItemIsFile", flags);
|
385
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsDir, "ItemIsDir", flags);
|
386
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsSymlink, "ItemIsSymlink", flags);
|
387
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagOwnEvent, "OwnEvent", flags);
|
388
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsHardlink, "ItemIsHardLink", flags);
|
389
|
+
FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsLastHardlink, "ItemIsLastHardLink", flags);
|
390
|
+
|
391
|
+
CFDictionarySetValue(event, CFSTR("flags"), flags);
|
392
|
+
|
393
|
+
|
359
394
|
CFArrayAppendValue(events, event);
|
360
395
|
|
361
396
|
CFRelease(event);
|
362
397
|
CFRelease(path);
|
363
|
-
CFRelease(flags);
|
364
398
|
CFRelease(ident);
|
399
|
+
CFRelease(cflags);
|
400
|
+
CFRelease(flags);
|
365
401
|
}
|
366
402
|
|
367
403
|
CFMutableDictionaryRef meta = CFDictionaryCreateMutable(kCFAllocatorDefault,
|
@@ -446,7 +482,10 @@ static void callback(__attribute__((unused)) FSEventStreamRef streamRef,
|
|
446
482
|
" Item is a directory");
|
447
483
|
FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsSymlink,
|
448
484
|
" Item is a symbolic link");
|
449
|
-
|
485
|
+
FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsHardlink,
|
486
|
+
" Item is a hard link");
|
487
|
+
FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsLastHardlink,
|
488
|
+
" Item is the last hard link");
|
450
489
|
fprintf(stderr, " event path: %s\n", paths[i]);
|
451
490
|
fprintf(stderr, "\n");
|
452
491
|
}
|
data/ext/rakefile.rb
CHANGED
@@ -8,7 +8,7 @@ require 'rake/clean'
|
|
8
8
|
raise "unable to find xcodebuild" unless system('which', 'xcodebuild')
|
9
9
|
|
10
10
|
|
11
|
-
FSEVENT_WATCH_EXE_VERSION = '0.1.
|
11
|
+
FSEVENT_WATCH_EXE_VERSION = '0.1.5'
|
12
12
|
|
13
13
|
$this_dir = Pathname.new(__FILE__).dirname.expand_path
|
14
14
|
$final_exe = $this_dir.parent.join('bin/fsevent_watch')
|
@@ -148,7 +148,7 @@ file $obj_dir.join('Info.plist').to_s => [$obj_dir.to_s, :setup_env] do
|
|
148
148
|
key['CFBundleDisplayName']
|
149
149
|
string['FSEvent Watch CLI']
|
150
150
|
key['NSHumanReadableCopyright']
|
151
|
-
string['Copyright (C) 2011-
|
151
|
+
string['Copyright (C) 2011-2017 Travis Tilley']
|
152
152
|
|
153
153
|
key['CFBundleVersion']
|
154
154
|
string["#{FSEVENT_WATCH_EXE_VERSION}"]
|
@@ -216,8 +216,10 @@ task :codesign => :build do
|
|
216
216
|
sh "codesign -s '#{$CODE_SIGN_IDENTITY}' #{$obj_dir.join('fsevent_watch')}"
|
217
217
|
end
|
218
218
|
|
219
|
+
directory $this_dir.parent.join('bin')
|
220
|
+
|
219
221
|
desc 'replace bundled fsevent_watch binary with build/fsevent_watch'
|
220
|
-
task :replace_exe => :build do
|
222
|
+
task :replace_exe => [$this_dir.parent.join('bin'), :build] do
|
221
223
|
sh "mv #{$obj_dir.join('fsevent_watch')} #{$final_exe}"
|
222
224
|
end
|
223
225
|
|
data/lib/otnetstring.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright (c) 2011 Konstantin Haase
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
|
22
|
+
require 'stringio'
|
23
|
+
|
24
|
+
module OTNetstring
|
25
|
+
class Error < StandardError; end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def parse(io, encoding = 'internal', fallback_encoding = nil)
|
29
|
+
fallback_encoding = io.encoding if io.respond_to? :encoding
|
30
|
+
io = StringIO.new(io) if io.respond_to? :to_str
|
31
|
+
length, byte = "", nil
|
32
|
+
|
33
|
+
while byte.nil? || byte =~ /\d/
|
34
|
+
length << byte if byte
|
35
|
+
byte = io.read(1)
|
36
|
+
end
|
37
|
+
|
38
|
+
if length.size > 9
|
39
|
+
raise Error, "#{length} is longer than 9 digits"
|
40
|
+
elsif length !~ /\d+/
|
41
|
+
raise Error, "Expected '#{byte}' to be a digit"
|
42
|
+
end
|
43
|
+
length = Integer(length)
|
44
|
+
|
45
|
+
case byte
|
46
|
+
when '#' then Integer io.read(length)
|
47
|
+
when ',' then with_encoding io.read(length), encoding, fallback_encoding
|
48
|
+
when '~' then
|
49
|
+
raise Error, "nil has length of 0, #{length} given" unless length == 0
|
50
|
+
when '!' then io.read(length) == 'true'
|
51
|
+
when '[', '{'
|
52
|
+
array = []
|
53
|
+
start = io.pos
|
54
|
+
array << parse(io, encoding, fallback_encoding) while io.pos - start < length
|
55
|
+
raise Error, 'Nested element longer than container' if io.pos - start != length
|
56
|
+
byte == "{" ? Hash[*array] : array
|
57
|
+
else
|
58
|
+
raise Error, "Unknown type '#{byte}'"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def encode(obj, string_sep = ',')
|
63
|
+
case obj
|
64
|
+
when String then with_encoding "#{obj.bytesize}#{string_sep}#{obj}", "binary"
|
65
|
+
when Integer then encode(obj.inspect, '#')
|
66
|
+
when NilClass then "0~"
|
67
|
+
when Array then encode(obj.map { |e| encode(e) }.join, '[')
|
68
|
+
when Hash then encode(obj.map { |a,b| encode(a)+encode(b) }.join, '{')
|
69
|
+
when FalseClass, TrueClass then encode(obj.inspect, '!')
|
70
|
+
else raise Error, 'cannot encode %p' % obj
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def with_encoding(str, encoding, fallback = nil)
|
77
|
+
return str unless str.respond_to? :encode
|
78
|
+
encoding = Encoding.find encoding if encoding.respond_to? :to_str
|
79
|
+
encoding ||= fallback
|
80
|
+
encoding ? str.encode(encoding) : str
|
81
|
+
rescue EncodingError
|
82
|
+
str.force_encoding(encoding)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/rb-fsevent/fsevent.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
+
require 'otnetstring'
|
4
|
+
|
3
5
|
class FSEvent
|
4
6
|
class << self
|
5
7
|
class_eval <<-END
|
@@ -40,9 +42,41 @@ class FSEvent
|
|
40
42
|
# please note the use of IO::select() here, as it is used specifically to
|
41
43
|
# preserve correct signal handling behavior in ruby 1.8.
|
42
44
|
while @running && IO::select([@pipe], nil, nil, nil)
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
# managing the IO ourselves allows us to be careful and never pass an
|
46
|
+
# incomplete message to OTNetstring.parse()
|
47
|
+
message = ""
|
48
|
+
length = ""
|
49
|
+
byte = nil
|
50
|
+
|
51
|
+
reading_length = true
|
52
|
+
found_length = false
|
53
|
+
|
54
|
+
while reading_length
|
55
|
+
byte = @pipe.read(1)
|
56
|
+
if "#{byte}" =~ /\d/
|
57
|
+
length << byte
|
58
|
+
found_length = true
|
59
|
+
elsif found_length == false
|
60
|
+
next
|
61
|
+
else
|
62
|
+
reading_length = false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
length = Integer(length, 10)
|
66
|
+
type = byte
|
67
|
+
|
68
|
+
message << "#{length}#{type}"
|
69
|
+
message << @pipe.read(length)
|
70
|
+
|
71
|
+
decoded = OTNetstring.parse(message)
|
72
|
+
modified_paths = decoded["events"].map {|event| event["path"]}
|
73
|
+
# passing the full info as a second block param feels icky, but such is
|
74
|
+
# the trap of backward compatibility.
|
75
|
+
case callback.arity
|
76
|
+
when 1
|
77
|
+
callback.call(modified_paths)
|
78
|
+
when 2
|
79
|
+
callback.call(modified_paths, decoded)
|
46
80
|
end
|
47
81
|
end
|
48
82
|
rescue Interrupt, IOError, Errno::EBADF
|
@@ -110,7 +144,7 @@ class FSEvent
|
|
110
144
|
private
|
111
145
|
|
112
146
|
def parse_options(options={})
|
113
|
-
opts = []
|
147
|
+
opts = ['--format=otnetstring']
|
114
148
|
opts.concat(['--since-when', options[:since_when]]) if options[:since_when]
|
115
149
|
opts.concat(['--latency', options[:latency]]) if options[:latency]
|
116
150
|
opts.push('--no-defer') if options[:no_defer]
|
data/lib/rb-fsevent/version.rb
CHANGED
data/rb-fsevent.gemspec
CHANGED
@@ -13,10 +13,15 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.description = 'FSEvents API with Signals catching (without RubyCocoa)'
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
+
s.metadata = {
|
17
|
+
'source_code_uri' => 'https://github.com/thibaudgg/rb-fsevent'
|
18
|
+
}
|
19
|
+
|
16
20
|
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
|
17
21
|
s.require_path = 'lib'
|
18
22
|
|
19
23
|
s.add_development_dependency 'bundler', '~> 1.0'
|
20
|
-
s.add_development_dependency 'rspec', '~>
|
24
|
+
s.add_development_dependency 'rspec', '~> 3.6'
|
21
25
|
s.add_development_dependency 'guard-rspec', '~> 4.2'
|
26
|
+
s.add_development_dependency 'rake', '~> 12.0'
|
22
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rb-fsevent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibaud Guillaume-Gentil
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-07-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '3.6'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
41
|
+
version: '3.6'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: guard-rspec
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '4.2'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rake
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '12.0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '12.0'
|
56
70
|
description: FSEvents API with Signals catching (without RubyCocoa)
|
57
71
|
email:
|
58
72
|
- thibaud@thibaud.gg
|
@@ -83,6 +97,7 @@ files:
|
|
83
97
|
- ext/fsevent_watch/signal_handlers.c
|
84
98
|
- ext/fsevent_watch/signal_handlers.h
|
85
99
|
- ext/rakefile.rb
|
100
|
+
- lib/otnetstring.rb
|
86
101
|
- lib/rb-fsevent.rb
|
87
102
|
- lib/rb-fsevent/fsevent.rb
|
88
103
|
- lib/rb-fsevent/version.rb
|
@@ -90,7 +105,8 @@ files:
|
|
90
105
|
homepage: http://rubygems.org/gems/rb-fsevent
|
91
106
|
licenses:
|
92
107
|
- MIT
|
93
|
-
metadata:
|
108
|
+
metadata:
|
109
|
+
source_code_uri: https://github.com/thibaudgg/rb-fsevent
|
94
110
|
post_install_message:
|
95
111
|
rdoc_options: []
|
96
112
|
require_paths:
|
@@ -107,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
123
|
version: '0'
|
108
124
|
requirements: []
|
109
125
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
126
|
+
rubygems_version: 2.6.11
|
111
127
|
signing_key:
|
112
128
|
specification_version: 4
|
113
129
|
summary: Very simple & usable FSEvents API
|