smparkes-watchr 0.5.7

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,6 @@
1
+ doc/
2
+ pkg/
3
+ bk/
4
+ .wiki
5
+ .yardoc
6
+ /*.gem
@@ -0,0 +1,32 @@
1
+
2
+ === v0.5.7
3
+
4
+ * Added manifest.watchr script
5
+ * Unix handler supports :deleted event type
6
+ * Unix handler supports :accessed (atime), :modified (mtime) and :changed
7
+ (ctime) event types (thanks gzuki[http://github.com/gzuki] for initial work)
8
+
9
+
10
+ === v0.5.6
11
+
12
+ * Rev gem optional in development (thanks TwP[http://github.com/TwP])
13
+ * Allow gems to bundle .watchr scripts (thanks foca[http://github.com/foca])
14
+
15
+ gemname/lib/gemname.watchr
16
+
17
+ is now automatically picked up with
18
+
19
+ $ watchr gemname.watchr
20
+
21
+ * Look for script in path
22
+ * debug msg when rev not found on *nix
23
+ * rake task for cross interpreter testing
24
+
25
+
26
+ === v0.5.5
27
+
28
+ * Rev gem is optional. Fixes issue #1
29
+ Install Rev to automatically get evented handler on *nix
30
+
31
+ gem install rev
32
+
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright © 2009 Martin Aumont (mynyml)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ 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 THE
19
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ .gitignore
2
+ History.txt
3
+ LICENSE
4
+ Manifest
5
+ README.rdoc
6
+ Rakefile
7
+ TODO.txt
8
+ bin/watchr
9
+ docs.watchr
10
+ gem.watchr
11
+ lib/watchr.rb
12
+ lib/watchr/controller.rb
13
+ lib/watchr/event_handlers/base.rb
14
+ lib/watchr/event_handlers/portable.rb
15
+ lib/watchr/event_handlers/unix.rb
16
+ lib/watchr/event_handlers/rev.rb
17
+ lib/watchr/event_handlers/em.rb
18
+ lib/watchr/script.rb
19
+ manifest.watchr
20
+ specs.watchr
21
+ test/README
22
+ test/event_handlers/test_base.rb
23
+ test/event_handlers/test_portable.rb
24
+ test/event_handlers/test_rev.rb
25
+ test/event_handlers/test_em.rb
26
+ test/test_controller.rb
27
+ test/test_helper.rb
28
+ test/test_script.rb
29
+ test/test_watchr.rb
30
+ watchr.gemspec
@@ -0,0 +1,82 @@
1
+ === Summary
2
+
3
+ This is a fork of the Watchr gem at git://github.com/mynyml/watchr.git.
4
+
5
+ The are a number of differences. It's been ported to EventMachine for
6
+ file-events and has some extensions for how watches can be written.
7
+
8
+ == EventMachine
9
+
10
+ Not much to say. It supports EM as well as Rev. The default is still
11
+ Rev. To use EventMachine, after installing the EM gem, I just add
12
+
13
+ begin; require 'watchr/event_handlers/em'; rescue LoadError; end
14
+
15
+ to my <tt>watchr.cnf</tt>. It'll use the first required backend, or
16
+ Rev if none are (and Rev is installed). There may be better ways to
17
+ do this.
18
+
19
+ === Event processing extensions
20
+
21
+ I made several changes to the way events are created/processed, mostly
22
+ to make my <tt>watchr.cnf</tt> work:
23
+
24
+ #!/usr/bin/env watchr
25
+
26
+ begin; require 'watchr/event_handlers/em'; rescue LoadError; end
27
+
28
+ watch( %r(.*), :modified, lambda { |md| File.directory? md[0] } ) do |md|
29
+ raise Watchr::Refresh
30
+ end
31
+
32
+ watch( %r((public/.*)\.haml$), [ :created, :modified ] ) do |md|
33
+ cmd = "rm -f #{md[1]}.html && haml -f html5 #{md[0]} #{md[1]}.html && chmod 444 #{md[1]}.html"
34
+ puts cmd
35
+ system cmd
36
+ if $?.signaled? && $?.termsig == 2
37
+ Process.kill 2, 0
38
+ end
39
+ end
40
+
41
+ watch( %r((spec/.*[Ss]pec)\.(html|js)$), [ :load, :created, :modified ] ) do |md|
42
+ cmd = "jazrb #{md[0]}"
43
+ puts cmd
44
+ system cmd
45
+ if $?.signaled? && $?.termsig == 2
46
+ Process.kill 2, 0
47
+ end
48
+ end
49
+
50
+ The purpose of the first watch is to cause watchr to refresh when
51
+ directories change. This allows new files to be picked up. The watch
52
+ pattern matches all files in the current directory tree (though not
53
+ <tt>.</tt> itself), and watches for <tt>:modified</tt> events. It adds
54
+ an extra lambda that is processed while looking at file paths: only
55
+ directories will get watches put on them. (Otherwise <tt>%r(.*)</tt> would put
56
+ watches on every file/directory in the tree, which seems kinda bad.
57
+
58
+ The second watch looks for HAML files in my public directory and
59
+ automatically converts them to HTML. These are static files, not
60
+ served by an app server like Rails, but even with static files, I hate
61
+ writing raw HTML. The extension here is that instead of a single event
62
+ type, I can pass an array. In addition to the <tt>:modified</tt>,
63
+ event, this will get called when watchr notes that a new file of this
64
+ type has appeared. (Note this works starting from watchr's first pass;
65
+ files created while watchr wasn't running don't count).
66
+
67
+ Then final watch looks for JavaScript and HTML spec files and runs
68
+ them under jazrb (see http://github.com/smparkes/jazrb if
69
+ interested). This case is similar to the previous but also adds the
70
+ <tt>:load</tt> event. This event gets fired the first time a file is
71
+ seen after watchr starts. This allows watchr to run all the specs when
72
+ first started, similar to what autotest does.
73
+
74
+ === Things to do
75
+
76
+ 1. Batch up specs instead of running them individually (not a big deal for jazrb and haml; a big detail for rspec)
77
+
78
+ 1. Integrate upstream (if the want it)
79
+
80
+ 1. Move directory watch into watchr itself
81
+
82
+ 1. Handle user interrupt processing more systematically
@@ -0,0 +1,51 @@
1
+ require 'rake/rdoctask'
2
+ begin
3
+ require 'yard'
4
+ rescue LoadError, RuntimeError
5
+ end
6
+
7
+ desc "Generate rdoc documentation."
8
+ Rake::RDocTask.new(:rdoc => 'rdoc', :clobber_rdoc => 'rdoc:clean', :rerdoc => 'rdoc:force') { |rdoc|
9
+ rdoc.rdoc_dir = 'doc/rdoc'
10
+ rdoc.title = "Watchr"
11
+ rdoc.options << '--line-numbers' << '--inline-source'
12
+ rdoc.options << '--charset' << 'utf-8'
13
+ rdoc.main = 'README.rdoc'
14
+ rdoc.rdoc_files.include('README.rdoc')
15
+ rdoc.rdoc_files.include('TODO.txt')
16
+ rdoc.rdoc_files.include('LICENSE')
17
+ rdoc.rdoc_files.include('lib/**/*.rb')
18
+ }
19
+
20
+ if defined? YARD
21
+ YARD::Rake::YardocTask.new do |t|
22
+ t.files = %w( lib/**/*.rb )
23
+ t.options = %w( -o doc/yard --readme README.rdoc --files LICENSE,TODO.txt )
24
+ end
25
+ end
26
+
27
+ namespace(:test) do
28
+
29
+ desc "Run all tests"
30
+ task(:all) do
31
+ tests = Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
32
+ cmd = "ruby -rubygems -Ilib -e'%w( #{tests.join(' ')} ).each {|file| require file }'"
33
+ puts cmd if ENV['VERBOSE']
34
+ system cmd
35
+ end
36
+
37
+ desc "Run all tests on multiple ruby versions (requires rvm with 1.8.6 and 1.8.7)"
38
+ task(:portability) do
39
+ versions = %w( 1.8.6 1.8.7 )
40
+ versions.each do |version|
41
+ system <<-BASH
42
+ bash -c 'source ~/.rvm/scripts/rvm;
43
+ rvm use #{version};
44
+ echo "--------- `ruby -v` ----------\n";
45
+ rake -s test:all'
46
+ BASH
47
+ end
48
+ end
49
+ end
50
+
51
+ task :default => "test:all"
@@ -0,0 +1,40 @@
1
+
2
+ * 1.9 compatibility
3
+
4
+ * sometimes an action is fired without a file being saved
5
+ * buffer flushing issue?
6
+ * libev issue?
7
+ * probably fixed with event type handling update, which ignores atime
8
+ updates by defaults
9
+
10
+ * when a file is saved twice quickly, subsequent events are ignored.
11
+ * seems like rev/libev drops the file watch
12
+
13
+ * test on other platforms
14
+ x mswin
15
+ x cygwin
16
+ * bsd
17
+ * osx
18
+ * solaris
19
+
20
+ * write a few prepackaged scripts
21
+ * post on gists
22
+ * post links on wiki
23
+ * post main links in readme
24
+
25
+ * eval script within own context?
26
+ * use case: using <tt>path</tt> within script accesses Script#path
27
+
28
+ * respond to different file events?
29
+ * modified
30
+ * created
31
+ * deleted
32
+ * etc.
33
+ * watch(pattern, EVENT, &action)
34
+ * use case: a script updates a manifest file when a file is deleted
35
+
36
+ * memory profiling / benchmarks
37
+
38
+ * version.watchr
39
+ * sync versions (gemspec & Watchr::VERSION)
40
+
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+ require 'optparse'
5
+
6
+ require 'watchr'
7
+
8
+ module Watchr
9
+ # Namespaced to avoid defining global methods
10
+ module Bin #:nodoc:
11
+ extend self
12
+
13
+ def usage
14
+ "Usage: watchr [opts] path/to/script"
15
+ end
16
+
17
+ def version
18
+ "watchr version: %s" % Watchr::VERSION
19
+ end
20
+
21
+ # Find a partial path name in load path
22
+ #
23
+ # ===== Params
24
+ # path<Pathname>:: partial pathname
25
+ #
26
+ # ===== Returns
27
+ # <Pathname>::
28
+ # absolute path of first occurence of partial path in load path, or nil if not found
29
+ #
30
+ def find_in_load_path(path)
31
+ dir = potentially_with_gem( path.basename('.watchr') ) do
32
+ $LOAD_PATH.detect {|p| Pathname(p).join(path).exist? }
33
+ end
34
+ dir ? path.expand_path(dir) : nil
35
+ end
36
+
37
+ private
38
+
39
+ # If the block returns nil, requires gem <tt>name</tt> and tries running the
40
+ # block again. If all fails, returns nil
41
+ #
42
+ # ===== Params
43
+ # name<Pathname,String>:: name of gem to require
44
+ #
45
+ # ===== Returns
46
+ # block's value or nil if gem <tt>name</tt> doesn't exist
47
+ #
48
+ def potentially_with_gem(name)
49
+ yield || (require(name) && yield)
50
+ rescue LoadError
51
+ nil
52
+ end
53
+ end
54
+ end
55
+
56
+ opts = OptionParser.new do |opts|
57
+ opts.banner = Watchr::Bin.usage
58
+
59
+ opts.on('-d', '--debug', "Print extra debug info while program runs") {
60
+ Watchr.options.debug = true
61
+ begin
62
+ require 'ruby-debug'
63
+ rescue LoadError, RuntimeError
64
+ end
65
+ }
66
+
67
+ opts.on_tail('-h', '--help', "Print inline help") { puts opts; exit }
68
+ opts.on_tail('-v', '--version', "Print version" ) { puts Watchr::Bin.version; exit }
69
+
70
+ opts.parse! ARGV
71
+ end
72
+
73
+ relative_path = Pathname( ARGV.first ) rescue abort(Watchr::Bin.usage)
74
+ absolute_path = Watchr::Bin.find_in_load_path(relative_path) or abort("no script found; file #{relative_path.to_s.inspect} is not in path.")
75
+
76
+ Watchr::Controller.new(Watchr::Script.new(absolute_path)).run
77
+
@@ -0,0 +1,26 @@
1
+ # Run me with:
2
+ #
3
+ # $ watchr docs.watchr
4
+
5
+ def run_rdoc
6
+ system('rake --silent rdoc')
7
+ end
8
+
9
+ def run_yard
10
+ print "\nUpdating yardocs... "
11
+ system('rake --silent yardoc')
12
+ print "done.\n"
13
+ end
14
+
15
+ def document
16
+ run_rdoc
17
+ run_yard
18
+ end
19
+
20
+ watch( 'lib/.*\.rb' ) { document }
21
+ watch( 'README.rdoc' ) { document }
22
+ watch( 'TODO.txt' ) { document }
23
+ watch( 'LICENSE' ) { document }
24
+
25
+
26
+ # vim:ft=ruby
@@ -0,0 +1,32 @@
1
+ # Run me with:
2
+ #
3
+ # $ watchr gem.watchr
4
+
5
+ # --------------------------------------------------
6
+ # Convenience Methods
7
+ # --------------------------------------------------
8
+ def build(gemspec)
9
+ system "gem build %s" % gemspec
10
+ FileUtils.mv Dir['watchr-*.gem'], 'pkg/'
11
+ puts
12
+ end
13
+
14
+ # --------------------------------------------------
15
+ # Watchr Rules
16
+ # --------------------------------------------------
17
+ watch( '^watchr.gemspec$' ) { |m| build m[0] }
18
+
19
+ # --------------------------------------------------
20
+ # Signal Handling
21
+ # --------------------------------------------------
22
+ # Ctrl-\
23
+ Signal.trap('QUIT') do
24
+ puts " --- Building Gem ---\n\n"
25
+ build 'watchr.gemspec'
26
+ end
27
+
28
+ # Ctrl-C
29
+ Signal.trap('INT') { abort("\n") }
30
+
31
+
32
+ # vim:ft=ruby
@@ -0,0 +1,101 @@
1
+ require 'pathname'
2
+ require 'rbconfig'
3
+
4
+ # Agile development tool that monitors a directory recursively, and triggers a
5
+ # user defined action whenever an observed file is modified. Its most typical
6
+ # use is continuous testing.
7
+ #
8
+ # Usage:
9
+ #
10
+ # # on command line, from project's root dir
11
+ # $ watchr path/to/script
12
+ #
13
+ # See README for more details
14
+ #
15
+ module Watchr
16
+ VERSION = '0.5.7'
17
+
18
+ autoload :Script, 'watchr/script'
19
+ autoload :Controller, 'watchr/controller'
20
+
21
+ module EventHandler
22
+ autoload :Base, 'watchr/event_handlers/base'
23
+ autoload :Unix, 'watchr/event_handlers/unix'
24
+ autoload :Portable, 'watchr/event_handlers/portable'
25
+ end
26
+
27
+ class << self
28
+ attr_accessor :options
29
+ attr_accessor :handler
30
+
31
+ # backwards compatibility
32
+ def version #:nodoc:
33
+ Watchr::VERSION
34
+ end
35
+
36
+ # Options proxy.
37
+ #
38
+ # Currently supported options:
39
+ # * debug<Boolean> Debugging state. More verbose.
40
+ #
41
+ # ===== Examples
42
+ #
43
+ # Watchr.options.debug #=> false
44
+ # Watchr.options.debug = true
45
+ #
46
+ # ===== Returns
47
+ # options<Struct>:: options proxy.
48
+ #
49
+ #--
50
+ # On first use, initialize the options struct and default option values.
51
+ def options
52
+ @options ||= Struct.new(:debug).new
53
+ @options.debug ||= false
54
+ @options
55
+ end
56
+
57
+ # Outputs formatted debug statement to stdout, only if ::options.debug is true
58
+ #
59
+ # ===== Examples
60
+ #
61
+ # Watchr.options.debug = true
62
+ # Watchr.debug('im in ur codes, notifayinin u')
63
+ #
64
+ # outputs: "[watchr debug] im in ur codes, notifayinin u"
65
+ #
66
+ def debug(str)
67
+ puts "[watchr debug] #{str}" if options.debug
68
+ end
69
+
70
+ # Detect current OS and return appropriate handler.
71
+ #
72
+ # ===== Examples
73
+ #
74
+ # Config::CONFIG['host_os'] #=> 'linux-gnu'
75
+ # Watchr.handler #=> Watchr::EventHandler::Unix
76
+ #
77
+ # Config::CONFIG['host_os'] #=> 'cygwin'
78
+ # Watchr.handler #=> Watchr::EventHandler::Portable
79
+ #
80
+ # ENV['HANDLER'] #=> 'unix'
81
+ # Watchr.handler #=> Watchr::EventHandler::Unix
82
+ #
83
+ # ENV['HANDLER'] #=> 'portable'
84
+ # Watchr.handler #=> Watchr::EventHandler::Portable
85
+ #
86
+ # ===== Returns
87
+ # handler<Class>:: handler class for current architecture
88
+ #
89
+ def handler
90
+ @handler ||=
91
+ case ENV['HANDLER'] || Config::CONFIG['host_os']
92
+ when /mswin|windows|cygwin/i
93
+ Watchr::EventHandler::Portable
94
+ when /sunos|solaris|darwin|mach|osx|bsd|linux/i, 'unix'
95
+ Watchr::EventHandler::Unix.default
96
+ else
97
+ Watchr::EventHandler::Portable
98
+ end
99
+ end
100
+ end
101
+ end