gazr 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6050b846af04b87fe491c3c00947a67de2a91dad
4
+ data.tar.gz: b004f3d6544d14d2b44b90961aa16c7434572380
5
+ SHA512:
6
+ metadata.gz: f685ba0475b63b4c1ce50f01630af484c6ead5eb8af130c1b5d5de9536b66eed9be3e4fcbf827373e31e677218296e8c888b49cd37d277102290aecd390e9e15
7
+ data.tar.gz: 73b06692d25b9d453a7b5e1f7141e8c9876f17f2006f5888debe372b7079cd09a63a9374c97a9a6c548cbf5c13e98bd90aa020deb8fffefe0863ab173af9cdcf
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gazr.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 James Akers
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
1
+ # Gazr
2
+
3
+ ## Summary
4
+ Gazr is a development tool that's purpose is to continue on where Martin Aumont's watchr left off at Ruby 1.9.2. It currently is only slightly modified to work with `>=` Ruby 1.9.3.
5
+
6
+ * For use with `<=` Ruby 1.9.2 just use [watchr][1]: `gem install watchr`
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'gazr'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install gazr
21
+
22
+ If you're on Linux/BSD and have the [rev][4] gem installed, Gazr will detect
23
+ it and use it automatically. This will make Gazr evented.
24
+
25
+ gem install rev
26
+
27
+ You can get the same evented behaviour on OS X by installing
28
+ [ruby-fsevent][10].
29
+
30
+ gem install ruby-fsevent
31
+
32
+ ## Usage
33
+
34
+ On the command line,
35
+
36
+ $ gazr path/to/script.file
37
+
38
+ will monitor files in the current directory tree, and react to events on those
39
+ files in accordance with the script.
40
+
41
+ ## Scripts
42
+
43
+ The script contains a set of simple rules that map observed files to an action.
44
+ Its DSL is a single method: `watch(pattern, &action)`
45
+
46
+ watch( 'a regexp pattern matching paths to observe' ) {|match_data_object| command_to_run }
47
+
48
+ So for example,
49
+
50
+ watch( 'test/test_.*\.rb' ) {|md| system("ruby #{md[0]}") }
51
+
52
+ will match any test file and run it whenever it is saved.
53
+
54
+ ## Contributing
55
+
56
+ 1. Fork it
57
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
58
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
59
+ 4. Push to the branch (`git push origin my-new-feature`)
60
+ 5. Create new Pull Request
61
+
62
+ [1]:https://github.com/mynyml/watchr
63
+ [4]: http://github.com/tarcieri/rev/
64
+ [10]: http://github.com/sandro/ruby-fsevent
65
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+ require 'optparse'
5
+ require 'tempfile'
6
+
7
+ require File.dirname(__FILE__) + '/../lib/gazr'
8
+
9
+ module Gazr
10
+ module Bin
11
+ extend self
12
+
13
+ DEFAULT_SCRIPT_PATH = Pathname.new('specs.gazr')
14
+
15
+ attr_accessor :path
16
+
17
+ def usage
18
+ "Usage: gazr [opts] path/to/script"
19
+ end
20
+
21
+ def version
22
+ "gazr version: %s" % Gazr::VERSION
23
+ end
24
+
25
+ # Absolute path to script file
26
+ #
27
+ # Unless set manually, the script's path is either first arg or
28
+ # `DEFAULT_SCRIPT_PATH`. If neither exists, the script immediatly aborts
29
+ # with an appropriate error message.
30
+ #
31
+ # @return [Pathname]
32
+ # absolute path to script
33
+ #
34
+ def path!
35
+ return @path unless @path.nil?
36
+ rel = relative_path or abort( usage )
37
+ find_in_load_path(rel) or abort("no script found: file #{rel.to_s.inspect} is not in path.")
38
+ end
39
+
40
+ # Find a partial path name in load path
41
+ #
42
+ # @param [Pathname] path
43
+ # partial pathname
44
+ #
45
+ # @return [Pathname]
46
+ # absolute path of first occurence of partial path in load path, or nil if not found
47
+ #
48
+ def find_in_load_path(path)
49
+ # Adds '.' for ruby1.9.2
50
+ dir = (['.'] + $LOAD_PATH).uniq.detect {|p| Pathname(p).join(path).exist? }
51
+ dir ? path.expand_path(dir) : nil
52
+ end
53
+
54
+ private
55
+
56
+ def relative_path
57
+ return Pathname.new(ARGV.first) if ARGV.first
58
+ return DEFAULT_SCRIPT_PATH if DEFAULT_SCRIPT_PATH.exist?
59
+ end
60
+ end
61
+ end
62
+
63
+ opts = OptionParser.new do |opts|
64
+ opts.banner = Gazr::Bin.usage
65
+
66
+ opts.on('-d', '--debug', "Print extra debug info while program runs") {
67
+ Gazr.options.debug = true
68
+ begin
69
+ require 'ruby-debug'
70
+ rescue LoadError, RuntimeError
71
+ end
72
+ }
73
+ opts.on('-l', '--list', "Display list of files monitored by script and exit") {
74
+ script = Gazr::Script.new(Gazr::Bin.path!)
75
+ controller = Gazr::Controller.new(script, Gazr.handler.new)
76
+ script.parse!
77
+ puts controller.monitored_paths
78
+ exit
79
+ }
80
+
81
+ def assert_syntax(code)
82
+ catch(:ok) { Object.new.instance_eval("BEGIN { throw :ok }; #{code}", %|-e "#{code}"|, 0) }
83
+ rescue SyntaxError => e
84
+ puts e.message.split("\n")[1]
85
+ exit
86
+ end
87
+
88
+ opts.on('-e', '--eval INLINE_SCRIPT', %|Evaluate script inline ($ gazr -e "watch('foo') { puts 'bar' }")|) {|code|
89
+ assert_syntax(code)
90
+
91
+ Tempfile.open('foo') {|f| f << code; @__path = f.path }
92
+ Gazr::Bin.path = Pathname(@__path)
93
+ }
94
+
95
+ opts.on_tail('-h', '--help', "Print inline help") { puts opts; exit }
96
+ opts.on_tail('-v', '--version', "Print version" ) { puts Gazr::Bin.version; exit }
97
+
98
+ opts.parse! ARGV
99
+ end
100
+
101
+ Gazr::Controller.new(Gazr::Script.new(Gazr::Bin.path!), Gazr.handler.new).run
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'gazr/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "gazr"
8
+ spec.version = Gazr::VERSION
9
+ spec.authors = ["James Akers"]
10
+ spec.email = ["j.f.akers@gmail.com"]
11
+ spec.description = %q{Flexible, Simple alternative to Guard. Watchr for Ruby 1.9.3 and beyond.}
12
+ spec.summary = %q{Flexible, Simple alternative to Guard. Watchr for Ruby 1.9.3 and beyond.}
13
+ spec.homepage = "http://github.com/jamesakers/gazr"
14
+ spec.license = "MIT"
15
+
16
+ spec.require_paths = ["lib"]
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/*}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "mocha"
23
+ spec.add_development_dependency "minitest"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,68 @@
1
+ require "gazr/version"
2
+
3
+ module Gazr
4
+
5
+ begin
6
+ require 'fsevent'
7
+ HAVE_FSE = true
8
+ rescue LoadError, RuntimeError
9
+ HAVE_FSE = false
10
+ end
11
+
12
+ begin
13
+ require 'rev'
14
+ HAVE_REV = true
15
+ rescue LoadError, RuntimeError
16
+ HAVE_REV = false
17
+ end
18
+
19
+ autoload :Script, 'gazr/script'
20
+ autoload :Controller, 'gazr/controller'
21
+
22
+ module EventHandler
23
+ autoload :Base, 'gazr/event_handlers/base'
24
+ autoload :Portable, 'gazr/event_handlers/portable'
25
+ autoload :Unix, 'gazr/event_handlers/unix' if ::Gazr::HAVE_REV
26
+ autoload :Darwin, 'gazr/event_handlers/darwin' if ::Gazr::HAVE_FSE
27
+ end
28
+
29
+ class << self
30
+ attr_accessor :options
31
+ attr_accessor :handler
32
+
33
+ def options
34
+ @options ||= Struct.new(:debug).new
35
+ @options.debug ||= false
36
+ @options
37
+ end
38
+
39
+ def debug(msg)
40
+ puts "[gazr debug] #{msg}" if options.debug
41
+ end
42
+
43
+ def handler
44
+ @handler ||=
45
+ case ENV['HANDLER'] || RbConfig::CONFIG['host_os']
46
+ when /darwin|mach|osx|fsevents?/i
47
+ if Gazr::HAVE_FSE
48
+ Gazr::EventHandler::Darwin
49
+ else
50
+ Gazr.debug "fsevent not found. `gem install ruby-fsevent` to get evented handler"
51
+ Gazr::EventHandler::Portable
52
+ end
53
+ when /sunos|solaris|bsd|linux|unix/i
54
+ if Gazr::HAVE_REV
55
+ Gazr::EventHandler::Unix
56
+ else
57
+ Gazr.debug "rev not found. `gem install rev` to get evented handler"
58
+ Gazr::EventHandler::Portable
59
+ end
60
+ when /mswin|windows|cygwin/i
61
+ Gazr::EventHandler::Portable
62
+ else
63
+ Gazr::EventHandler::Portable
64
+ end
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,37 @@
1
+ module Gazr
2
+ class Controller
3
+ def initialize(script, handler)
4
+ @script, @handler = script, handler
5
+ @handler.add_observer(self)
6
+ Gazr.debug "using %s handler" % handler.class.name
7
+ end
8
+
9
+ def run
10
+ @script.parse!
11
+ @handler.listen(monitored_paths)
12
+ rescue Interrupt
13
+ end
14
+
15
+ def update(path, event_type = nil)
16
+ path = Pathname(path).expand_path
17
+
18
+ Gazr.debug("received #{event_type.inspect} event for #{path.relative_path_from(Pathname(Dir.pwd))}")
19
+ if path == @script.path && event_type != :accessed
20
+ @script.parse!
21
+ @handler.refresh(monitored_paths)
22
+ else
23
+ @script.action_for(path, event_type).call
24
+ end
25
+ end
26
+
27
+ def monitored_paths
28
+ paths = Dir['**/*'].select do |path|
29
+ @script.patterns.any? {|p| path.match(p) }
30
+ end
31
+ paths.push(@script.path).compact!
32
+ paths.map {|path| Pathname(path).expand_path }
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,24 @@
1
+ require 'observer'
2
+
3
+ module Gazr
4
+ module EventHandler
5
+ class AbstractMethod < Exception; end
6
+ module Base
7
+ include Observable
8
+
9
+ def notify(path, event_type = nil)
10
+ changed(true)
11
+ notify_observers(path, event_type)
12
+ end
13
+
14
+ def listen(monitored_paths)
15
+ raise AbstractMethod
16
+ end
17
+
18
+ def refresh(monitored_paths)
19
+ raise AbstractMethod
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,85 @@
1
+ module Gazr
2
+ module EventHandler
3
+
4
+ class ::FSEvents
5
+ def self.debug(msg)
6
+ puts "[fsevents] #{msg}" if Watchr.options.debug
7
+ end
8
+ end
9
+
10
+ class Darwin < FSEvent
11
+ include Base
12
+
13
+ def initialize
14
+ super
15
+ self.latency = 0.2
16
+ end
17
+
18
+ def listen(monitored_paths)
19
+ register_paths(monitored_paths)
20
+ start
21
+ end
22
+
23
+ def refresh(monitored_paths)
24
+ register_paths(monitored_paths)
25
+ restart
26
+ end
27
+
28
+ private
29
+
30
+ def on_change(dirs)
31
+ dirs.each do |dir|
32
+ path, type = detect_change(dir)
33
+ notify(path, type) unless path.nil?
34
+ end
35
+ end
36
+
37
+ def detect_change(dir)
38
+ paths = monitored_paths_for(dir)
39
+ type = nil
40
+ path = paths.find {|path| type = event_type(path) }
41
+
42
+ FSEvents.debug("event detection error") if type.nil?
43
+
44
+ update_reference_times
45
+ [path, type]
46
+ end
47
+
48
+ def event_type(path)
49
+ return :deleted if !path.exist?
50
+ return :modified if path.mtime > @reference_times[path][:mtime]
51
+ return :accessed if path.atime > @reference_times[path][:atime]
52
+ return :changed if path.ctime > @reference_times[path][:ctime]
53
+ nil
54
+ end
55
+
56
+ def monitored_paths_for(dir)
57
+ dir = Pathname(dir).expand_path
58
+ @paths.select {|path| path.dirname.expand_path == dir }
59
+ end
60
+
61
+ def register_paths(paths)
62
+ @paths = paths
63
+ watch_directories(dirs_for(@paths))
64
+ update_reference_times
65
+ end
66
+
67
+ def dirs_for(paths)
68
+ paths.map {|path| path.dirname.to_s }.uniq
69
+ end
70
+
71
+ def update_reference_times
72
+ @reference_times = {}
73
+ now = Time.now
74
+ @paths.each do |path|
75
+ @reference_times[path] = {}
76
+ @reference_times[path][:atime] = now
77
+ @reference_times[path][:mtime] = now
78
+ @reference_times[path][:ctime] = now
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+
@@ -0,0 +1,45 @@
1
+ module Gazr
2
+ module EventHandler
3
+ class Portable
4
+ include Base
5
+
6
+ def initialize
7
+ @reference_mtime = @reference_atime = @reference_ctime = Time.now
8
+ end
9
+
10
+ def listen(monitored_paths)
11
+ @monitored_paths = monitored_paths
12
+ loop { trigger; sleep(1) }
13
+ end
14
+
15
+ def trigger
16
+ path, type = detect_event
17
+ notify(path, type) unless path.nil?
18
+ end
19
+
20
+ def refresh(monitored_paths)
21
+ @monitored_paths = monitored_paths
22
+ end
23
+
24
+ private
25
+
26
+ def detect_event # OPTIMIZE, REFACTOR
27
+ @monitored_paths.each do |path|
28
+ return [path, :deleted] unless path.exist?
29
+ end
30
+
31
+ mtime_path = @monitored_paths.max {|a,b| a.mtime <=> b.mtime }
32
+ atime_path = @monitored_paths.max {|a,b| a.atime <=> b.atime }
33
+ ctime_path = @monitored_paths.max {|a,b| a.ctime <=> b.ctime }
34
+
35
+ if mtime_path.mtime > @reference_mtime then @reference_mtime = mtime_path.mtime; [mtime_path, :modified]
36
+ elsif atime_path.atime > @reference_atime then @reference_atime = atime_path.atime; [atime_path, :accessed]
37
+ elsif ctime_path.ctime > @reference_ctime then @reference_ctime = ctime_path.ctime; [ctime_path, :changed ]
38
+ else; nil; end
39
+ rescue Errno::ENOENT
40
+ retry
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,125 @@
1
+ module Gazr
2
+ module EventHandler
3
+ class Unix
4
+ include Base
5
+
6
+ # Used by Rev. Wraps a monitored path, and `Rev::Loop` will call its
7
+ # callback on file events.
8
+ #
9
+ # @private
10
+ class SingleFileWatcher < Rev::StatWatcher
11
+ class << self
12
+ # Stores a reference back to handler so we can call its {Base#notify notify}
13
+ # method with file event info
14
+ #
15
+ # @return [EventHandler::Base]
16
+ #
17
+ attr_accessor :handler
18
+ end
19
+
20
+ # @param [String] path
21
+ # single file to monitor
22
+ #
23
+ def initialize(path)
24
+ super
25
+ update_reference_times
26
+ end
27
+
28
+ # File's path as a Pathname
29
+ #
30
+ # @return [Pathname]
31
+ #
32
+ def pathname
33
+ @pathname ||= Pathname(@path)
34
+ end
35
+
36
+ # Callback. Called on file change event. Delegates to
37
+ # {Controller#update}, passing in path and event type
38
+ #
39
+ # @return [undefined]
40
+ #
41
+ def on_change
42
+ self.class.handler.notify(path, type)
43
+ update_reference_times unless type == :deleted
44
+ end
45
+
46
+ private
47
+
48
+ # @todo improve ENOENT error handling
49
+ def update_reference_times
50
+ @reference_atime = pathname.atime
51
+ @reference_mtime = pathname.mtime
52
+ @reference_ctime = pathname.ctime
53
+ rescue Errno::ENOENT
54
+ retry
55
+ end
56
+
57
+ # Type of latest event.
58
+ #
59
+ # A single type is determined, even though more than one stat times may
60
+ # have changed on the file. The type is the first to match in the
61
+ # following hierarchy:
62
+ #
63
+ # :deleted, :modified (mtime), :accessed (atime), :changed (ctime)
64
+ #
65
+ # @return [Symbol] type
66
+ # latest event's type
67
+ #
68
+ def type
69
+ return :deleted if !pathname.exist?
70
+ return :modified if pathname.mtime > @reference_mtime
71
+ return :accessed if pathname.atime > @reference_atime
72
+ return :changed if pathname.ctime > @reference_ctime
73
+ end
74
+ end
75
+
76
+ def initialize
77
+ SingleFileWatcher.handler = self
78
+ @loop = Rev::Loop.default
79
+ end
80
+
81
+ # Enters listening loop. Will block control flow until application is
82
+ # explicitly stopped/killed.
83
+ #
84
+ # @return [undefined]
85
+ #
86
+ def listen(monitored_paths)
87
+ @monitored_paths = monitored_paths
88
+ attach
89
+ @loop.run
90
+ end
91
+
92
+ # Rebuilds file bindings. Will detach all current bindings, and reattach
93
+ # the `monitored_paths`
94
+ #
95
+ # @param [Array<Pathname>] monitored_paths
96
+ # list of paths the application is currently monitoring.
97
+ #
98
+ # @return [undefined]
99
+ #
100
+ def refresh(monitored_paths)
101
+ @monitored_paths = monitored_paths
102
+ detach
103
+ attach
104
+ end
105
+
106
+ private
107
+
108
+ # Binds all `monitored_paths` to the listening loop.
109
+ #
110
+ # @return [undefined]
111
+ #
112
+ def attach
113
+ @monitored_paths.each {|path| SingleFileWatcher.new(path.to_s).attach(@loop) }
114
+ end
115
+
116
+ # Unbinds all paths currently attached to listening loop.
117
+ #
118
+ # @return [undefined]
119
+ #
120
+ def detach
121
+ @loop.watchers.each {|watcher| watcher.detach }
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,94 @@
1
+ module Gazr
2
+ class Script
3
+
4
+ DEFAULT_EVENT_TYPE = :modified
5
+
6
+ attr_reader :ec
7
+ attr_reader :rules
8
+
9
+ Rule = Struct.new(:pattern, :event_type, :action)
10
+
11
+ class EvalContext
12
+
13
+ def initialize(script)
14
+ @__script = script
15
+ end
16
+
17
+ def default_action(&action)
18
+ @__script.default_action(&action)
19
+ end
20
+
21
+ def watch(*args, &block)
22
+ @__script.watch(*args, &block)
23
+ end
24
+
25
+ def reload
26
+ @__script.parse!
27
+ end
28
+ end
29
+
30
+
31
+ def initialize(path = nil)
32
+ @path = path
33
+ @rules = []
34
+ @default_action = Proc.new {}
35
+ @ec = EvalContext.new(self)
36
+ end
37
+
38
+ def watch(pattern, event_type = DEFAULT_EVENT_TYPE, &action)
39
+ @rules << Rule.new(pattern, event_type, action || @default_action)
40
+ @rules.last
41
+ end
42
+
43
+ def default_action(&action)
44
+ @default_action = action if action
45
+ @default_action
46
+ end
47
+
48
+ def reset
49
+ @rules = []
50
+ @default_action = Proc.new {}
51
+ end
52
+
53
+ def parse!
54
+ return unless @path
55
+ reset
56
+ @ec.instance_eval(@path.read, @path.to_s)
57
+ rescue Errno::ENOENT
58
+ sleep(0.5)
59
+ retry
60
+ ensure
61
+ Gazr.debug('loaded script file %s' % @path.to_s.inspect)
62
+ end
63
+
64
+ def action_for(path, event_type = DEFAULT_EVENT_TYPE)
65
+ path = rel_path(path).to_s
66
+ rule = rules_for(path).detect {|rule| rule.event_type.nil? || rule.event_type == event_type }
67
+ if rule
68
+ data = path.match(rule.pattern)
69
+ lambda { rule.action.call(data) }
70
+ else
71
+ lambda {}
72
+ end
73
+ end
74
+
75
+ def patterns
76
+ @rules.map {|r| r.pattern }
77
+ end
78
+
79
+ def path
80
+ @path && Pathname(@path.respond_to?(:to_path) ? @path.to_path : @path.to_s).expand_path
81
+ end
82
+
83
+ private
84
+
85
+ def rules_for(path)
86
+ @rules.reverse.select {|rule| path.match(rule.pattern) }
87
+ end
88
+
89
+ def rel_path(path)
90
+ Pathname(path).expand_path.relative_path_from(Pathname(Dir.pwd))
91
+ end
92
+ end
93
+ end
94
+
@@ -0,0 +1,3 @@
1
+ module Gazr
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gazr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Akers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-06-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mocha
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Flexible, Simple alternative to Guard. Watchr for Ruby 1.9.3 and beyond.
70
+ email:
71
+ - j.f.akers@gmail.com
72
+ executables:
73
+ - gazr
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/gazr
83
+ - gazr.gemspec
84
+ - lib/gazr.rb
85
+ - lib/gazr/controller.rb
86
+ - lib/gazr/event_handlers/base.rb
87
+ - lib/gazr/event_handlers/darwin.rb
88
+ - lib/gazr/event_handlers/portable.rb
89
+ - lib/gazr/event_handlers/unix.rb
90
+ - lib/gazr/script.rb
91
+ - lib/gazr/version.rb
92
+ homepage: http://github.com/jamesakers/gazr
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.0.3
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Flexible, Simple alternative to Guard. Watchr for Ruby 1.9.3 and beyond.
116
+ test_files: []