wake 0.1.0

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
data/LICENSE ADDED
@@ -0,0 +1,44 @@
1
+ Wake license:
2
+
3
+ Copyright (c) 2010 Steven Parkes
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.
23
+
24
+ Watch license:
25
+
26
+ Copyright © 2009 Martin Aumont (mynyml)
27
+
28
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
29
+ this software and associated documentation files (the "Software"), to deal in
30
+ the Software without restriction, including without limitation the rights to
31
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
32
+ of the Software, and to permit persons to whom the Software is furnished to do
33
+ so, subject to the following conditions:
34
+
35
+ The above copyright notice and this permission notice shall be included in all
36
+ copies or substantial portions of the Software.
37
+
38
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
44
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ .gitignore
2
+ History.txt
3
+ LICENSE
4
+ Manifest
5
+ README.rdoc
6
+ Rakefile
7
+ TODO.txt
8
+ bin/wake
9
+ docs.wk
10
+ gem.wk
11
+ lib/wake.rb
12
+ lib/wake/controller.rb
13
+ lib/wake/event_handlers/base.rb
14
+ lib/wake/event_handlers/portable.rb
15
+ lib/wake/event_handlers/unix.rb
16
+ lib/wake/event_handlers/rev.rb
17
+ lib/wake/event_handlers/em.rb
18
+ lib/wake/script.rb
19
+ manifest.wk
20
+ specs.wk
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_wake.rb
30
+ wake.gemspec
@@ -0,0 +1,105 @@
1
+ === Summary
2
+
3
+ The vision for wake is as a sort of rake/make like program, combined
4
+ with the real-time filesystem "watching" aspect of autotest/autospec/watchr.
5
+
6
+ Wake started out (and still is) mostly a fork of the watchr gem at
7
+ http://github.com/mynyml/watchr.
8
+
9
+ The are a number of differences now and they're expected to grow.
10
+
11
+ It's been ported to EventMachine for file-events and has some
12
+ extensions for how watches can be written.
13
+
14
+ To install, you can clone the repo (http://github.com/smparkes/wake)
15
+ or install the gem, <tt>wake</tt>. Note that for now, you'll need my
16
+ copy of EventMachine (http://github.com/smparkes/eventmachine or the
17
+ <tt>smparkes-eventmachine</tt> gem) for directory watches to work
18
+ well. (These changes are in the process of getting pulled upstream.)
19
+
20
+ == EventMachine
21
+
22
+ Not much to say. It supports EM as well as Rev, though the Rev stuff
23
+ will probably be dropped unles there's a compelling reason to keep
24
+ it. The default is still Rev. To use EventMachine, after installing
25
+ the EM gem, I just add
26
+
27
+ begin; require 'wake/event_handlers/em'; rescue LoadError; end
28
+
29
+ to my <tt>Wakefile</tt>. It'll use the first required backend, or
30
+ Rev if none are found (and Rev is installed). There may be better ways to
31
+ do this.
32
+
33
+ === Event processing extensions
34
+
35
+ I made several changes to the way events are created/processed, mostly
36
+ to make my <tt>Wakefile</tt> work:
37
+
38
+ #!/usr/bin/env wake
39
+
40
+ begin; require 'wake/event_handlers/em'; rescue LoadError; end
41
+
42
+ watch( %r(.*), :modified, lambda { |md| File.directory? md[0] } ) do |md|
43
+ raise Wake::Refresh
44
+ end
45
+
46
+ watch( %r((public/.*)\.haml$), [ :created, :modified ] ) do |md|
47
+ cmd = "rm -f #{md[1]}.html && haml -f html5 #{md[0]} #{md[1]}.html && chmod 444 #{md[1]}.html"
48
+ puts cmd
49
+ system cmd
50
+ if $?.signaled? && $?.termsig == 2
51
+ Process.kill 2, 0
52
+ end
53
+ end
54
+
55
+ watch( %r((spec/.*[Ss]pec)\.(html|js)$), [ :load, :created, :modified ] ) do |md|
56
+ cmd = "jazrb #{md[0]}"
57
+ puts cmd
58
+ system cmd
59
+ if $?.signaled? && $?.termsig == 2
60
+ Process.kill 2, 0
61
+ end
62
+ end
63
+
64
+ The purpose of the first watch is to cause wake to refresh when
65
+ directories change. This allows new files to be picked up. The watch
66
+ pattern matches all files in the current directory tree (though not
67
+ <tt>.</tt> itself; probably should), and watches for
68
+ <tt>:modified</tt> events. It adds an extra lambda that is processed
69
+ while looking at file paths: only directories will get watches put on
70
+ them. (Otherwise <tt>%r(.*)</tt> would put watches on every
71
+ file/directory in the tree, which seems kinda bad.)
72
+
73
+ The second watch looks for Haml files in my public directory and
74
+ automatically converts them to HTML. These are static files, not
75
+ served by an app server like Rails: even with static files, I hate
76
+ writing raw HTML. The extension here is so that instead of a single event
77
+ type, I can pass an array. In addition to the <tt>:modified</tt>,
78
+ event, this will get called when wake notes that a new file of this
79
+ type has appeared. (Note this works starting from wake's first pass;
80
+ files created while wake wasn't running don't count).
81
+
82
+ Then final watch looks for JavaScript and HTML spec files and runs
83
+ them under jazrb (see http://github.com/smparkes/jazrb if
84
+ interested). This case is similar to the previous but also adds the
85
+ <tt>:load</tt> event. This event gets fired the first time a file is
86
+ seen after wake starts. This allows wake to run all the specs when
87
+ first started, similar to what autotest does.
88
+
89
+ === Recent Changes
90
+
91
+ 1. POC for batch events that occur within a time window
92
+
93
+ 1. Pass event type to callbacks
94
+
95
+ 1. Has some POC dependency detection. Needs to be formalized into an API and have a better backend.
96
+
97
+ === Things to do
98
+
99
+ 1. Move directory watch into wake itself
100
+
101
+ 1. Handle user interrupt processing more systematically
102
+
103
+ 1. Don't swallow config file error messages, particularly on reload. Is this still happening?
104
+
105
+ 1. Integrate with rake/make.
@@ -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 = "Wake"
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,88 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ require 'pathname'
6
+ require 'optparse'
7
+
8
+ require 'wake'
9
+
10
+ module Wake
11
+ # Namespaced to avoid defining global methods
12
+ module Bin #:nodoc:
13
+ extend self
14
+
15
+ def usage
16
+ "Usage: wake [opts] [path/to/script]"
17
+ end
18
+
19
+ def version
20
+ "wake version: %s" % Wake::VERSION
21
+ end
22
+
23
+ # Find a partial path name in load path
24
+ #
25
+ # ===== Params
26
+ # path<Pathname>:: partial pathname
27
+ #
28
+ # ===== Returns
29
+ # <Pathname>::
30
+ # absolute path of first occurence of partial path in load path, or nil if not found
31
+ #
32
+ def find_in_load_path(path)
33
+ dir = potentially_with_gem( path.basename('.wk') ) do
34
+ $LOAD_PATH.detect {|p| Pathname(p).join(path).exist? }
35
+ end
36
+ dir ? path.expand_path(dir) : nil
37
+ end
38
+
39
+ private
40
+
41
+ # If the block returns nil, requires gem <tt>name</tt> and tries running the
42
+ # block again. If all fails, returns nil
43
+ #
44
+ # ===== Params
45
+ # name<Pathname,String>:: name of gem to require
46
+ #
47
+ # ===== Returns
48
+ # block's value or nil if gem <tt>name</tt> doesn't exist
49
+ #
50
+ def potentially_with_gem(name)
51
+ yield || (require(name) && yield)
52
+ rescue LoadError
53
+ nil
54
+ end
55
+ end
56
+ end
57
+
58
+ opts = OptionParser.new do |opts|
59
+ opts.banner = Wake::Bin.usage
60
+
61
+ opts.on('-d', '--debug', "Print extra debug info while program runs") {
62
+ Wake.options.debug = true
63
+ begin
64
+ require 'ruby-debug'
65
+ rescue LoadError, RuntimeError
66
+ end
67
+ }
68
+
69
+ opts.on('-1', '--once', "Run load patterns and then exit") {
70
+ Wake.options.once = true
71
+ }
72
+
73
+ opts.on('-f', '--wakefile FILE', "use wakefile FILE") { |file|
74
+ Wake.options.wakefile = file
75
+ }
76
+
77
+ opts.on_tail('-h', '--help', "Print inline help") { puts opts; exit }
78
+ opts.on_tail('-v', '--version', "Print version" ) { puts Wake::Bin.version; exit }
79
+
80
+ opts.parse! ARGV
81
+ end
82
+
83
+ path = Wake.options.wakefile || "Wakefile"
84
+ relative_path = Pathname( path ) rescue abort(Wake::Bin.usage)
85
+ absolute_path = Wake::Bin.find_in_load_path(relative_path) or abort("no script found; file #{relative_path.to_s.inspect} is not in path.")
86
+
87
+ Wake::Controller.new(Wake::Script.new(absolute_path)).run
88
+
data/docs.wk ADDED
@@ -0,0 +1,26 @@
1
+ # Run me with:
2
+ #
3
+ # $ wake -f docs.wk
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
data/gem.wk ADDED
@@ -0,0 +1,32 @@
1
+ # Run me with:
2
+ #
3
+ # $ wake gem.wk
4
+
5
+ # --------------------------------------------------
6
+ # Convenience Methods
7
+ # --------------------------------------------------
8
+ def build(gemspec)
9
+ system "gem build %s" % gemspec
10
+ FileUtils.mv Dir['wake-*.gem'], 'pkg/'
11
+ puts
12
+ end
13
+
14
+ # --------------------------------------------------
15
+ # Wake Rules
16
+ # --------------------------------------------------
17
+ watch( '^wake.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 'wake.gemspec'
26
+ end
27
+
28
+ # Ctrl-C
29
+ Signal.trap('INT') { abort("\n") }
30
+
31
+
32
+ # vim:ft=ruby
@@ -0,0 +1,109 @@
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
+ # $ wake path/to/script
12
+ # # default script if none is given is Wakefile.
13
+ #
14
+ # See README for more details
15
+ #
16
+ module Wake
17
+ VERSION = '0.1.0'
18
+
19
+ autoload :Script, 'wake/script'
20
+ autoload :Controller, 'wake/controller'
21
+
22
+ module EventHandler
23
+ autoload :Base, 'wake/event_handlers/base'
24
+ autoload :Unix, 'wake/event_handlers/unix'
25
+ autoload :Portable, 'wake/event_handlers/portable'
26
+ end
27
+
28
+ class << self
29
+ # backwards compatibility
30
+ def version #:nodoc:
31
+ Wake::VERSION
32
+ end
33
+
34
+ # Options proxy.
35
+ #
36
+ # Currently supported options:
37
+ # * debug<Boolean> Debugging state. More verbose.
38
+ #
39
+ # ===== Examples
40
+ #
41
+ # Wake.options.debug #=> false
42
+ # Wake.options.debug = true
43
+ #
44
+ # ===== Returns
45
+ # options<Struct>:: options proxy.
46
+ #
47
+ #--
48
+ # On first use, initialize the options struct and default option values.
49
+ def options
50
+ @options ||= Struct.new(:debug,:once, :wakefile).new
51
+ @options.debug ||= false
52
+ @options.once.nil? and @options.once = false
53
+ @options
54
+ end
55
+
56
+ def options= arg
57
+ @options = arg
58
+ end
59
+
60
+ # Outputs formatted debug statement to stdout, only if ::options.debug is true
61
+ #
62
+ # ===== Examples
63
+ #
64
+ # Wake.options.debug = true
65
+ # Wake.debug('im in ur codes, notifayinin u')
66
+ #
67
+ # outputs: "[wake debug] im in ur codes, notifayinin u"
68
+ #
69
+ def debug(str)
70
+ puts "[wake debug] #{str}" if options.debug
71
+ end
72
+
73
+ # Detect current OS and return appropriate handler.
74
+ #
75
+ # ===== Examples
76
+ #
77
+ # Config::CONFIG['host_os'] #=> 'linux-gnu'
78
+ # Wake.handler #=> Wake::EventHandler::Unix
79
+ #
80
+ # Config::CONFIG['host_os'] #=> 'cygwin'
81
+ # Wake.handler #=> Wake::EventHandler::Portable
82
+ #
83
+ # ENV['HANDLER'] #=> 'unix'
84
+ # Wake.handler #=> Wake::EventHandler::Unix
85
+ #
86
+ # ENV['HANDLER'] #=> 'portable'
87
+ # Wake.handler #=> Wake::EventHandler::Portable
88
+ #
89
+ # ===== Returns
90
+ # handler<Class>:: handler class for current architecture
91
+ #
92
+ def handler
93
+ @handler ||=
94
+ case ENV['HANDLER'] || Config::CONFIG['host_os']
95
+ when /mswin|windows|cygwin/i
96
+ Wake::EventHandler::Portable
97
+ when /sunos|solaris|darwin|mach|osx|bsd|linux/i, 'unix'
98
+ Wake::EventHandler::Unix.default
99
+ else
100
+ Wake::EventHandler::Portable
101
+ end
102
+ end
103
+
104
+ def handler= arg
105
+ @handler = arg
106
+ end
107
+
108
+ end
109
+ end