mynyml-watchr 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.
data/README.rdoc ADDED
@@ -0,0 +1,73 @@
1
+ ==== Summary
2
+
3
+ Agile development tool that monitors a directory recursively, and triggers a
4
+ user defined action whenever an observed file is modified. Its most typical use
5
+ is continious testing, and as such it is a more flexible alternative to
6
+ autotest.
7
+
8
+
9
+ ==== Features
10
+
11
+ * Ridiculously simple to use
12
+ * web framework agnostic <i>(rails, merb, sinatra, camping, invisible, ...)</i>
13
+ * test framework agnostic <i>(test/unit, minitest, rspec, test/spec, expectations, ...)</i>
14
+ * ruby interpreter agnostic <i>(ruby1.8, ruby1.9, MRI, JRuby, ...)</i>
15
+ * package framework agnostic <i>(rubygems, rip, ...)</i>
16
+ * Low level / highly flexible
17
+
18
+
19
+ ==== Usage
20
+
21
+ On the command line,
22
+
23
+ $ watchr path/to/script.file
24
+
25
+ will monitor all files from within the current directory and below it
26
+ recursively, and react to events on those files in accordance with the script.
27
+
28
+
29
+ ==== Scripts
30
+
31
+ The script contains a set of simple rules that map observed files to an action.
32
+ Its DSL is a single method: watch(pattern, &action)
33
+
34
+ watch( 'a regexp pattern matching paths to observe' ) {|match_data_object| command_to_run }
35
+
36
+ So for example,
37
+
38
+ watch( 'test/test_.*\.rb' ) {|md| system("ruby #{md[0]}") }
39
+
40
+ will match test files and run them whenever they are modified.
41
+
42
+ A continious testing script for a basic project could be
43
+
44
+ watch( 'test/test_.*\.rb' ) {|md| system("ruby #{md[0]}") }
45
+ watch( 'lib/(.*)\.rb' ) {|md| system("ruby test/test_#{md[1]}.rb") }
46
+
47
+ which, in addition to running any saved test file as above, will also run a
48
+ lib file's associated test. This mimics the equivalent autotest behaviour.
49
+
50
+ It's easy to see why watchr is so flexible, since the whole command is custom.
51
+ And remember the scripts are pure ruby, so feel free to add methods,
52
+ Signal#trap calls, etc.
53
+
54
+ The wiki[http://wiki.github.com/mynyml/watchr] has more details and examples.
55
+
56
+
57
+ ==== Install
58
+
59
+ gem install mynyml-watchr --source http://gems.github.com/
60
+
61
+
62
+ ==== See Also
63
+
64
+ redgreen[http://github.com/mynyml/redgreen]:: Standalone redgreen eye candy for test results, ala autotest.
65
+ phocus[http://github.com/mynyml/phocus]:: Run focused tests when running the whole file/suite is unnecessary.
66
+
67
+
68
+ ==== Links
69
+
70
+ source:: http://github.com/mynyml/watchr
71
+ rdocs:: http://docs.github.com/mynyml/watchr
72
+ wiki:: http://wiki.github.com/mynyml/watchr
73
+
data/Rakefile ADDED
@@ -0,0 +1,70 @@
1
+ # --------------------------------------------------
2
+ # based on thin's Rakefile (http://github.com/macournoyer/thin)
3
+ # --------------------------------------------------
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'pathname'
7
+ require 'yaml'
8
+ require 'lib/watchr/version'
9
+
10
+ RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
11
+ WIN = (RUBY_PLATFORM =~ /mswin|cygwin/)
12
+ SUDO = (WIN ? "" : "sudo")
13
+
14
+ def gem
15
+ RUBY_1_9 ? 'gem19' : 'gem'
16
+ end
17
+
18
+ def all_except(res)
19
+ Dir['**/*'].reject do |path|
20
+ Array(res).any? {|re| path.match(re) }
21
+ end
22
+ end
23
+
24
+ spec = Gem::Specification.new do |s|
25
+ s.name = 'watchr'
26
+ s.version = Watchr.version
27
+ s.summary = "Continious anything"
28
+ s.description = "Continious anything; project files observer/trigger."
29
+ s.author = "Martin Aumont"
30
+ s.email = 'mynyml@gmail.com'
31
+ s.homepage = ''
32
+ s.has_rdoc = true
33
+ s.require_path = "lib"
34
+ s.bindir = "bin"
35
+ s.executables = "watchr"
36
+ s.files = all_except %w( ^doc ^pkg ^test/fixtures )
37
+ end
38
+
39
+ desc "Generate rdoc documentation."
40
+ Rake::RDocTask.new(:rdoc => 'rdoc', :clobber_rdoc => 'rdoc:clean', :rerdoc => 'rdoc:force') { |rdoc|
41
+ rdoc.rdoc_dir = 'doc/rdoc'
42
+ rdoc.title = "Watchr"
43
+ rdoc.options << '--line-numbers' << '--inline-source'
44
+ rdoc.options << '--charset' << 'utf-8'
45
+ rdoc.main = 'README.rdoc'
46
+ rdoc.rdoc_files.include('README.rdoc')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ }
49
+
50
+ Rake::GemPackageTask.new(spec) do |p|
51
+ p.gem_spec = spec
52
+ end
53
+
54
+ desc "Remove package products"
55
+ task :clean => :clobber_package
56
+
57
+ desc "Update the gemspec for GitHub's gem server"
58
+ task :gemspec do
59
+ Pathname("#{spec.name}.gemspec").open('w') {|f| f << YAML.dump(spec) }
60
+ end
61
+
62
+ desc "Install gem"
63
+ task :install => [:clobber, :package] do
64
+ sh "#{SUDO} #{gem} install pkg/#{spec.full_name}.gem"
65
+ end
66
+
67
+ desc "Uninstall gem"
68
+ task :uninstall => :clean do
69
+ sh "#{SUDO} #{gem} uninstall -v #{spec.version} -x #{spec.name}"
70
+ end
data/TODO.txt ADDED
@@ -0,0 +1,27 @@
1
+
2
+ o write a few prepackaged scripts
3
+ o post on gists
4
+ o post links on wiki
5
+ o post main links in readme
6
+
7
+ o split watchr.rb classes into own files?
8
+ o run script within own context?
9
+
10
+ o use filesystem events for file monitoring (MA)
11
+ o linux: inotify
12
+ o osx: fsevent
13
+ o win: Directory Management? NTFS Change Journal? ReadDirectoryChangesW?
14
+ o *BSD: kqueue? pnotify?
15
+ o solaris: FEM?
16
+ o fallback to current method when no other method is available
17
+ o api will also need refactoring for clearer separation of functionality
18
+
19
+ o document source
20
+ o rdoc or yard?
21
+
22
+ o respond to different file events
23
+ o modified
24
+ o created
25
+ o deleted
26
+ o etc.
27
+ o watch(pattern, EVENT, &action)
data/bin/watchr ADDED
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+ require 'optparse'
5
+ root = Pathname(__FILE__).dirname.parent
6
+ require root.join('lib/watchr')
7
+ require root.join('lib/watchr/version')
8
+
9
+ def usage
10
+ "Usage: watchr [opts] path/to/script"
11
+ end
12
+
13
+ def version
14
+ "watchr version: %s" % Watchr.version
15
+ end
16
+
17
+ opts = OptionParser.new do |opts|
18
+ opts.banner = usage
19
+
20
+ opts.on('-d', '--debug', "Print extra debug info while program runs") {
21
+ Watchr.options.debug = true
22
+ }
23
+
24
+ opts.on_tail('-h', '--help', "Print inline help") { puts opts; exit }
25
+ opts.on_tail('-v', '--version', "Print version" ) { puts version; exit }
26
+
27
+ opts.parse! ARGV
28
+ end
29
+
30
+ abort(usage) unless ARGV.first
31
+
32
+ file = Pathname(ARGV.first)
33
+ abort(%|no script found; file "#{file.to_s}" doesn't exist.|) unless file.exist?
34
+
35
+ Watchr::Runner.new(file).run
36
+
@@ -0,0 +1,11 @@
1
+ module Watchr
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 3
5
+ TINY = 0
6
+ end
7
+
8
+ def self.version
9
+ [VERSION::MAJOR, VERSION::MINOR, VERSION::TINY].join('.')
10
+ end
11
+ end
data/lib/watchr.rb ADDED
@@ -0,0 +1,137 @@
1
+ module Watchr
2
+ class << self
3
+ attr_accessor :options
4
+
5
+ def options
6
+ @options ||= Struct.new(:debug).new
7
+ # set default options
8
+ @options.debug ||= false
9
+ @options
10
+ end
11
+ end
12
+
13
+ class Script
14
+ attr_accessor :map
15
+ attr_accessor :file
16
+ attr_accessor :reference_time
17
+
18
+ def initialize(file = nil)
19
+ self.map = []
20
+ self.file = file.is_a?(Pathname) ? file : Pathname.new(file) unless file.nil?
21
+ self.parse!
22
+ end
23
+
24
+ def watch(pattern, &action)
25
+ a = block_given? ? action : @default_action
26
+ self.map << [pattern, a]
27
+ end
28
+
29
+ def default_action(&action)
30
+ @default_action = action
31
+ end
32
+
33
+ def changed?
34
+ return false unless self.bound?
35
+ self.file.mtime > self.reference_time
36
+ end
37
+
38
+ def parse!
39
+ puts "[debug] loading script file #{self.file.to_s.inspect}" if Watchr.options.debug
40
+
41
+ return false unless self.bound?
42
+ self.map.clear
43
+ self.instance_eval(self.file.read)
44
+ self.reference_time = self.file.mtime
45
+ end
46
+
47
+ def bound?
48
+ self.file && self.file.respond_to?(:exist?) && self.file.exist?
49
+ end
50
+ end
51
+
52
+ class Runner
53
+ attr_accessor :script
54
+ attr_accessor :map
55
+ attr_accessor :init_time
56
+ attr_accessor :reference_file
57
+
58
+ # Caches reference_file.mtime to allow picking up an update to the
59
+ # reference file itself
60
+ attr_accessor :reference_time
61
+
62
+ def initialize(script)
63
+ self.init_time = Time.now.to_f
64
+ self.script = script.is_a?(Script) ? script : Script.new(script)
65
+ end
66
+
67
+ def paths
68
+ self.map.keys
69
+ end
70
+
71
+ def last_updated_file
72
+ path = self.paths.max {|a,b| File.mtime(a) <=> File.mtime(b) }
73
+ Pathname(path)
74
+ end
75
+
76
+ # TODO extract updating the reference out of this method
77
+ def changed?
78
+ return true if self.paths.empty?
79
+ return false if self.last_updated_file.mtime.to_f < self.init_time.to_f
80
+
81
+ if self.reference_file.nil? || (self.reference_time.to_f < self.last_updated_file.mtime.to_f)
82
+ self.reference_file = self.last_updated_file
83
+ self.reference_time = self.last_updated_file.mtime
84
+ true
85
+ else
86
+ false
87
+ end
88
+ end
89
+
90
+ def run
91
+ # enter monitoring state
92
+ loop do
93
+ self.trigger
94
+ Kernel.sleep(1)
95
+ end
96
+ end
97
+
98
+ def trigger
99
+ self.script.parse! && self.map! if self.script.changed?
100
+ self.call_action! if self.changed?
101
+ end
102
+
103
+ def map
104
+ @map || self.map!
105
+ end
106
+
107
+ protected
108
+
109
+ def call_action!
110
+ puts "[debug] monitoring paths: #{self.paths.inspect}" if Watchr.options.debug
111
+ raise "no reference file" if self.reference_file.nil?
112
+
113
+ ref = self.reference_file.to_s
114
+ pattern, action = self.map[ref]
115
+ md = ref.match(pattern)
116
+ action.call(md)
117
+ end
118
+
119
+ def map!
120
+ @map = {}
121
+ patterns = self.script.map.map {|mapping| mapping[0] }
122
+ patterns.each do |pattern|
123
+ local_files.each do |path|
124
+ if path.match(pattern)
125
+ action = self.script.map.assoc(pattern)[1]
126
+ @map[path] = [pattern, action]
127
+ end
128
+ end
129
+ end
130
+ @map
131
+ end
132
+
133
+ def local_files
134
+ Dir['**/*']
135
+ end
136
+ end
137
+ end
data/rdoc.watchr ADDED
@@ -0,0 +1,15 @@
1
+ # Run me with:
2
+ #
3
+ # $ watchr docs.watchr
4
+
5
+ run_rdoc = lambda { system('rake --silent rdoc') }
6
+
7
+ watch( '(lib|bin)/.*\.rb', &run_rdoc )
8
+ watch( 'README.rdoc', &run_rdoc )
9
+ watch( 'TODO.txt', &run_rdoc )
10
+ watch( 'LICENSE', &run_rdoc )
11
+
12
+
13
+
14
+
15
+ # vim:ft=ruby
data/specs.watchr ADDED
@@ -0,0 +1,35 @@
1
+ # Run me with:
2
+ #
3
+ # $ watchr specs.watchr
4
+
5
+ def all_test_files
6
+ Dir['test/**/test_*.rb'] - ['test/test_helper.rb']
7
+ end
8
+
9
+ def run(cmd)
10
+ puts(cmd)
11
+ system(cmd)
12
+ end
13
+
14
+ def run_all_tests
15
+ cmd = "ruby -rubygems -I.:lib:test -e'%w( #{all_test_files.join(' ')} ).each {|file| require file }'"
16
+ run(cmd)
17
+ end
18
+
19
+ watch( 'test/test_.*\.rb' ) {|md| run("ruby -rubygems #{md[0]}") }
20
+ watch( 'lib/(.*)\.rb' ) {|md| run("ruby -rubygems test/test_#{md[1]}.rb") }
21
+ watch( 'test/test_helper\.rb' ) { run_all_tests }
22
+
23
+ # Ctrl-C
24
+ Signal.trap('INT') do
25
+ puts " RERUNING ALL TESTS (Ctrl-\\ to quit)\n\n"
26
+ run_all_tests
27
+ end
28
+
29
+ # Ctrl-\
30
+ Signal.trap('QUIT') { abort("\n") }
31
+
32
+
33
+
34
+
35
+ # vim:ft=ruby
@@ -0,0 +1,67 @@
1
+ require 'pathname'
2
+ require 'test/unit'
3
+ require 'matchy'
4
+ require 'mocha'
5
+ require 'every'
6
+ require 'pending'
7
+ begin
8
+ require 'ruby-debug'
9
+ require 'phocus'
10
+ require 'redgreen'
11
+ rescue LoadError, RuntimeError
12
+ end
13
+
14
+ ROOT = Pathname(__FILE__).dirname.parent
15
+ $:.unshift(ROOT.join('lib'))
16
+
17
+ require 'watchr'
18
+
19
+ class Test::Unit::TestCase
20
+ class << self
21
+ def test(name, &block)
22
+ name = :"test_#{name.gsub(/\s/,'_')}"
23
+ define_method(name, &block)
24
+ end
25
+ alias :should :test
26
+ end
27
+ end
28
+
29
+ class Pathname
30
+ def rel
31
+ self.relative_path_from(ROOT).to_s
32
+ end
33
+ def pattern
34
+ Regexp.escape(self.rel)
35
+ end
36
+ def touch(time = Time.now)
37
+ `touch -mt #{time.strftime('%Y%m%d%H%M.%S')} #{self.expand_path.to_s}`
38
+ self
39
+ end
40
+ def mtime=(t)
41
+ self.touch(t).mtime
42
+ end
43
+ end
44
+
45
+ class Fixture
46
+ DIR = Pathname(__FILE__).dirname.join('fixtures')
47
+
48
+ class << self
49
+ attr_accessor :files
50
+
51
+ def create(name=nil, content=nil)
52
+ name ||= 'a.rb'
53
+ file = DIR.join(name)
54
+ self.files ||= []
55
+ self.files << file
56
+ file.open('w+') {|f| f << (content || "fixture\n") }
57
+ file
58
+ end
59
+
60
+ def delete_all
61
+ DIR.entries.each do |fixture|
62
+ next if %w( .. . ).include?(fixture.to_s)
63
+ DIR.join(fixture.to_s).expand_path.delete
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,182 @@
1
+ require 'test/test_helper'
2
+
3
+ class TestWatchr < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Watchr.options = nil
7
+ end
8
+
9
+ ## options
10
+
11
+ test "debug" do
12
+ Watchr.options.debug.should be(false)
13
+ Watchr.options.debug = true
14
+ Watchr.options.debug.should be(true)
15
+ end
16
+ end
17
+
18
+ class TestScript < Test::Unit::TestCase
19
+ include Watchr
20
+
21
+ ## api
22
+
23
+ test "watch" do
24
+ script = Script.new
25
+ script.watch('pattern') { nil }
26
+
27
+ script.map.first[0].should be('pattern')
28
+ script.map.first[1].call.should be(nil)
29
+ end
30
+
31
+ test "default action" do
32
+ script = Script.new
33
+ script.default_action { nil }
34
+ script.watch('pattern')
35
+
36
+ script.map.first[0].should be('pattern')
37
+ script.map.first[1].call.should be(nil)
38
+ end
39
+
40
+ test "automatically picks up changes to script file" do
41
+ file = Fixture.create('script.watchr', "watch('abc')")
42
+ script = Script.new(file)
43
+ script.changed?.should be(false)
44
+
45
+ script.stubs(:reference_time).returns(Time.now - 10) #mock sleep
46
+
47
+ Fixture.create('script.watchr', "watch('def')")
48
+ script.changed?.should be(true)
49
+ end
50
+
51
+ test "reparses script file" do
52
+ file = Fixture.create('script.watchr', "watch('abc')")
53
+ script = Script.new(file)
54
+ script.map.first.should include('abc')
55
+ script.map.first.should exclude('def')
56
+
57
+ script.stubs(:reference_time).returns(Time.now - 10) #mock sleep
58
+ Fixture.create('script.watchr', "watch('def')")
59
+ script.parse!
60
+ script.map.first.should include('def')
61
+ script.map.first.should exclude('abc')
62
+ end
63
+ end
64
+
65
+ class TestRunner < Test::Unit::TestCase
66
+ include Watchr
67
+
68
+ def teardown
69
+ Fixture.delete_all
70
+ Watchr.options = nil
71
+ end
72
+
73
+ test "maps observed files to their pattern and the actions they trigger" do
74
+ file_a = Fixture.create('a.rb')
75
+ file_b = Fixture.create('b.rb')
76
+ script = Script.new
77
+ script.watch(file_a.pattern) { 'ohaie' }
78
+ script.watch(file_b.pattern) { 'kthnx' }
79
+
80
+ runner = Runner.new(script)
81
+ runner.map[file_a.rel][0].should be(file_a.pattern)
82
+ runner.map[file_b.rel][0].should be(file_b.pattern)
83
+ runner.map[file_a.rel][1].call.should be('ohaie')
84
+ runner.map[file_b.rel][1].call.should be('kthnx')
85
+ end
86
+
87
+ test "latest mtime" do
88
+ file_a = Fixture.create('a.rb')
89
+ file_b = Fixture.create('b.rb')
90
+ script = Script.new
91
+ script.watch(file_a.pattern) { 'ohaie' }
92
+ script.watch(file_b.pattern) { 'kthnx' }
93
+
94
+ runner = Runner.new(script)
95
+ file_a.touch
96
+
97
+ runner.last_updated_file.rel.should be(file_a.rel)
98
+ end
99
+
100
+ test "monitors file changes" do
101
+ file_a = Fixture.create('a.rb')
102
+ script = Script.new
103
+ script.watch(file_a.pattern) { nil }
104
+
105
+ runner = Runner.new(script)
106
+ runner.changed?.should be(false)
107
+
108
+ # fake Kernel.sleep(2)
109
+ file_a.mtime = Time.now - 2
110
+ runner.init_time = Time.now - 2
111
+
112
+ file_a.touch
113
+ runner.changed?.should be(true)
114
+ end
115
+
116
+ test "calls action corresponding to file changed" do
117
+ script = Script.new
118
+ script.watch(Fixture.create.pattern) { throw(:ohaie) }
119
+
120
+ runner = Runner.new(script)
121
+ runner.init_time = Time.now - 2
122
+ runner.changed?
123
+ assert_throws(:ohaie) do
124
+ runner.instance_eval { call_action! }
125
+ end
126
+ end
127
+
128
+ test "passes match data to action" do
129
+ file_a = Fixture.create('a.rb')
130
+ script = Script.new
131
+ pattern = Fixture::DIR.join('(.*)\.(.*)$').rel
132
+ script.watch((pattern)) {|md| [md[1], md[2]].join('|') }
133
+
134
+ runner = Runner.new(script)
135
+ runner.init_time = Time.now - 2
136
+ file_a.touch
137
+ runner.changed?
138
+ runner.instance_eval { call_action! }.should be('a|rb')
139
+ end
140
+
141
+ test "doesn't run at startup" do
142
+ file = Fixture.create('a.rb')
143
+ script = Script.new
144
+ script.watch(file.pattern) { nil }
145
+
146
+ runner = Runner.new(script)
147
+ runner.changed?.should be(false)
148
+ end
149
+
150
+ test "a path only triggers its last matching pattern's action" do
151
+ file_a = Fixture.create('fix_a.rb')
152
+ file_b = Fixture.create('fix_b.rb')
153
+ script = Script.new
154
+ script.watch('fix_a\.rb') { throw(:ohaie) }
155
+ script.watch('fix_.*\.rb') { throw(:kkthx) }
156
+
157
+ runner = Runner.new(script)
158
+ runner.init_time = Time.now - 2
159
+ file_a.touch
160
+ runner.changed?
161
+ assert_throws(:kkthx) do
162
+ runner.instance_eval { call_action! }
163
+ end
164
+ end
165
+
166
+ test "updates map when script changes" do
167
+ file_a = Fixture.create('aaa')
168
+ file_b = Fixture.create('bbb')
169
+ script = Fixture.create('script.watchr', "watch('aaa')")
170
+
171
+ # fake Kernel.sleep(2)
172
+ script.mtime = Time.now - 2
173
+
174
+ runner = Runner.new(script)
175
+ assert runner.paths.first.match('aaa')
176
+
177
+ Fixture.create('script.watchr', "watch('bbb')")
178
+
179
+ runner.trigger
180
+ assert runner.paths.first.match('bbb')
181
+ end
182
+ end
data/watchr.gemspec ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: watchr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Aumont
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-26 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Continious anything; project files observer/trigger.
17
+ email: mynyml@gmail.com
18
+ executables:
19
+ - watchr
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Rakefile
26
+ - test
27
+ - test/test_watchr.rb
28
+ - test/test_helper.rb
29
+ - TODO.txt
30
+ - bin
31
+ - bin/watchr
32
+ - lib
33
+ - lib/watchr
34
+ - lib/watchr/version.rb
35
+ - lib/watchr.rb
36
+ - README.rdoc
37
+ - LICENSE
38
+ - yard.watchr
39
+ - rdoc.watchr
40
+ - specs.watchr
41
+ - watchr.gemspec
42
+ has_rdoc: true
43
+ homepage: ""
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Continious anything
70
+ test_files: []
71
+
data/yard.watchr ADDED
@@ -0,0 +1,18 @@
1
+ # Run me with:
2
+ #
3
+ # $ watchr docs-yard.watchr
4
+
5
+ def run_yard
6
+ print "Updating yardocs... "
7
+ system('yardoc -o doc/yard --readme README.rdoc --files LICENSE')
8
+ print "done.\n"
9
+ end
10
+
11
+ watch( '^(lib|bin)/.*\.rb' ) { run_yard }
12
+ watch( '^README.rdoc' ) { run_yard }
13
+ watch( '^LICENSE' ) { run_yard }
14
+
15
+
16
+
17
+
18
+ # vim:ft=ruby
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mynyml-watchr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Aumont
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-08-25 21:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Continious anything; project files observer/trigger.
17
+ email: mynyml@gmail.com
18
+ executables:
19
+ - watchr
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - Rakefile
26
+ - test
27
+ - test/test_watchr.rb
28
+ - test/test_helper.rb
29
+ - TODO.txt
30
+ - bin
31
+ - bin/watchr
32
+ - lib
33
+ - lib/watchr
34
+ - lib/watchr/version.rb
35
+ - lib/watchr.rb
36
+ - README.rdoc
37
+ - LICENSE
38
+ - yard.watchr
39
+ - rdoc.watchr
40
+ - specs.watchr
41
+ - watchr.gemspec
42
+ has_rdoc: true
43
+ homepage: ""
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Continious anything
70
+ test_files: []
71
+