rb-fsevent 0.9.8 → 0.10.2
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.
- 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
|