smparkes-watchr 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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