filewatcher 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/filewatcher.rb +3 -2
- data/lib/filewatcher/env.rb +6 -2
- data/lib/filewatcher/version.rb +1 -1
- data/test/helper.rb +119 -37
- data/test/test_filewatcher.rb +63 -28
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9221be161e73cc2f85ea6f9706a2e558c31ff314664bc31817e9715439a31927
|
4
|
+
data.tar.gz: bae2bc1ba2f5b88693fe1c8093b135652885094c69adc3da51193916ada96b44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0aec2e10e03aad69fd0e4ccda0a6f488efc7c908abe31640319971dda6ed71ca8873588d87693f91309d13ac996bb62a952e3c7430c41b462d663e0064185e8e
|
7
|
+
data.tar.gz: ebf1581b4e3e56c77c4a18867ce55d2cb9a6fbf97d7804da305192dd9622a39d9b16cfe1392dd880c6dd1c43f47539a66a10f61956de7fad0202f2c43222b64d
|
data/lib/filewatcher.rb
CHANGED
@@ -8,7 +8,8 @@ require_relative 'filewatcher/cycles'
|
|
8
8
|
class Filewatcher
|
9
9
|
include Filewatcher::Cycles
|
10
10
|
|
11
|
-
|
11
|
+
attr_accessor :interval
|
12
|
+
attr_reader :keep_watching
|
12
13
|
|
13
14
|
def update_spinner(label)
|
14
15
|
return unless @show_spinner
|
@@ -28,7 +29,7 @@ class Filewatcher
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def watch(&on_update)
|
31
|
-
trap(
|
32
|
+
%w[HUP INT TERM].each { |signal| trap(signal) { exit } }
|
32
33
|
@on_update = on_update
|
33
34
|
@keep_watching = true
|
34
35
|
yield('', '') if @immediate
|
data/lib/filewatcher/env.rb
CHANGED
@@ -10,8 +10,12 @@ class Filewatcher
|
|
10
10
|
@filename = filename
|
11
11
|
@event = event
|
12
12
|
@path = Pathname.new(@filename)
|
13
|
-
@realpath = @path.realpath
|
13
|
+
@realpath = @path.exist? ? @path.realpath : @path
|
14
14
|
@current_dir = Pathname.new(Dir.pwd)
|
15
|
+
# For safely `immediate` option with empty-strings arguments
|
16
|
+
@relative_path =
|
17
|
+
(@realpath.to_s.empty? ? @current_dir : @realpath)
|
18
|
+
.relative_path_from(@current_dir)
|
15
19
|
end
|
16
20
|
|
17
21
|
def to_h
|
@@ -22,7 +26,7 @@ class Filewatcher
|
|
22
26
|
'EVENT' => @event.to_s,
|
23
27
|
'DIRNAME' => @path.parent.realpath.to_s,
|
24
28
|
'ABSOLUTE_FILENAME' => @realpath.to_s,
|
25
|
-
'RELATIVE_FILENAME' => @
|
29
|
+
'RELATIVE_FILENAME' => @relative_path.to_s
|
26
30
|
}
|
27
31
|
end
|
28
32
|
end
|
data/lib/filewatcher/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -12,50 +12,93 @@ end
|
|
12
12
|
class WatchRun
|
13
13
|
TMP_DIR = File.join(__dir__, 'tmp')
|
14
14
|
|
15
|
-
attr_reader :filename
|
15
|
+
attr_reader :filename
|
16
16
|
|
17
17
|
def initialize(
|
18
18
|
filename: 'tmp_file.txt',
|
19
19
|
directory: false,
|
20
|
-
every: false,
|
21
|
-
filewatcher: Filewatcher.new(
|
22
|
-
File.join(TMP_DIR, '**', '*'), interval: 0.1, every: every
|
23
|
-
),
|
24
20
|
action: :update
|
25
21
|
)
|
26
22
|
@filename =
|
27
23
|
filename.start_with?('/', '~') ? filename : File.join(TMP_DIR, filename)
|
28
24
|
@directory = directory
|
29
|
-
@filewatcher = filewatcher
|
30
25
|
@action = action
|
31
26
|
end
|
32
27
|
|
33
28
|
def start
|
34
29
|
File.write(@filename, 'content1') unless @action == :create
|
35
|
-
|
36
|
-
@thread = thread_initialize
|
37
|
-
sleep 3 # thread needs a chance to start
|
38
30
|
end
|
39
31
|
|
40
32
|
def run
|
41
33
|
start
|
42
34
|
|
43
35
|
make_changes
|
44
|
-
# Some OS, filesystems and Ruby interpretators
|
45
|
-
# doesn't catch milliseconds of `File.mtime`
|
46
|
-
sleep 3
|
47
36
|
|
48
37
|
stop
|
49
38
|
end
|
50
39
|
|
51
40
|
def stop
|
52
41
|
FileUtils.rm_r(@filename) if File.exist?(@filename)
|
53
|
-
@thread.exit
|
54
|
-
sleep 3
|
55
42
|
end
|
56
43
|
|
57
44
|
private
|
58
45
|
|
46
|
+
def make_changes
|
47
|
+
if @action == :delete
|
48
|
+
FileUtils.remove(@filename)
|
49
|
+
elsif @directory
|
50
|
+
FileUtils.mkdir_p(@filename)
|
51
|
+
else
|
52
|
+
File.write(@filename, 'content2')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class RubyWatchRun < WatchRun
|
58
|
+
attr_reader :filewatcher, :thread, :watched, :processed
|
59
|
+
|
60
|
+
def initialize(
|
61
|
+
every: false,
|
62
|
+
filewatcher: Filewatcher.new(
|
63
|
+
File.join(TMP_DIR, '**', '*'), interval: 0.1, every: every
|
64
|
+
),
|
65
|
+
**args
|
66
|
+
)
|
67
|
+
super(**args)
|
68
|
+
@filewatcher = filewatcher
|
69
|
+
end
|
70
|
+
|
71
|
+
def start
|
72
|
+
super
|
73
|
+
@thread = thread_initialize
|
74
|
+
# thread needs a chance to start
|
75
|
+
wait 3 do
|
76
|
+
filewatcher.keep_watching
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def stop
|
81
|
+
thread.exit
|
82
|
+
|
83
|
+
wait 3 do
|
84
|
+
thread.stop?
|
85
|
+
end
|
86
|
+
|
87
|
+
super
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def make_changes
|
93
|
+
super
|
94
|
+
|
95
|
+
# Some OS, filesystems and Ruby interpretators
|
96
|
+
# doesn't catch milliseconds of `File.mtime`
|
97
|
+
wait 3 do
|
98
|
+
processed.any?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
59
102
|
def thread_initialize
|
60
103
|
@watched ||= 0
|
61
104
|
Thread.new(
|
@@ -72,56 +115,95 @@ class WatchRun
|
|
72
115
|
@watched += 1
|
73
116
|
end
|
74
117
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
118
|
+
def wait(seconds)
|
119
|
+
max_count = seconds / filewatcher.interval
|
120
|
+
count = 0
|
121
|
+
while count < max_count && !yield
|
122
|
+
sleep filewatcher.interval
|
123
|
+
count += 1
|
124
|
+
end
|
79
125
|
end
|
80
126
|
end
|
81
127
|
|
82
|
-
class ShellWatchRun
|
128
|
+
class ShellWatchRun < WatchRun
|
83
129
|
EXECUTABLE = "#{'ruby ' if Gem.win_platform?}" \
|
84
130
|
"#{File.realpath File.join(__dir__, '..', 'bin', 'filewatcher')}".freeze
|
85
131
|
|
86
|
-
|
132
|
+
SLEEP_MULTIPLIER = RUBY_PLATFORM == 'java' ? 5 : 1
|
133
|
+
|
134
|
+
ENV_FILE = File.join(TMP_DIR, 'env')
|
87
135
|
|
88
136
|
def initialize(
|
89
|
-
options:
|
137
|
+
options: {},
|
90
138
|
dumper: :watched,
|
91
|
-
|
139
|
+
**args
|
92
140
|
)
|
141
|
+
super(**args)
|
93
142
|
@options = options
|
143
|
+
@options[:interval] ||= 0.1
|
144
|
+
@options_string =
|
145
|
+
@options.map { |key, value| "--#{key}=#{value}" }.join(' ')
|
94
146
|
@dumper = dumper
|
95
|
-
@output = output
|
96
147
|
end
|
97
148
|
|
98
149
|
def start
|
150
|
+
super
|
151
|
+
|
99
152
|
@pid = spawn(
|
100
|
-
"#{EXECUTABLE} #{@
|
101
|
-
" \"ruby #{File.join(__dir__, 'dumpers', "#{@dumper}_dumper.rb")}\""
|
153
|
+
"#{EXECUTABLE} #{@options_string} \"#{@filename}\"" \
|
154
|
+
" \"ruby #{File.join(__dir__, 'dumpers', "#{@dumper}_dumper.rb")}\"",
|
155
|
+
pgroup: true
|
102
156
|
)
|
103
|
-
Process.detach(@pid)
|
104
|
-
sleep 12
|
105
|
-
end
|
106
157
|
|
107
|
-
|
108
|
-
start
|
158
|
+
Process.detach(@pid)
|
109
159
|
|
110
|
-
|
160
|
+
wait 12 do
|
161
|
+
pid_state == 'S' && (!@options[:immediate] || File.exist?(ENV_FILE))
|
162
|
+
end
|
111
163
|
|
112
|
-
|
164
|
+
# a little more time
|
165
|
+
sleep 1 * SLEEP_MULTIPLIER
|
113
166
|
end
|
114
167
|
|
115
168
|
def stop
|
116
|
-
|
117
|
-
|
169
|
+
## Problems: https://github.com/thomasfl/filewatcher/pull/83
|
170
|
+
## Solution: https://stackoverflow.com/a/45032252/2630849
|
171
|
+
Process.kill('TERM', -Process.getpgid(@pid))
|
172
|
+
Process.waitall
|
173
|
+
|
174
|
+
wait 12 do
|
175
|
+
pid_state.empty?
|
176
|
+
end
|
177
|
+
|
178
|
+
# a little more time
|
179
|
+
sleep 1 * SLEEP_MULTIPLIER
|
180
|
+
|
181
|
+
super
|
118
182
|
end
|
119
183
|
|
120
184
|
private
|
121
185
|
|
122
186
|
def make_changes
|
123
|
-
|
124
|
-
|
187
|
+
super
|
188
|
+
|
189
|
+
wait 12 do
|
190
|
+
File.exist?(ENV_FILE)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def pid_state
|
195
|
+
## For macOS output:
|
196
|
+
## https://travis-ci.org/thomasfl/filewatcher/jobs/304433538
|
197
|
+
`ps -ho state -p #{@pid}`.sub('STAT', '').strip
|
198
|
+
end
|
199
|
+
|
200
|
+
def wait(seconds)
|
201
|
+
max_count = seconds / @options[:interval]
|
202
|
+
count = 0
|
203
|
+
while count < max_count && !yield
|
204
|
+
sleep @options[:interval]
|
205
|
+
count += 1
|
206
|
+
end
|
125
207
|
end
|
126
208
|
end
|
127
209
|
|
@@ -130,5 +212,5 @@ custom_matcher :include_all_files do |obj, elements|
|
|
130
212
|
end
|
131
213
|
|
132
214
|
def dump_to_env_file(content)
|
133
|
-
File.write File.join(
|
215
|
+
File.write File.join(ShellWatchRun::ENV_FILE), content
|
134
216
|
end
|
data/test/test_filewatcher.rb
CHANGED
@@ -10,11 +10,18 @@ describe Filewatcher do
|
|
10
10
|
|
11
11
|
after do
|
12
12
|
FileUtils.rm_r WatchRun::TMP_DIR
|
13
|
+
|
14
|
+
interval = 0.1
|
15
|
+
wait = 5
|
16
|
+
count = 0
|
17
|
+
while File.exist?(WatchRun::TMP_DIR) && count < (wait / interval)
|
18
|
+
sleep interval
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
describe '#initialize' do
|
16
23
|
it 'should exclude selected file patterns' do
|
17
|
-
wr =
|
24
|
+
wr = RubyWatchRun.new(
|
18
25
|
filewatcher: Filewatcher.new(
|
19
26
|
File.expand_path('test/tmp/**/*'),
|
20
27
|
exclude: File.expand_path('test/tmp/**/*.txt')
|
@@ -27,7 +34,7 @@ describe Filewatcher do
|
|
27
34
|
end
|
28
35
|
|
29
36
|
it 'should handle absolute paths with globs' do
|
30
|
-
wr =
|
37
|
+
wr = RubyWatchRun.new(
|
31
38
|
filewatcher: Filewatcher.new(
|
32
39
|
File.expand_path('test/tmp/**/*')
|
33
40
|
)
|
@@ -41,7 +48,7 @@ describe Filewatcher do
|
|
41
48
|
end
|
42
49
|
|
43
50
|
it 'should handle globs' do
|
44
|
-
wr =
|
51
|
+
wr = RubyWatchRun.new(
|
45
52
|
filewatcher: Filewatcher.new('test/tmp/**/*')
|
46
53
|
)
|
47
54
|
|
@@ -53,7 +60,7 @@ describe Filewatcher do
|
|
53
60
|
end
|
54
61
|
|
55
62
|
it 'should handle explicit relative paths with globs' do
|
56
|
-
wr =
|
63
|
+
wr = RubyWatchRun.new(
|
57
64
|
filewatcher: Filewatcher.new('./test/tmp/**/*')
|
58
65
|
)
|
59
66
|
|
@@ -65,7 +72,7 @@ describe Filewatcher do
|
|
65
72
|
end
|
66
73
|
|
67
74
|
it 'should handle explicit relative paths' do
|
68
|
-
wr =
|
75
|
+
wr = RubyWatchRun.new(
|
69
76
|
filewatcher: Filewatcher.new('./test/tmp')
|
70
77
|
)
|
71
78
|
|
@@ -79,7 +86,7 @@ describe Filewatcher do
|
|
79
86
|
it 'should handle tilde expansion' do
|
80
87
|
filename = File.expand_path('~/file_watcher_1.txt')
|
81
88
|
|
82
|
-
wr =
|
89
|
+
wr = RubyWatchRun.new(
|
83
90
|
filename: filename,
|
84
91
|
filewatcher: Filewatcher.new('~/file_watcher_1.txt')
|
85
92
|
)
|
@@ -92,7 +99,7 @@ describe Filewatcher do
|
|
92
99
|
end
|
93
100
|
|
94
101
|
it 'should immediately run with corresponding option' do
|
95
|
-
wr =
|
102
|
+
wr = RubyWatchRun.new(
|
96
103
|
filewatcher: Filewatcher.new('**/*', immediate: true)
|
97
104
|
)
|
98
105
|
|
@@ -104,7 +111,7 @@ describe Filewatcher do
|
|
104
111
|
end
|
105
112
|
|
106
113
|
it 'should not be executed without immediate option and changes' do
|
107
|
-
wr =
|
114
|
+
wr = RubyWatchRun.new(
|
108
115
|
filewatcher: Filewatcher.new('**/*', immediate: false)
|
109
116
|
)
|
110
117
|
|
@@ -118,7 +125,7 @@ describe Filewatcher do
|
|
118
125
|
|
119
126
|
describe '#watch' do
|
120
127
|
it 'should detect file deletions' do
|
121
|
-
wr =
|
128
|
+
wr = RubyWatchRun.new(action: :delete)
|
122
129
|
|
123
130
|
wr.run
|
124
131
|
|
@@ -128,7 +135,7 @@ describe Filewatcher do
|
|
128
135
|
end
|
129
136
|
|
130
137
|
it 'should detect file additions' do
|
131
|
-
wr =
|
138
|
+
wr = RubyWatchRun.new(action: :create)
|
132
139
|
|
133
140
|
wr.run
|
134
141
|
|
@@ -138,7 +145,7 @@ describe Filewatcher do
|
|
138
145
|
end
|
139
146
|
|
140
147
|
it 'should detect file updates' do
|
141
|
-
wr =
|
148
|
+
wr = RubyWatchRun.new(action: :update)
|
142
149
|
|
143
150
|
wr.run
|
144
151
|
|
@@ -150,7 +157,7 @@ describe Filewatcher do
|
|
150
157
|
it 'should detect new files in subfolders' do
|
151
158
|
FileUtils.mkdir_p subfolder = File.expand_path('test/tmp/new_sub_folder')
|
152
159
|
|
153
|
-
wr =
|
160
|
+
wr = RubyWatchRun.new(
|
154
161
|
filename: File.join(subfolder, 'file.txt'),
|
155
162
|
action: :create,
|
156
163
|
every: true
|
@@ -167,7 +174,7 @@ describe Filewatcher do
|
|
167
174
|
it 'should detect new subfolders' do
|
168
175
|
subfolder = 'new_sub_folder'
|
169
176
|
|
170
|
-
wr =
|
177
|
+
wr = RubyWatchRun.new(
|
171
178
|
filename: subfolder,
|
172
179
|
directory: true,
|
173
180
|
action: :create
|
@@ -183,7 +190,7 @@ describe Filewatcher do
|
|
183
190
|
|
184
191
|
describe '#stop' do
|
185
192
|
it 'should work' do
|
186
|
-
wr =
|
193
|
+
wr = RubyWatchRun.new
|
187
194
|
|
188
195
|
wr.start
|
189
196
|
|
@@ -196,7 +203,7 @@ describe Filewatcher do
|
|
196
203
|
|
197
204
|
describe '#pause, #resume' do
|
198
205
|
it 'should work' do
|
199
|
-
wr =
|
206
|
+
wr = RubyWatchRun.new(action: :create, every: true)
|
200
207
|
|
201
208
|
wr.start
|
202
209
|
|
@@ -230,7 +237,7 @@ describe Filewatcher do
|
|
230
237
|
|
231
238
|
describe '#finalize' do
|
232
239
|
it 'should process all remaining changes' do
|
233
|
-
wr =
|
240
|
+
wr = RubyWatchRun.new(action: :create, every: true)
|
234
241
|
|
235
242
|
wr.start
|
236
243
|
|
@@ -249,7 +256,7 @@ describe Filewatcher do
|
|
249
256
|
end
|
250
257
|
|
251
258
|
describe 'executable' do
|
252
|
-
tmp_dir =
|
259
|
+
tmp_dir = ShellWatchRun::TMP_DIR
|
253
260
|
|
254
261
|
it 'should run' do
|
255
262
|
null_output = Gem.win_platform? ? 'NUL' : '/dev/null'
|
@@ -257,49 +264,77 @@ describe Filewatcher do
|
|
257
264
|
.should.be.true
|
258
265
|
end
|
259
266
|
|
260
|
-
it 'should set correct ENV variables' do
|
267
|
+
it 'should set correct ENV variables for file creation' do
|
268
|
+
filename = 'foo.txt'
|
269
|
+
|
261
270
|
swr = ShellWatchRun.new(
|
271
|
+
filename: filename,
|
272
|
+
action: :create,
|
262
273
|
dumper: :env
|
263
274
|
)
|
264
275
|
|
265
276
|
swr.run
|
266
277
|
|
267
|
-
File.read(
|
278
|
+
File.read(ShellWatchRun::ENV_FILE)
|
268
279
|
.should.equal(
|
269
280
|
%W[
|
270
|
-
#{tmp_dir}
|
271
|
-
|
281
|
+
#{tmp_dir}/#{filename}
|
282
|
+
#{filename}
|
272
283
|
created
|
273
284
|
#{tmp_dir}
|
274
|
-
#{tmp_dir}
|
275
|
-
test/tmp
|
285
|
+
#{tmp_dir}/#{filename}
|
286
|
+
test/tmp/#{filename}
|
287
|
+
].join(', ')
|
288
|
+
)
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should set correct ENV variables for file deletion' do
|
292
|
+
filename = 'foo.txt'
|
293
|
+
|
294
|
+
swr = ShellWatchRun.new(
|
295
|
+
filename: filename,
|
296
|
+
action: :delete,
|
297
|
+
dumper: :env
|
298
|
+
)
|
299
|
+
|
300
|
+
swr.run
|
301
|
+
|
302
|
+
File.read(ShellWatchRun::ENV_FILE)
|
303
|
+
.should.equal(
|
304
|
+
%W[
|
305
|
+
#{tmp_dir}/#{filename}
|
306
|
+
#{filename}
|
307
|
+
deleted
|
308
|
+
#{tmp_dir}
|
309
|
+
#{tmp_dir}/#{filename}
|
310
|
+
test/tmp/#{filename}
|
276
311
|
].join(', ')
|
277
312
|
)
|
278
313
|
end
|
279
314
|
|
280
315
|
it 'should be executed immediately with corresponding option' do
|
281
316
|
swr = ShellWatchRun.new(
|
282
|
-
options:
|
317
|
+
options: { immediate: true },
|
283
318
|
dumper: :watched
|
284
319
|
)
|
285
320
|
|
286
321
|
swr.start
|
287
322
|
swr.stop
|
288
323
|
|
289
|
-
File.exist?(
|
290
|
-
File.read(
|
324
|
+
File.exist?(ShellWatchRun::ENV_FILE).should.be.true
|
325
|
+
File.read(ShellWatchRun::ENV_FILE).should.equal 'watched'
|
291
326
|
end
|
292
327
|
|
293
328
|
it 'should not be executed without immediate option and changes' do
|
294
329
|
swr = ShellWatchRun.new(
|
295
|
-
options:
|
330
|
+
options: {},
|
296
331
|
dumper: :watched
|
297
332
|
)
|
298
333
|
|
299
334
|
swr.start
|
300
335
|
swr.stop
|
301
336
|
|
302
|
-
File.exist?(
|
337
|
+
File.exist?(ShellWatchRun::ENV_FILE).should.be.false
|
303
338
|
end
|
304
339
|
end
|
305
340
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: filewatcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Flemming
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bacon
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: trollop
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,19 +59,19 @@ dependencies:
|
|
45
59
|
- !ruby/object:Gem::Version
|
46
60
|
version: '12.0'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
62
|
+
name: rubocop
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
50
64
|
requirements:
|
51
65
|
- - "~>"
|
52
66
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
67
|
+
version: '0.51'
|
54
68
|
type: :development
|
55
69
|
prerelease: false
|
56
70
|
version_requirements: !ruby/object:Gem::Requirement
|
57
71
|
requirements:
|
58
72
|
- - "~>"
|
59
73
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
74
|
+
version: '0.51'
|
61
75
|
description: Detect changes in filesystem. Works anywhere.
|
62
76
|
email:
|
63
77
|
- thomas.flemming@gmail.com
|
@@ -100,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
114
|
version: '0'
|
101
115
|
requirements: []
|
102
116
|
rubyforge_project:
|
103
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.7.2
|
104
118
|
signing_key:
|
105
119
|
specification_version: 4
|
106
120
|
summary: Lighweight filewatcher.
|