nite-owl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 98012eb7fa0d83d070a5ea27e9a802124506d3f8
4
+ data.tar.gz: 68149cdad3bcb5156e72318ad43b0354be15f63f
5
+ SHA512:
6
+ metadata.gz: cbba57bfcd8f61d35a1bacb5d80c4cb2b520af292688d01e2f6def2a6d10095b4eb3b8b9f41b92abdb5d98760ca09251550190b252a53ad95b1ee4e7a8491414
7
+ data.tar.gz: 1ec829878b577acc16a501a0d75a494223bb1a71c69aa380b5b8a6268e0ad8a26871ab0d8767ab8a3b1177dc3dbc356575faff35b12fae7f671f928e06489d07
@@ -0,0 +1,12 @@
1
+ *.lock
2
+ /.bundle/
3
+ /.yardoc
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in nite-owl.gemspec
6
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 troydm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/Niteowl ADDED
@@ -0,0 +1,14 @@
1
+ whenever(/.*rb/)
2
+ .changes
3
+ .after(5.seconds)
4
+ .if_not {
5
+ false
6
+ }
7
+ .run do |n,f|
8
+ puts "Hello World"
9
+ cancel
10
+ shell "ls -lh"
11
+ end
12
+ .also.run do |n,f|
13
+ puts "Change detected "+n.to_s+" "+f.to_s
14
+ end
@@ -0,0 +1,29 @@
1
+ # Nite::Owl [![Gem Version](https://badge.fury.io/rb/nite-owl.svg)](https://badge.fury.io/rb/nite-owl) [![Build Status](https://travis-ci.org/troydm/nite-owl.png?branch=master)](https://travis-ci.org/troydm/nite-owl)
2
+
3
+ Nite Owl watches over your files and executes commands if anything happens to them, it's like [guard](https://github.com/guard/guard) on a super diet!
4
+ Supports linux and macos only and depends only on rb-fsevent and rb-inotify.
5
+
6
+ ## Installation
7
+
8
+ To install just run this command:
9
+
10
+ $ gem install nite-owl
11
+
12
+ ## Usage
13
+
14
+ Create Niteowl configuration file inside a directory you want to watch over and the run nite-owl.
15
+ See example Niteowl configuration file.
16
+
17
+ ## Development
18
+
19
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
20
+
21
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
22
+
23
+ ## Contributing
24
+
25
+ Bug reports and pull requests are welcome on GitHub at https://github.com/troydm/nite-owl.
26
+
27
+ ## License
28
+
29
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "nite/owl"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ require "nite/owl"
3
+
4
+ if ARGV.empty?
5
+ Nite::Owl::NiteOwl.instance.watch(Dir.pwd)
6
+ else
7
+ Nite::Owl::NiteOwl.instance.watch(ARGV[0])
8
+ end
9
+
10
+ Nite::Owl::NiteOwl.instance.start
@@ -0,0 +1,2 @@
1
+ require "nite/owl/version"
2
+ require "nite/owl/niteowl"
@@ -0,0 +1,564 @@
1
+ require 'open3'
2
+
3
+ # Nite Owl DSL
4
+ def quote(path)
5
+ if path.include? " "
6
+ "\"#{path}\""
7
+ else
8
+ path
9
+ end
10
+ end
11
+
12
+ def cd(dir)
13
+ Dir.chdir quote(dir)
14
+ puts "cd #{dir}"
15
+ end
16
+
17
+ def pwd
18
+ d = Dir.pwd
19
+ puts "pwd: #{d}"
20
+ d
21
+ end
22
+
23
+ def whenever(files)
24
+ if files.is_a?(String) or files.is_a?(Regexp)
25
+ files = [files]
26
+ end
27
+ Nite::Owl::NiteOwl.instance.whenever(files)
28
+ end
29
+
30
+ def action
31
+ Nite::Owl::NiteOwl.instance.current_action()
32
+ end
33
+
34
+ def delay(time)
35
+ action.delay(time)
36
+ end
37
+
38
+ def cancel
39
+ action.cancel
40
+ end
41
+
42
+ # Run command in shell and redirect it's output to stdout and stderr
43
+ def shell(command,options={:verbose => false,:silent => false,:stdin => nil})
44
+ stdout = ""
45
+ stderr = ""
46
+ verbose = options[:verbose]
47
+ silent = options[:silent]
48
+ stdin = options[:stdin]
49
+ if verbose
50
+ puts "Executing: #{command}"
51
+ end
52
+ Open3.popen3(command) do |i,o,e,t|
53
+ stdin_i = 0
54
+ stdin_open = stdin != nil
55
+ stdout_buffer = ""
56
+ stderr_buffer = ""
57
+ stdout_open = true
58
+ stderr_open = true
59
+ stdout_ch = nil
60
+ stderr_ch = nil
61
+ while stdout_open or stderr_open or stdin_open
62
+ if stdin_open
63
+ begin
64
+ p stdin
65
+ i.write(stdin)
66
+ i.close_write
67
+ stdin_open = false
68
+ #c = i.write_nonblock(stdin[stdin_i])
69
+ #if c > 0
70
+ # stdin_i += 1
71
+ # if stdin_i == stdin.size
72
+ # i.close_write
73
+ # stdin_open = false
74
+ # end
75
+ #end
76
+ rescue IO::WaitWritable
77
+ IO.select([i])
78
+ puts "retry writeable"
79
+ retry
80
+ rescue EOFError
81
+ stdin_open = false
82
+ end
83
+ end
84
+ if stdout_open
85
+ begin
86
+ stdout_ch = o.read_nonblock(1)
87
+ rescue IO::WaitReadable
88
+ IO.select([o])
89
+ retry
90
+ rescue EOFError
91
+ stdout_open = false
92
+ end
93
+ end
94
+ if stderr_open
95
+ begin
96
+ stderr_ch = e.read_nonblock(1)
97
+ rescue IO::WaitReadable
98
+ IO.select([e])
99
+ retry
100
+ rescue EOFError
101
+ stderr_open = false
102
+ end
103
+ end
104
+ if stdout_ch == "\n" then
105
+ stdout += stdout_buffer+"\n"
106
+ unless silent
107
+ puts stdout_buffer
108
+ end
109
+ stdout_buffer = ""
110
+ elsif stdout_ch != nil
111
+ stdout_buffer << stdout_ch
112
+ end
113
+ stdout_ch = nil
114
+ if stderr_ch == "\n" then
115
+ stderr += stderr_buffer+"\n"
116
+ unless silent
117
+ STDERR.puts stderr_buffer
118
+ end
119
+ stderr_buffer = ""
120
+ elsif stderr_ch != nil
121
+ stderr_buffer << stderr_ch
122
+ end
123
+ stderr_ch = nil
124
+ end
125
+ end
126
+ if stderr != ""
127
+ return stdout, stderr
128
+ else
129
+ return stdout
130
+ end
131
+ end
132
+
133
+ # get process pid(s)
134
+ def process(name,full=true)
135
+ if full
136
+ full = '-f '
137
+ else
138
+ full = ''
139
+ end
140
+ out,_ = Open3.capture2("/usr/bin/pgrep #{full}#{name}")
141
+ if out == ''
142
+ nil
143
+ else
144
+ pids = []
145
+ out.lines.each do |pid|
146
+ pids << pid.to_i
147
+ end
148
+ if pids.size == 1
149
+ pids[0]
150
+ else
151
+ pids
152
+ end
153
+ end
154
+ end
155
+
156
+ # kill process
157
+ def kill(pids,signal=15)
158
+ if pids.is_a?(Array)
159
+ pids.each do |pid|
160
+ Process.kill(signal,pid)
161
+ end
162
+ else
163
+ Process.kill(signal,pids)
164
+ end
165
+ end
166
+
167
+ module Nite
168
+ module Owl
169
+ require 'singleton'
170
+ require 'time'
171
+
172
+ class ::Fixnum
173
+ def milliseconds
174
+ self/1000.0
175
+ end
176
+ def seconds
177
+ to_f
178
+ end
179
+ def minutes
180
+ self*60.0
181
+ end
182
+ def hours
183
+ self*3600.0
184
+ end
185
+ end
186
+
187
+ # special exception thrown by cancel method
188
+ class Cancel < Exception
189
+ end
190
+
191
+ # special exception thrown by delay method
192
+ class Delay < Exception
193
+ attr_accessor :time
194
+ def initialize(time)
195
+ @time = time
196
+ end
197
+ end
198
+
199
+ $current_action = nil
200
+ $deferred_actions = {}
201
+
202
+ class Action
203
+ attr_accessor :parent
204
+ def initialize
205
+ @actions = []
206
+ @parent=nil
207
+ @delay=nil
208
+ end
209
+ def current_action
210
+ $current_action
211
+ end
212
+ def cancel
213
+ raise Cancel.new
214
+ end
215
+ def defer(name,flags)
216
+ unless $deferred_actions.has_key?(self)
217
+ $deferred_actions[self] = [name,flags]
218
+ end
219
+ end
220
+ def undefer
221
+ $deferred_actions.delete(self)
222
+ end
223
+ def self.call_all_deferred_actions
224
+ unless $deferred_actions.empty?
225
+ $deferred_actions.dup.each do |a,event|
226
+ a.call(event[0],event[1])
227
+ end
228
+ end
229
+ end
230
+ def root
231
+ r = self
232
+ while r.parent.parent
233
+ r = r.parent
234
+ end
235
+ r
236
+ end
237
+ def also
238
+ root
239
+ end
240
+ def add(a)
241
+ @actions << a
242
+ if a.is_a?(Action)
243
+ a.parent = self
244
+ end
245
+ a
246
+ end
247
+ def contains?(a)
248
+ @actions.find { |b| a == b or (b.is_a?(Action) and b.contains?(a)) }
249
+ end
250
+ def remove(a)
251
+ @actions.delete_if { |b| a == b }
252
+ @actions.each { |b| b.is_a?(Action) and b.remove(a) }
253
+ a
254
+ end
255
+ def run(&block)
256
+ add(block)
257
+ self
258
+ end
259
+ def call(name,flags)
260
+ $current_action = self
261
+ @actions.each do |n|
262
+ begin
263
+ n.call(name,flags)
264
+ rescue Cancel => c
265
+ undefer()
266
+ rescue Delay => d
267
+ handle_delay(d)
268
+ defer(name,flags)
269
+ rescue Exception => e
270
+ STDERR.puts e.message
271
+ STDERR.puts e.backtrace
272
+ end
273
+ end
274
+ end
275
+ def delay(time)
276
+ if @delay
277
+ if Time.now >= @delay
278
+ @delay = nil
279
+ else
280
+ raise Delay.new(0)
281
+ end
282
+ else
283
+ raise Delay.new(time)
284
+ end
285
+ end
286
+ def handle_delay(d)
287
+ unless @delay
288
+ @delay = Time.now + d.time
289
+ end
290
+ end
291
+ def only_once
292
+ run { root.parent.remove(self) }
293
+ end
294
+ def ignore(files)
295
+ add(NameIsNot.new(files))
296
+ end
297
+ def after(delay)
298
+ add(After.new(delay))
299
+ end
300
+ def created
301
+ add(HasFlags.new([:create]))
302
+ end
303
+ def modified
304
+ add(HasFlags.new([:modify]))
305
+ end
306
+ def deleted
307
+ add(HasFlags.new([:delete]))
308
+ end
309
+ def renamed
310
+ add(HasFlags.new([:rename]))
311
+ end
312
+ def changes
313
+ add(HasFlags.new([:create,:delete,:modify,:rename]))
314
+ end
315
+ def only_if(&block)
316
+ add(OnlyIf.new(block))
317
+ end
318
+ def if_not(&block)
319
+ add(IfNot.new(block))
320
+ end
321
+ end
322
+
323
+ class PredicateAction < Action
324
+ def initialize
325
+ super()
326
+ @time = nil
327
+ @expires = nil
328
+ end
329
+ def predicate?(name,flags)
330
+ true
331
+ end
332
+ def expired?
333
+ @expires and @time and (@time+@expires) >= Time.now.to_f
334
+ end
335
+ def expires(delay)
336
+ @expires = delay.to_f
337
+ self
338
+ end
339
+ def call(name,flags)
340
+ $current_action = self
341
+ begin
342
+ unless @time
343
+ @time = Time.now.to_f
344
+ end
345
+ if expired?
346
+ cancel
347
+ elsif predicate?(name,flags)
348
+ super(name,flags)
349
+ cancel
350
+ else
351
+ defer(name,flags)
352
+ end
353
+ rescue Cancel => c
354
+ undefer()
355
+ @time = nil
356
+ rescue Delay => d
357
+ handle_delay(d)
358
+ defer(name,flags)
359
+ rescue Exception => e
360
+ STDERR.puts e.message
361
+ STDERR.puts e.backtrace
362
+ end
363
+ end
364
+ end
365
+
366
+ class After < PredicateAction
367
+ def initialize(delay)
368
+ super()
369
+ @delay = delay.to_f
370
+ @time = nil
371
+ end
372
+ def predicate?(name,flags)
373
+ Time.now.to_f >= @time+@delay
374
+ end
375
+ end
376
+
377
+ class OnlyIf < PredicateAction
378
+ def initialize(block)
379
+ super()
380
+ @predicate = block
381
+ end
382
+ def predicate?(name,flags)
383
+ @predicate.call(name,flags)
384
+ end
385
+ end
386
+
387
+ class IfNot < PredicateAction
388
+ def initialize(block)
389
+ super()
390
+ @predicate = block
391
+ end
392
+ def predicate?(name,flags)
393
+ not @predicate.call(name,flags)
394
+ end
395
+ end
396
+
397
+ class HasFlags < Action
398
+ def initialize(flags)
399
+ super()
400
+ @flags = flags
401
+ end
402
+ def match?(flags)
403
+ @flags.find { |f| flags.include?(f) }
404
+ end
405
+ def call(name,flags)
406
+ match?(flags) && super(name,flags)
407
+ end
408
+ end
409
+
410
+ class FilesAction < Action
411
+ def initialize(files)
412
+ super()
413
+ @files = files
414
+ end
415
+ def match?(file)
416
+ @files.find do |pattern|
417
+ if pattern.is_a?(Regexp)
418
+ pattern.match(file) != nil
419
+ else
420
+ File.fnmatch?(pattern,file)
421
+ end
422
+ end
423
+ end
424
+ end
425
+
426
+ class NameIs < FilesAction
427
+ def call(name,flags)
428
+ match?(name) && super(name,flags)
429
+ end
430
+ end
431
+
432
+ class NameIsNot < FilesAction
433
+ def call(name,flags)
434
+ not match?(name) && super(name,flags)
435
+ end
436
+ end
437
+
438
+ class NiteOwl < Action
439
+ include Singleton
440
+
441
+ def initialize
442
+ super()
443
+ @workers_thread = nil
444
+ @queue = Queue.new
445
+ end
446
+
447
+ def watch(dir)
448
+ Dir.chdir dir
449
+ if File.file?("Niteowl") && File.readable?("Niteowl")
450
+ load "Niteowl"
451
+ else
452
+ puts "No Niteowl file found in: #{dir}"
453
+ end
454
+ if @actions.empty?
455
+ puts "No actions configured"
456
+ end
457
+ end
458
+
459
+ def whenever(files)
460
+ add(NameIs.new(files))
461
+ end
462
+
463
+ def start
464
+ @workers_thread = Thread.new {
465
+ begin
466
+ interval = 0.1
467
+ event_interval = 0.5
468
+ last_event_time = nil
469
+ next_time = Time.now.to_f+interval
470
+ events = {}
471
+ while true
472
+ until @queue.empty?
473
+ event = @queue.pop(true) rescue nil
474
+ if event
475
+ name = event[0]
476
+ flags = event[1]
477
+ if events[name]
478
+ new_flags = events[name] + flags
479
+ if new_flags == [:delete, :create, :modify]
480
+ new_flags = [:modify]
481
+ end
482
+ events[name] = new_flags
483
+ else
484
+ events[name] = flags
485
+ end
486
+ last_event_time = Time.now.to_f
487
+ end
488
+ end
489
+ if last_event_time && Time.now.to_f >= (last_event_time+event_interval)
490
+ events.each do |name,flags|
491
+ begin
492
+ Nite::Owl::NiteOwl.instance.call(name,flags.uniq)
493
+ rescue Exception => e
494
+ puts e.message
495
+ puts e.backtrace
496
+ end
497
+ end
498
+ events.clear
499
+ last_event_time = nil
500
+ end
501
+ Action.call_all_deferred_actions()
502
+ delay = next_time - Time.now.to_f
503
+ if delay > 0
504
+ sleep(delay)
505
+ end
506
+ next_time = Time.now.to_f+interval
507
+ end
508
+ rescue Exception => e
509
+ puts e.message
510
+ puts e.backtrace
511
+ end
512
+ }
513
+ # start platform specific notifier
514
+ pwd = Dir.pwd
515
+ if RUBY_PLATFORM =~ /linux/
516
+ require 'rb-inotify'
517
+ puts "Nite Owl watching: #{pwd}"
518
+ notifier = INotify::Notifier.new
519
+ notifier.watch(pwd, :recursive, :modify, :create, :delete, :move) do |event|
520
+ name = event.absolute_name.slice(pwd.size+1,event.absolute_name.size-pwd.size)
521
+ flags = event.flags do |f|
522
+ if f == :moved_to or f == :moved_from
523
+ :rename
524
+ else
525
+ f
526
+ end
527
+ end
528
+ @queue << [name,flags]
529
+ end
530
+ begin
531
+ notifier.run
532
+ rescue Interrupt => e
533
+ end
534
+ elsif RUBY_PLATFORM =~ /darwin/
535
+ require 'rb-fsevent'
536
+ puts "Nite Owl watching: #{pwd}"
537
+ fsevent = FSEvent.new
538
+ fsevent.watch pwd,{:file_events => true} do |paths, event_meta|
539
+ event_meta['events'].each do |event|
540
+ name = event['path']
541
+ name = name.slice(pwd.size+1,name.size-pwd.size)
542
+ flags = event['flags'].map do |f|
543
+ if f == 'ItemCreated'
544
+ :create
545
+ elsif f == 'ItemModified'
546
+ :modify
547
+ elsif f == 'ItemRemoved'
548
+ :delete
549
+ elsif f == 'ItemRenamed'
550
+ :rename
551
+ end
552
+ end.keep_if {|f| f}
553
+ @queue << [name,flags]
554
+ end
555
+ end
556
+ fsevent.run
557
+ else
558
+ puts "Platform unsupported"
559
+ exit(1)
560
+ end
561
+ end
562
+ end
563
+ end
564
+ end
@@ -0,0 +1,5 @@
1
+ module Nite
2
+ module Owl
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,29 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "nite/owl/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "nite-owl"
8
+ spec.version = Nite::Owl::VERSION
9
+ spec.authors = ["Dmitry Geurkov"]
10
+ spec.email = ["d.geurkov@gmail.com"]
11
+
12
+ spec.summary = %q{Linux/OSX File System Events Watcher.}
13
+ spec.description = %q{Linux/OSX File System Events Watcher.}
14
+ spec.homepage = "https://github.com/troydm/nite-owl"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_dependency "rb-fsevent", "~> 0.10", ">= 0.10.2"
25
+ spec.add_dependency "rb-inotify", "~> 0.9", ">= 0.9.10"
26
+ spec.add_development_dependency "bundler", "~> 1.16"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nite-owl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dmitry Geurkov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-09-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rb-fsevent
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.10'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.10.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.10'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.10.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: rb-inotify
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.9'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.9.10
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.9'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.9.10
53
+ - !ruby/object:Gem::Dependency
54
+ name: bundler
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.16'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.16'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rake
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '10.0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '10.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '3.0'
95
+ description: Linux/OSX File System Events Watcher.
96
+ email:
97
+ - d.geurkov@gmail.com
98
+ executables:
99
+ - nite-owl
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - ".gitignore"
104
+ - ".rspec"
105
+ - ".travis.yml"
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - Niteowl
109
+ - README.md
110
+ - Rakefile
111
+ - bin/console
112
+ - bin/setup
113
+ - exe/nite-owl
114
+ - lib/nite/owl.rb
115
+ - lib/nite/owl/niteowl.rb
116
+ - lib/nite/owl/version.rb
117
+ - nite-owl.gemspec
118
+ homepage: https://github.com/troydm/nite-owl
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.5.2.1
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Linux/OSX File System Events Watcher.
142
+ test_files: []