Browse files

Port inline docs to yard

  • Loading branch information...
1 parent 7b55c3a commit 3b088e0ecef6b9269c25f1a700096c8cf4954b0a @mynyml mynyml committed Feb 9, 2010
View
2 docs.watchr
@@ -21,6 +21,6 @@ Signal.trap('INT' ) { abort("\n") } # Ctrl-C
# --------------------------------------------------
def yard
print "Updating yardocs... "; STDOUT.flush
- YARD::CLI::Yardoc.run *%w( -o doc/yard --readme README.md --markup rdoc - LICENSE TODO.txt )
+ YARD::CLI::Yardoc.run *%w( -o doc/yard --readme README.md --markup markdown - LICENSE TODO.txt )
print "done\n"
end
View
66 lib/watchr.rb
@@ -5,12 +5,12 @@
# user defined action whenever an observed file is modified. Its most typical
# use is continuous testing.
#
-# Usage:
+# See README for more details
#
-# # on command line, from project's root dir
-# $ watchr path/to/script
+# @example
#
-# See README for more details
+# # on command line, from project's root dir
+# $ watchr path/to/script
#
module Watchr
VERSION = '0.5.9'
@@ -35,63 +35,67 @@ class << self
attr_accessor :options
attr_accessor :handler
- # backwards compatibility
+ # @deprecated
def version #:nodoc:
Watchr::VERSION
end
# Options proxy.
#
# Currently supported options:
- # * debug<Boolean> Debugging state. More verbose.
#
- # ===== Examples
+ # * debug[Boolean] Debugging state. More verbose.
+ #
+ # @example
#
- # Watchr.options.debug #=> false
- # Watchr.options.debug = true
+ # Watchr.options.debug #=> false
+ # Watchr.options.debug = true
#
- # ===== Returns
- # options<Struct>:: options proxy.
+ # @return [Struct]
+ # options proxy.
#
- #--
- # On first use, initialize the options struct and default option values.
def options
@options ||= Struct.new(:debug).new
@options.debug ||= false
@options
end
- # Outputs formatted debug statement to stdout, only if ::options.debug is true
+ # Outputs formatted debug statement to stdout, only if `::options.debug` is true
+ #
+ # @example
+ #
+ # Watchr.options.debug = true
+ # Watchr.debug('im in ur codes, notifayinin u')
#
- # ===== Examples
+ # #outputs: "[watchr debug] im in ur codes, notifayinin u"
#
- # Watchr.options.debug = true
- # Watchr.debug('im in ur codes, notifayinin u')
+ # @param [String] message
+ # debug message to print
#
- # outputs: "[watchr debug] im in ur codes, notifayinin u"
+ # @return [nil]
#
- def debug(str)
- puts "[watchr debug] #{str}" if options.debug
+ def debug(msg)
+ puts "[watchr debug] #{msg}" if options.debug
end
# Detect current OS and return appropriate handler.
#
- # ===== Examples
+ # @example
#
- # Config::CONFIG['host_os'] #=> 'linux-gnu'
- # Watchr.handler #=> Watchr::EventHandler::Unix
+ # Config::CONFIG['host_os'] #=> 'linux-gnu'
+ # Watchr.handler #=> Watchr::EventHandler::Unix
#
- # Config::CONFIG['host_os'] #=> 'cygwin'
- # Watchr.handler #=> Watchr::EventHandler::Portable
+ # Config::CONFIG['host_os'] #=> 'cygwin'
+ # Watchr.handler #=> Watchr::EventHandler::Portable
#
- # ENV['HANDLER'] #=> 'unix'
- # Watchr.handler #=> Watchr::EventHandler::Unix
+ # ENV['HANDLER'] #=> 'unix'
+ # Watchr.handler #=> Watchr::EventHandler::Unix
#
- # ENV['HANDLER'] #=> 'portable'
- # Watchr.handler #=> Watchr::EventHandler::Portable
+ # ENV['HANDLER'] #=> 'portable'
+ # Watchr.handler #=> Watchr::EventHandler::Portable
#
- # ===== Returns
- # handler<Class>:: handler class for current architecture
+ # @return [Class]
+ # handler class for current architecture
#
def handler
@handler ||=
View
55 lib/watchr/controller.rb
@@ -2,55 +2,58 @@ module Watchr
# The controller contains the app's core logic.
#
- # ===== Examples
+ # @example
#
- # script = Watchr::Script.new(file)
- # contrl = Watchr::Controller.new(script)
- # contrl.run
+ # script = Watchr::Script.new(file)
+ # contrl = Watchr::Controller.new(script, Watchr.handler.new)
+ # contrl.run
#
- # Calling <tt>#run</tt> will enter the listening loop, and from then on every
- # file event will trigger its corresponding action defined in <tt>script</tt>
+ # # Calling `run` will enter the listening loop, and from then on every
+ # # file event will trigger its corresponding action defined in `script`
#
- # The controller also automatically adds the script's file itself to its list
- # of monitored files and will detect any changes to it, providing on the fly
- # updates of defined rules.
+ # # The controller also automatically adds the script's file to its list of
+ # # monitored files and will detect any changes to it, providing on the fly
+ # # updates of defined rules.
#
class Controller
- # Creates a controller object around given <tt>script</tt>
+ # Create a controller object around given `script`
#
- # ===== Parameters
- # script<Script>:: The script object
- # handler<EventHanlder::Base>:: The filesystem event handler
+ # @param [Script] script
+ # The script object
+ #
+ # @param [EventHandler::Base] handler
+ # The filesystem event handler
+ #
+ # @see Watchr::Script
+ # @see Watchr.handler
#
def initialize(script, handler)
- @script = script
- @handler = handler
-
+ @script, @handler = script, handler
@handler.add_observer(self)
Watchr.debug "using %s handler" % handler.class.name
end
- # Enters listening loop.
- #
- # Will block control flow until application is explicitly stopped/killed.
- #
+ # Enter listening loop. Will block control flow until application is
+ # explicitly stopped/killed.
def run
@script.parse!
@handler.listen(monitored_paths)
rescue Interrupt
end
- # Callback for file events.
+ # Callback for file events
#
# Called while control flow is in listening loop. It will execute the
# file's corresponding action as defined in the script. If the file is the
# script itself, it will refresh its state to account for potential changes.
#
- # ===== Parameters
- # path<Pathname, String>:: path that triggered event
- # event_type<Symbol>:: event type
+ # @param [Pathname, String] path
+ # path that triggered the event
+ #
+ # @param [Symbol] event
+ # event type
#
def update(path, event_type = nil)
path = Pathname(path).expand_path
@@ -68,8 +71,8 @@ def update(path, event_type = nil)
# Basically this means all paths below current directoly recursivelly that
# match any of the rules' patterns, plus the script file.
#
- # ===== Returns
- # paths<Array[Pathname]>:: List of monitored paths
+ # @return [Array<Pathname>]
+ # list of all monitored paths
#
def monitored_paths
paths = Dir['**/*'].select do |path|
View
39 lib/watchr/event_handlers/base.rb
@@ -2,44 +2,53 @@
module Watchr
module EventHandler
- class AbstractMethod < Exception #:nodoc:
- end
- # Base functionality mixin meant to be included in specific event handlers.
+ # @private
+ class AbstractMethod < Exception; end
+
+ # Base functionality mixin, meant to be included in specific event handlers.
+ #
+ # @abstract
module Base
include Observable
# Notify that a file was modified.
#
- # ===== Parameters
- # path<Pathname, String>:: full path or path relative to current working directory
- # event_type<Symbol>:: event type.
- #--
- # #changed and #notify_observers are Observable methods
+ # @param [Pathname, String] path
+ # full path or path relative to current working directory
+ #
+ # @param [Symbol] event
+ # event type.
+ #
+ # @return [undefined]
+ #
def notify(path, event_type = nil)
changed(true)
notify_observers(path, event_type)
end
- # Begin watching given paths and enter listening loop. Called by the controller.
+ # Begin watching given paths and enter listening loop. Called by the
+ # controller.
#
- # Abstract method
+ # @param [Array<Pathname>] monitored_paths
+ # list of paths the application is currently monitoring.
#
- # ===== Parameters
- # monitored_paths<Array(Pathname)>:: list of paths the application is currently monitoring.
+ # @return [undefined]
#
+ # @abstract
def listen(monitored_paths)
raise AbstractMethod
end
# Called by the controller when the list of paths monitored by wantchr
# has changed. It should refresh the list of paths being watched.
#
- # Abstract method
+ # @param [Array<Pathname>] monitored_paths
+ # list of paths the application is currently monitoring.
#
- # ===== Parameters
- # monitored_paths<Array(Pathname)>:: list of paths the application is currently monitoring.
+ # @return [undefined]
#
+ # @abstract
def refresh(monitored_paths)
raise AbstractMethod
end
View
28 lib/watchr/event_handlers/portable.rb
@@ -11,18 +11,33 @@ def initialize
#
# Will block control flow until application is explicitly stopped/killed.
#
+ # @param [Array<Pathname>] monitored_paths
+ # list of paths the application is currently monitoring.
+ #
+ # @return [undefined]
+ #
def listen(monitored_paths)
@monitored_paths = monitored_paths
loop { trigger; sleep(1) }
end
# See if an event occured, and if so notify observers.
- def trigger #:nodoc:
+ #
+ # @return [undefined]
+ #
+ # @private
+ def trigger
path, type = detect_event
notify(path, type) unless path.nil?
end
# Update list of monitored paths.
+ #
+ # @param [Array<Pathname>] monitored_paths
+ # list of paths the application is currently monitoring.
+ #
+ # @return [undefined]
+ #
def refresh(monitored_paths)
@monitored_paths = monitored_paths
end
@@ -34,13 +49,12 @@ def refresh(monitored_paths)
# If the latest mtime is more recent than the reference mtime, return
# that file's path.
#
- # ===== Returns
- # path and type of event if event occured, nil otherwise
+ # @return [[Pathname, Symbol]]
+ # path and type of event if event occured, nil otherwise
+ #
+ # @todo improve ENOENT error handling
#
- #--
- # OPTIMIZE, REFACTOR
- # TODO fix/figure out ENOENT error
- def detect_event
+ def detect_event # OPTIMIZE, REFACTOR
@monitored_paths.each do |path|
return [path, :deleted] unless path.exist?
end
View
54 lib/watchr/event_handlers/unix.rb
@@ -3,36 +3,49 @@ module EventHandler
class Unix
include Base
- # Used by Rev. Wraps a monitored path, and Rev::Loop will call its
+ # Used by Rev. Wraps a monitored path, and `Rev::Loop` will call its
# callback on file events.
- class SingleFileWatcher < Rev::StatWatcher #:nodoc:
+ #
+ # @private
+ class SingleFileWatcher < Rev::StatWatcher
class << self
- # Stores a reference back to handler so we can call its #nofity
+ # Stores a reference back to handler so we can call its {Base#notify notify}
# method with file event info
+ #
+ # @return [EventHandler::Base]
+ #
attr_accessor :handler
end
+ # @param [String] path
+ # single file to monitor
+ #
def initialize(path)
super
update_reference_times
end
# File's path as a Pathname
+ #
+ # @return [Pathname]
+ #
def pathname
@pathname ||= Pathname(@path)
end
- # Callback. Called on file change event
- # Delegates to Controller#update, passing in path and event type
+ # Callback. Called on file change event. Delegates to
+ # {Controller#update}, passing in path and event type
+ #
+ # @return [undefined]
+ #
def on_change
self.class.handler.notify(path, type)
update_reference_times unless type == :deleted
end
private
- #--
- # TODO fix/figure out ENOENT error
+ # @todo improve ENOENT error handling
def update_reference_times
@reference_atime = pathname.atime
@reference_mtime = pathname.mtime
@@ -47,10 +60,10 @@ def update_reference_times
# have changed on the file. The type is the first to match in the
# following hierarchy:
#
- # :deleted, :modified (mtime), :accessed (atime), :changed (ctime)
+ # :deleted, :modified (mtime), :accessed (atime), :changed (ctime)
#
- # ===== Returns
- # type<Symbol>:: latest event's type
+ # @return [Symbol] type
+ # latest event's type
#
def type
return :deleted if !pathname.exist?
@@ -65,19 +78,24 @@ def initialize
@loop = Rev::Loop.default
end
- # Enters listening loop.
+ # Enters listening loop. Will block control flow until application is
+ # explicitly stopped/killed.
#
- # Will block control flow until application is explicitly stopped/killed.
+ # @return [undefined]
#
def listen(monitored_paths)
@monitored_paths = monitored_paths
attach
@loop.run
end
- # Rebuilds file bindings.
+ # Rebuilds file bindings. Will detach all current bindings, and reattach
+ # the `monitored_paths`
#
- # will detach all current bindings, and reattach the <tt>monitored_paths</tt>
+ # @param [Array<Pathname>] monitored_paths
+ # list of paths the application is currently monitoring.
+ #
+ # @return [undefined]
#
def refresh(monitored_paths)
@monitored_paths = monitored_paths
@@ -87,12 +105,18 @@ def refresh(monitored_paths)
private
- # Binds all <tt>monitored_paths</tt> to the listening loop.
+ # Binds all `monitored_paths` to the listening loop.
+ #
+ # @return [undefined]
+ #
def attach
@monitored_paths.each {|path| SingleFileWatcher.new(path.to_s).attach(@loop) }
end
# Unbinds all paths currently attached to listening loop.
+ #
+ # @return [undefined]
+ #
def detach
@loop.watchers.each {|watcher| watcher.detach }
end
View
164 lib/watchr/script.rb
@@ -2,21 +2,23 @@ module Watchr
# A script object wraps a script file, and is used by a controller.
#
- # ===== Examples
+ # @example
#
- # path = Pathname.new('specs.watchr')
- # script = Watchr::Script.new(path)
+ # path = Pathname.new('specs.watchr')
+ # script = Watchr::Script.new(path)
#
class Script
+
+ # @private
DEFAULT_EVENT_TYPE = :modified
# Convenience type. Provides clearer and simpler access to rule properties.
#
- # ===== Examples
+ # @example
#
- # rule = script.watch('lib/.*\.rb') { 'ohaie' }
- # rule.pattern #=> 'lib/.*\.rb'
- # rule.action.call #=> 'ohaie'
+ # rule = script.watch('lib/.*\.rb') { 'ohaie' }
+ # rule.pattern #=> 'lib/.*\.rb'
+ # rule.action.call #=> 'ohaie'
#
Rule = Struct.new(:pattern, :event_type, :action)
@@ -26,53 +28,58 @@ class Script
# that they get a clearly defined set of methods to work with. In other
# words, it is the user script's API.
#
+ # @private
class EvalContext #:nodoc:
def initialize(script)
@__script = script
end
- # Delegated to Script
+ # Delegated to script
def default_action(&action)
@__script.default_action(&action)
end
- # Delegated to Script
+ # Delegated to script
def watch(*args, &block)
@__script.watch(*args, &block)
end
+ # Reload script
def reload
@__script.parse!
end
end
# EvalContext instance
#
- # ===== Examples
- # script.ec.watch('pattern') { }
- # script.ec.reload
+ # @example
+ #
+ # script.ec.watch('pattern') { }
+ # script.ec.reload
+ #
+ # @return [EvalContext]
#
attr_reader :ec
# Defined rules
#
- # ===== Returns
- # Array[Rule]:: rules defined with #watch calls
+ # @return [Rule]
+ # all rules defined with `#watch` calls
#
attr_reader :rules
# Default action
#
- # ===== Returns
- # Proc:: action defined with #default_action call
+ # @return [Proc]
+ # action defined with `#default_action` call
#
attr_reader :default_action
- # Create a script object for <tt>path</tt>.
+ # Create a Script object for script at `path`
#
- # ===== Parameters
- # path<Pathname>:: the path to the script
+ # @param [Pathname] path
+ # the path to the script
#
def initialize(path = nil)
@path = path
@@ -83,44 +90,46 @@ def initialize(path = nil)
# Main script API method. Builds a new rule, binding a pattern to an action.
#
- # Whenever a file is saved that matches a rule's <tt>pattern</tt>, its
- # corresponding <tt>action</tt> is triggered.
+ # Whenever a file is saved that matches a rule's `pattern`, its
+ # corresponding `action` is triggered.
#
# Patterns can be either a Regexp or a string. Because they always
# represent paths however, it's simpler to use strings. But remember to use
# single quotes (not double quotes), otherwise escape sequences will be
- # parsed (for example "foo/bar\.rb" #=> "foo/bar.rb", notice "\." becomes
+ # parsed (for example `"foo/bar\.rb" #=> "foo/bar.rb"`, notice "\." becomes
# "."), and won't be interpreted as the regexp you expect.
#
# Also note that patterns will be matched against relative paths (relative
- # from current working directory).
+ # to current working directory).
#
- # Actions, the blocks passed to <tt>watch</tt>, receive a MatchData object
- # as argument. It will be populated with the whole matched string (md[0])
- # as well as individual backreferences (md[1..n]). See MatchData#[]
+ # Actions, the blocks passed to `watch`, receive a `MatchData` object as
+ # argument. It will be populated with the whole matched string ( `md[0]` )
+ # as well as individual backreferences ( `md[1..n]` ). See `MatchData#[]`
# documentation for more details.
#
- # ===== Examples
+ # @example
#
- # # in script file
- # watch( 'test/test_.*\.rb' ) {|md| system("ruby #{md[0]}") }
- # watch( 'lib/(.*)\.rb' ) {|md| system("ruby test/test_#{md[1]}.rb") }
+ # # in script file
+ # watch( 'test/test_.*\.rb' ) {|md| system("ruby #{md[0]}") }
+ # watch( 'lib/(.*)\.rb' ) {|md| system("ruby test/test_#{md[1]}.rb") }
#
# With these two rules, watchr will run any test file whenever it is itself
# changed (first rule), and will also run a corresponding test file
# whenever a lib file is changed (second rule).
#
- # ===== Parameters
- # pattern<~#match>:: pattern to match targetted paths
- # event_type<Symbol>::
- # Rule will only match events of this type. Accepted types are :accessed,
- # :modified, :changed, :delete and nil (any), where the first three
- # correspond to atime, mtime and ctime respectively. Defaults to
- # :modified.
- # action<Block>:: action to trigger
+ # @param [#match] pattern
+ # pattern to match targetted paths
+ #
+ # @param [Symbol] event_type
+ # rule will only match events of this type. Accepted types are
+ # `:accessed`, `:modified`, `:changed`, `:delete` and `nil` (any), where
+ # the first three correspond to atime, mtime and ctime respectively.
+ # Defaults to `:modified`.
#
- # ===== Returns
- # rule<Rule>:: rule created by the method
+ # @yield
+ # action to trigger
+ #
+ # @return [Rule]
#
def watch(pattern, event_type = DEFAULT_EVENT_TYPE, &action)
@rules << Rule.new(pattern, event_type, action || @default_action)
@@ -130,26 +139,26 @@ def watch(pattern, event_type = DEFAULT_EVENT_TYPE, &action)
# Convenience method. Define a default action to be triggered when a rule
# has none specified.
#
- # ===== Examples
+ # @example
#
- # # in script file
+ # # in script file
#
- # default_action { system('rake --silent rdoc') }
+ # default_action { system('rake --silent yard') }
#
- # watch( 'lib/.*\.rb' )
- # watch( 'README.rdoc' )
- # watch( 'TODO.txt' )
- # watch( 'LICENSE' )
+ # watch( 'lib/.*\.rb' )
+ # watch( 'README.md' )
+ # watch( 'TODO.txt' )
+ # watch( 'LICENSE' )
#
- # # equivalent to:
+ # # is equivalent to:
#
- # watch( 'lib/.*\.rb' ) { system('rake --silent rdoc') }
- # watch( 'README.rdoc' ) { system('rake --silent rdoc') }
- # watch( 'TODO.txt' ) { system('rake --silent rdoc') }
- # watch( 'LICENSE' ) { system('rake --silent rdoc') }
+ # watch( 'lib/.*\.rb' ) { system('rake --silent yard') }
+ # watch( 'README.md' ) { system('rake --silent yard') }
+ # watch( 'TODO.txt' ) { system('rake --silent yard') }
+ # watch( 'LICENSE' ) { system('rake --silent yard') }
#
- # ===== Returns
- # Proc:: default action
+ # @return [Proc]
+ # default action
#
def default_action(&action)
@default_action = action if action
@@ -163,8 +172,8 @@ def reset
end
# Eval content of script file.
- #--
- # TODO fix/figure out ENOENT error
+ #
+ # @todo improve ENOENT error handling
def parse!
return unless @path
reset
@@ -180,14 +189,19 @@ def parse!
# action is actually a wrapper around the rule's action, with the
# match_data prepopulated.
#
- # ===== Params
- # path<Pathnane,String>:: Find action that corresponds to this path.
- # event_type<Symbol>:: Find action only if rule's event if of this type.
+ # @example
+ #
+ # script.watch( 'test/test_.*\.rb' ) {|md| "ruby #{md[0]}" }
+ # script.action_for('test/test_watchr.rb').call #=> "ruby test/test_watchr.rb"
+ #
+ # @param [Pathname, String] path
+ # find action that corresponds to this path.
#
- # ===== Examples
+ # @param [Symbol] event_type
+ # find action only if rule's event is of this type.
#
- # script.watch( 'test/test_.*\.rb' ) {|md| "ruby #{md[0]}" }
- # script.action_for('test/test_watchr.rb').call #=> "ruby test/test_watchr.rb"
+ # @return [Proc]
+ # action, preparsed and ready to be called
#
def action_for(path, event_type = DEFAULT_EVENT_TYPE)
path = rel_path(path).to_s
@@ -202,18 +216,18 @@ def action_for(path, event_type = DEFAULT_EVENT_TYPE)
# Collection of all patterns defined in script.
#
- # ===== Returns
- # patterns<String, Regexp>:: all patterns
+ # @return [Array<String,Regexp>]
+ # all defined patterns
#
def patterns
#@rules.every.pattern
@rules.map {|r| r.pattern }
end
- # Path to the script file
+ # Path to the script file corresponding to this object
#
- # ===== Returns
- # path<Pathname>:: absolute path to script file
+ # @return [Pathname]
+ # absolute path to script file
#
def path
@path && Pathname(@path.respond_to?(:to_path) ? @path.to_path : @path.to_s).expand_path
@@ -224,23 +238,23 @@ def path
# Rules corresponding to a given path, in reversed order of precedence
# (latest one is most inportant).
#
- # ===== Parameters
- # path<Pathname, String>:: path to look up rule for
+ # @param [Pathname, String] path
+ # path to look up rule for
#
- # ===== Returns
- # rules<Array(Rule)>:: rules corresponding to <tt>path</tt>
+ # @return [Array<Rule>]
+ # rules corresponding to `path`
#
def rules_for(path)
@rules.reverse.select {|rule| path.match(rule.pattern) }
end
# Make a path relative to current working directory.
#
- # ===== Parameters
- # path<Pathname, String>:: absolute or relative path
+ # @param [Pathname, String] path
+ # absolute or relative path
#
- # ===== Returns
- # path<Pathname>:: relative path, from current working directory.
+ # @return [Pathname]
+ # relative path, from current working directory.
#
def rel_path(path)
Pathname(path).expand_path.relative_path_from(Pathname(Dir.pwd))

0 comments on commit 3b088e0

Please sign in to comment.