Class: Watchr::Script

Inherits:
Object
  • Object
show all
Defined in:
lib/watchr/script.rb

Overview

A script object wraps a script file, and is used by a controller.

Examples
path   = Pathname.new('specs.watchr')
script = Watchr::Script.new(path)

Defined Under Namespace

Classes: API, Batch, Rule

Constant Summary collapse

DEFAULT_EVENT_TYPE =
:modified

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Script

Creates a script object for path.

Does not parse the script. The controller knows when to parse the script.

Parameters
path<Pathname>

the path to the script



114
115
116
117
118
119
# File 'lib/watchr/script.rb', line 114

def initialize(path)
  self.class.script = self
  @path  = path
  @rules = []
  @default_action = lambda {}
end

Class Attribute Details

.handlerObject

Returns the value of attribute handler.



226
227
228
# File 'lib/watchr/script.rb', line 226

def handler
  @handler
end

.scriptObject

Returns the value of attribute script.



226
227
228
# File 'lib/watchr/script.rb', line 226

def script
  @script
end

Class Method Details

.learn(path) ⇒ Object



227
228
229
230
231
# File 'lib/watchr/script.rb', line 227

def learn path
  script.depends_on(path).each do |p|
    handler.add Pathname(p)
  end
end

Instance Method Details

#call_action_for(path, event_type = DEFAULT_EVENT_TYPE) ⇒ Object

Find an action corresponding to a path and event type. The returned action is actually a wrapper around the rule’s action, with the match_data prepopulated.

Params
path<Pathnane,String>

Find action that correspond to this path.

event_type<Symbol>

Find action only if rule’s event if of this type.

Examples
script.watch( 'test/test_.*\.rb' ) {|md| "ruby #{md[0]}" }
script.action_for('test/test_watchr.rb').call #=> "ruby test/test_watchr.rb"


255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/watchr/script.rb', line 255

def call_action_for(path, event_type = DEFAULT_EVENT_TYPE)
  # $stderr.print "caf #{path}\n";
  pathname = path
  path = rel_path(path).to_s
  depended_on_by(path).each { |dependence| call_action_for(dependence, event_type) }
  rules_for(path).each do |rule|
    types = rule.event_types
    !types.empty? or types = [ nil ]
    types.each do |rule_event_type|
      if ( rule_event_type.nil? && ( event_type != :load ) ) || ( rule_event_type == event_type )
        data = path.match(rule.pattern)
        return rule.call(data, event_type, pathname)
      end
    end
  end
  nil
end

#default_action(&action) ⇒ Object

Convenience method. Define a default action to be triggered when a rule has none specified.

Examples
# in script file

default_action { system('rake --silent rdoc') }

watch( 'lib/.*\.rb'  )
watch( 'README.rdoc' )
watch( 'TODO.txt'    )
watch( 'LICENSE'     )

# 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') }


189
190
191
# File 'lib/watchr/script.rb', line 189

def default_action(&action)
  @default_action = action
end

#depended_on_by(path) ⇒ Object



238
239
240
# File 'lib/watchr/script.rb', line 238

def depended_on_by path
  []
end

#depends_on(path) ⇒ Object



234
235
236
# File 'lib/watchr/script.rb', line 234

def depends_on path
  []
end

#parse!Object

Eval content of script file. – TODO fix script file not found error



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/watchr/script.rb', line 196

def parse!
  Watchr.debug('loading script file %s' % @path.to_s.inspect)

  reset

  # Some editors do delete/rename. Even when they don't some events come very fast ...
  # and editor could do a trunc/write. If you look after the trunc, before the write, well,
  # things aren't pretty.
  
  # Should probably use a watchdog timer that gets reset on every change and then only fire actions
  # after the watchdog timer fires without get reset ..

  v = nil
  (1..10).each do
    old_v = v
    v = @path.read
    break if v != "" && v == old_v
    sleep(0.3)
  end

  instance_eval(@path.read)

rescue Errno::ENOENT
  # TODO figure out why this is happening. still can't reproduce
  Watchr.debug('script file "not found". wth')
  sleep(0.3) #enough?
  instance_eval(@path.read)
end

#pathObject

Path to the script file

Returns
path<Pathname>

path to script file



292
293
294
# File 'lib/watchr/script.rb', line 292

def path
  Pathname(@path.respond_to?(:to_path) ? @path.to_path : @path.to_s).expand_path
end

#patternsObject

Collection of all patterns defined in script.

Returns
patterns<String, Regexp>

all patterns



278
279
280
281
# File 'lib/watchr/script.rb', line 278

def patterns
  #@rules.every.pattern
  @rules.map {|r| r.pattern }
end

#rulesObject



283
284
285
# File 'lib/watchr/script.rb', line 283

def rules
  @rules
end

#watch(pattern, event_type = DEFAULT_EVENT_TYPE, predicate = nil, options = {}, &action) ⇒ Object

Main script API method. Builds a new rule, binding a pattern to an action.

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 “.”), 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).

Actions, the blocks passed to watch, receive a MatchData object as argument. It will be populated with the whole matched string (md) as well as individual backreferences (md). See MatchData#[] documentation for more details.

Examples
# 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_types<Symbol|Array<Symbol>>

Rule will only match events of one of these 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

Returns
rule<Rule>

rule created by the method



162
163
164
165
166
# File 'lib/watchr/script.rb', line 162

def watch(pattern, event_type = DEFAULT_EVENT_TYPE, predicate = nil, options = {}, &action)
  event_types = Array(event_type)
  @rules << Rule.new(pattern, event_types, predicate, options, action || @default_action)
  @rules.last
end