directory_watcher 1.1.2 → 1.2.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.
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ == 1.2.0 / 2009-04-12
2
+
3
+ * 2 minor enhancements
4
+ - added an option to persist state to a file [Benjamin Thomas]
5
+ - the option to run the directory watcher scanner manually
6
+
1
7
  == 1.1.2 / 2008-12-14
2
8
 
3
9
  * 1 minor bugfix
data/Rakefile CHANGED
@@ -3,7 +3,8 @@ begin
3
3
  require 'bones'
4
4
  Bones.setup
5
5
  rescue LoadError
6
- load 'tasks/setup.rb'
6
+ begin; load 'tasks/setup.rb'
7
+ rescue LoadError; abort '### please install the "bones" gem ###'; end
7
8
  end
8
9
 
9
10
  ensure_in_path 'lib'
@@ -18,6 +19,7 @@ PROJ.email = 'tim.pease@gmail.com'
18
19
  PROJ.url = 'http://codeforpeople.rubyforge.org/directory_watcher'
19
20
  PROJ.version = DirectoryWatcher::VERSION
20
21
  PROJ.rubyforge.name = 'codeforpeople'
22
+ PROJ.ignore_file = '.gitignore'
21
23
 
22
24
  PROJ.rdoc.remote_dir = 'directory_watcher'
23
25
  PROJ.spec.opts << '--color'
@@ -5,6 +5,7 @@
5
5
  #
6
6
 
7
7
  require 'observer'
8
+ require 'yaml'
8
9
 
9
10
  # == Synopsis
10
11
  #
@@ -132,6 +133,40 @@ require 'observer'
132
133
  # gets # when the user hits "enter" the script will terminate
133
134
  # dw.stop
134
135
  #
136
+ # === Persisting State
137
+ #
138
+ # A directory watcher can be configured to persist its current state to a
139
+ # file when it is stopped and to load state from that same file when it
140
+ # starts. Setting the +persist+ value to a filename will enable this
141
+ # feature.
142
+ #
143
+ # require 'directory_watcher'
144
+ #
145
+ # dw = DirectoryWatcher.new '.', :glob => '**/*.rb'
146
+ # dw.interval = 5.0
147
+ # dw.persist = "dw_state.yml"
148
+ # dw.add_observer {|*args| args.each {|event| puts event}}
149
+ #
150
+ # dw.start # loads state from dw_state.yml
151
+ # gets # when the user hits "enter" the script will terminate
152
+ # dw.stop # stores state to dw_state.yml
153
+ #
154
+ # === Running Once
155
+ #
156
+ # Instead of using the built in run loop, the directory watcher can be run
157
+ # one or many times using the +run_once+ method. The state of the directory
158
+ # watcher can be loaded and dumped if so desired.
159
+ #
160
+ # dw = DirectoryWatcher.new '.', :glob => '**/*.rb'
161
+ # dw.persist = "dw_state.yml"
162
+ # dw.add_observer {|*args| args.each {|event| puts event}}
163
+ #
164
+ # dw.load! # loads state from dw_state.yml
165
+ # dw.run_once
166
+ # sleep 5.0
167
+ # dw.run_once
168
+ # dw.persist! # stores state to dw_state.yml
169
+ #
135
170
  # == Contact
136
171
  #
137
172
  # A lot of discussion happens about Ruby in general on the ruby-talk
@@ -150,7 +185,7 @@ require 'observer'
150
185
  #
151
186
  class DirectoryWatcher
152
187
 
153
- VERSION = '1.1.2' # :nodoc:
188
+ VERSION = '1.2.0' # :nodoc:
154
189
 
155
190
  # An +Event+ structure contains the _type_ of the event and the file _path_
156
191
  # to which the event pertains. The type can be one of the following:
@@ -161,11 +196,19 @@ class DirectoryWatcher
161
196
  # :removed => file has been removed from the directory
162
197
  # :stable => file has stabilized since being added or modified
163
198
  #
164
- Event = Struct.new :type, :path
199
+ Event = Struct.new(:type, :path) do
200
+ def to_s( ) "#{type} '#{path}'" end
201
+ end
165
202
 
166
203
  # :stopdoc:
167
- class Event
168
- def to_s( ) "#{type} '#{path}'" end
204
+ # A persistable file stat structure used internally by the directory
205
+ # watcher.
206
+ #
207
+ FileStat = Struct.new(:mtime, :size, :stable) do
208
+ def <=>( other )
209
+ return unless other.is_a? ::DirectoryWatcher::FileStat
210
+ self.mtime <=> other.mtime
211
+ end
169
212
  end
170
213
  # :startdoc:
171
214
 
@@ -186,6 +229,9 @@ class DirectoryWatcher
186
229
  # round of file added events that would normally
187
230
  # be generated (glob pattern must also be
188
231
  # specified otherwise odd things will happen)
232
+ # :persist => file the state will be persisted to and restored
233
+ # from the file when the directory watcher is
234
+ # stopped and started (respectively)
189
235
  #
190
236
  # The default glob pattern will scan all files in the configured directory.
191
237
  # Setting the :stable option to +nil+ will prevent stable events from being
@@ -205,6 +251,7 @@ class DirectoryWatcher
205
251
  self.glob = opts[:glob] || '*'
206
252
  self.interval = opts[:interval] || 30
207
253
  self.stable = opts[:stable] || nil
254
+ self.persist = opts[:persist]
208
255
 
209
256
  @files = (opts[:pre_load] ? scan_files : Hash.new)
210
257
  @events = []
@@ -279,9 +326,6 @@ class DirectoryWatcher
279
326
  end
280
327
  attr_reader :glob
281
328
 
282
- # call-seq:
283
- # interval = 30.0
284
- #
285
329
  # Sets the directory scan interval. The directory will be scanned every
286
330
  # _interval_ seconds for changes to files matching the glob pattern.
287
331
  # Raises +ArgumentError+ if the interval is zero or negative.
@@ -293,9 +337,6 @@ class DirectoryWatcher
293
337
  end
294
338
  attr_reader :interval
295
339
 
296
- # call-seq:
297
- # stable = 2
298
- #
299
340
  # Sets the number of intervals a file must remain unchanged before it is
300
341
  # considered "stable". When this condition is met, a stable event is
301
342
  # generated for the file. If stable is set to +nil+ then stable events
@@ -328,9 +369,35 @@ class DirectoryWatcher
328
369
  end
329
370
  attr_reader :stable
330
371
 
331
- # call-seq:
332
- # running?
372
+ # Sets the name of the file to which the directory watcher state will be
373
+ # persisted when it is stopped. Setting the persist filename to +nil+ will
374
+ # disable this feature.
333
375
  #
376
+ def persist=( filename )
377
+ @persist = filename ? filename.to_s : nil
378
+ end
379
+ attr_reader :persist
380
+
381
+ # Write the current state of the directory watcher to the persist file.
382
+ # This method will do nothing if the directory watcher is running or if
383
+ # the persist file is not configured.
384
+ #
385
+ def persist!
386
+ return if running?
387
+ File.open(@persist, 'w') {|fd| fd.write YAML.dump(@files)} if @persist
388
+ self
389
+ end
390
+
391
+ # Loads the state of the directory watcher from the persist file. This
392
+ # method will do nothing if the directory watcher is running or if the
393
+ # persist file is not configured.
394
+ #
395
+ def load!
396
+ return if running?
397
+ @files = YAML.load_file(@persist) if @persist and test(?f, @persist)
398
+ self
399
+ end
400
+
334
401
  # Returns +true+ if the directory watcher is currently running. Returns
335
402
  # +false+ if this is not the case.
336
403
  #
@@ -338,23 +405,18 @@ class DirectoryWatcher
338
405
  !@thread.nil?
339
406
  end
340
407
 
341
- # call-seq:
342
- # start
343
- #
344
408
  # Start the directory watcher scanning thread. If the directory watcher is
345
409
  # already running, this method will return without taking any action.
346
410
  #
347
411
  def start
348
412
  return if running?
349
413
 
414
+ load!
350
415
  @stop = false
351
- @thread = Thread.new(self) {|dw| dw.__send__ :run}
416
+ @thread = Thread.new(self) {|dw| dw.__send__ :run_loop}
352
417
  self
353
418
  end
354
419
 
355
- # call-seq:
356
- # stop
357
- #
358
420
  # Stop the directory watcher scanning thread. If the directory watcher is
359
421
  # already stopped, this method will return without taking any action.
360
422
  #
@@ -364,8 +426,10 @@ class DirectoryWatcher
364
426
  @stop = true
365
427
  @thread.wakeup if @thread.status == 'sleep'
366
428
  @thread.join
367
- @thread = nil
368
429
  self
430
+ ensure
431
+ @thread = nil
432
+ persist!
369
433
  end
370
434
 
371
435
  # call-seq:
@@ -382,6 +446,7 @@ class DirectoryWatcher
382
446
  was_running = running?
383
447
 
384
448
  stop if was_running
449
+ File.delete(@persist) if @persist and test(?f, @persist)
385
450
  @files = (pre_load ? scan_files : Hash.new)
386
451
  start if was_running
387
452
  end
@@ -402,12 +467,28 @@ class DirectoryWatcher
402
467
  @thread.join limit
403
468
  end
404
469
 
470
+ # Performs exactly one scan of the directory for file changes and notifies
471
+ # the observers.
472
+ #
473
+ # This method wil not persist file changes if that options is configured.
474
+ # The user must call persist! explicitly when using the run_once method.
475
+ #
476
+ def run_once
477
+ files = scan_files
478
+ keys = [files.keys, @files.keys] # current files, previous files
479
+
480
+ find_added(files, *keys)
481
+ find_modified(files, *keys)
482
+ find_removed(*keys)
483
+
484
+ notify_observers
485
+ @files = files # store the current file list for the next iteration
486
+ self
487
+ end
488
+
405
489
 
406
490
  private
407
491
 
408
- # call-seq:
409
- # scan_files
410
- #
411
492
  # Using the configured glob pattern, scan the directory for all files and
412
493
  # return a hash with the filenames as keys and +File::Stat+ objects as the
413
494
  # values. The +File::Stat+ objects contain the mtime and size of the file.
@@ -419,35 +500,24 @@ class DirectoryWatcher
419
500
  begin
420
501
  stat = File.stat fn
421
502
  next unless stat.file?
422
- files[fn] = stat
503
+ files[fn] = DirectoryWatcher::FileStat.new(stat.mtime, stat.size)
423
504
  rescue SystemCallError; end
424
505
  end
425
506
  end
426
507
  files
427
508
  end
428
509
 
429
- # call-seq:
430
- # run
431
- #
432
510
  # Calling this method will enter the directory watcher's run loop. The
433
511
  # calling thread will not return until the +stop+ method is called.
434
512
  #
435
513
  # The run loop is responsible for scanning the directory for file changes,
436
514
  # and then dispatching events to registered listeners.
437
515
  #
438
- def run
516
+ def run_loop
439
517
  until @stop
440
518
  start = Time.now.to_f
441
519
 
442
- files = scan_files
443
- keys = [files.keys, @files.keys] # current files, previous files
444
-
445
- find_added(files, *keys)
446
- find_modified(files, *keys)
447
- find_removed(*keys)
448
-
449
- notify_observers
450
- @files = files # store the current file list for the next iteration
520
+ run_once
451
521
 
452
522
  nap_time = @interval - (Time.now.to_f - start)
453
523
  sleep nap_time if nap_time > 0
@@ -516,9 +586,6 @@ class DirectoryWatcher
516
586
  self
517
587
  end
518
588
 
519
- # call-seq:
520
- # notify_observers
521
- #
522
589
  # If there are queued files events, then invoke the update method of each
523
590
  # registered observer in turn passing the list of file events to each.
524
591
  # The file events array is cleared at the end of this method call.
@@ -534,11 +601,4 @@ class DirectoryWatcher
534
601
 
535
602
  end # class DirectoryWatcher
536
603
 
537
- # :stopdoc:
538
- # We need to add a 'stable' attribute to the File::Stat object
539
- class File::Stat
540
- attr_accessor :stable
541
- end
542
- # :startdoc:
543
-
544
604
  # EOF
data/tasks/gem.rake CHANGED
@@ -37,8 +37,6 @@ class GemPackageTask < Rake::PackageTask
37
37
  local_setup = File.join(Dir.pwd, %w[tasks setup.rb])
38
38
  if !test(?e, local_setup)
39
39
  Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn}
40
- gem_spec.files = (gem_spec.files +
41
- bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
42
40
  end
43
41
  end
44
42
 
@@ -63,6 +61,10 @@ class GemPackageTask < Rake::PackageTask
63
61
 
64
62
  file package_dir_path => bones_files do
65
63
  mkdir_p package_dir rescue nil
64
+
65
+ gem_spec.files = (gem_spec.files +
66
+ bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort
67
+
66
68
  bones_files.each do |fn|
67
69
  base_fn = File.join('tasks', File.basename(fn))
68
70
  f = File.join(package_dir_path, base_fn)
@@ -157,6 +159,13 @@ namespace :gem do
157
159
  puts PROJ.gem._spec.to_ruby
158
160
  end
159
161
 
162
+ desc 'Write the gemspec '
163
+ task :spec => 'gem:prereqs' do
164
+ File.open("#{PROJ.name}.gemspec", 'w') do |f|
165
+ f.write PROJ.gem._spec.to_ruby
166
+ end
167
+ end
168
+
160
169
  desc 'Install the gem'
161
170
  task :install => [:clobber, 'gem:package'] do
162
171
  sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
data/tasks/post_load.rake CHANGED
@@ -2,8 +2,8 @@
2
2
  # This file does not define any rake tasks. It is used to load some project
3
3
  # settings if they are not defined by the user.
4
4
 
5
- PROJ.rdoc.exclude << "^#{Regexp.escape(PROJ.manifest_file)}$"
6
5
  PROJ.exclude << ["^#{Regexp.escape(PROJ.ann.file)}$",
6
+ "^#{Regexp.escape(PROJ.ignore_file)}$",
7
7
  "^#{Regexp.escape(PROJ.rdoc.dir)}/",
8
8
  "^#{Regexp.escape(PROJ.rcov.dir)}/"]
9
9
 
@@ -25,12 +25,7 @@ PROJ.description ||= paragraphs_of(PROJ.readme_file, 'description').join("\n\n")
25
25
 
26
26
  PROJ.summary ||= PROJ.description.split('.').first
27
27
 
28
- PROJ.gem.files ||=
29
- if test(?f, PROJ.manifest_file)
30
- files = File.readlines(PROJ.manifest_file).map {|fn| fn.chomp.strip}
31
- files.delete ''
32
- files
33
- else [] end
28
+ PROJ.gem.files ||= manifest
34
29
 
35
30
  PROJ.gem.executables ||= PROJ.gem.files.find_all {|fn| fn =~ %r/^bin/}
36
31
 
data/tasks/rdoc.rake CHANGED
@@ -19,10 +19,11 @@ namespace :doc do
19
19
  end
20
20
  rd.rdoc_files.push(*files)
21
21
 
22
- title = "#{PROJ.name}-#{PROJ.version} Documentation"
23
-
22
+ name = PROJ.name
24
23
  rf_name = PROJ.rubyforge.name
25
- title = "#{rf_name}'s " + title if rf_name.valid? and rf_name != title
24
+
25
+ title = "#{name}-#{PROJ.version} Documentation"
26
+ title = "#{rf_name}'s " + title if rf_name.valid? and rf_name != name
26
27
 
27
28
  rd.options << "-t #{title}"
28
29
  rd.options.concat(rdoc.opts)
data/tasks/setup.rb CHANGED
@@ -4,8 +4,9 @@ require 'rake'
4
4
  require 'rake/clean'
5
5
  require 'fileutils'
6
6
  require 'ostruct'
7
+ require 'find'
7
8
 
8
- class OpenStruct; undef :gem; end
9
+ class OpenStruct; undef :gem if defined? :gem; end
9
10
 
10
11
  # TODO: make my own openstruct type object that includes descriptions
11
12
  # TODO: use the descriptions to output help on the available bones options
@@ -27,8 +28,8 @@ PROJ = OpenStruct.new(
27
28
  :ruby_opts => %w(-w),
28
29
  :libs => [],
29
30
  :history_file => 'History.txt',
30
- :manifest_file => 'Manifest.txt',
31
31
  :readme_file => 'README.txt',
32
+ :ignore_file => '.bnsignore',
32
33
 
33
34
  # Announce
34
35
  :ann => OpenStruct.new(
@@ -123,9 +124,7 @@ import(*rakefiles)
123
124
  %w(lib ext).each {|dir| PROJ.libs << dir if test ?d, dir}
124
125
 
125
126
  # Setup some constants
126
- WIN32 = %r/djgpp|(cyg|ms|bcc)win|mingw/ =~ RUBY_PLATFORM unless defined? WIN32
127
-
128
- DEV_NULL = WIN32 ? 'NUL:' : '/dev/null'
127
+ DEV_NULL = File.exist?('/dev/null') ? '/dev/null' : 'NUL:'
129
128
 
130
129
  def quiet( &block )
131
130
  io = [STDOUT.dup, STDERR.dup]
@@ -138,23 +137,17 @@ ensure
138
137
  $stdout, $stderr = STDOUT, STDERR
139
138
  end
140
139
 
141
- DIFF = if WIN32 then 'diff.exe'
142
- else
143
- if quiet {system "gdiff", __FILE__, __FILE__} then 'gdiff'
144
- else 'diff' end
145
- end unless defined? DIFF
140
+ DIFF = if system("gdiff '#{__FILE__}' '#{__FILE__}' > #{DEV_NULL} 2>&1") then 'gdiff'
141
+ else 'diff' end unless defined? DIFF
146
142
 
147
- SUDO = if WIN32 then ''
148
- else
149
- if quiet {system 'which sudo'} then 'sudo'
150
- else '' end
151
- end
143
+ SUDO = if system("which sudo > #{DEV_NULL} 2>&1") then 'sudo'
144
+ else '' end unless defined? SUDO
152
145
 
153
- RCOV = WIN32 ? 'rcov.bat' : 'rcov'
154
- RDOC = WIN32 ? 'rdoc.bat' : 'rdoc'
155
- GEM = WIN32 ? 'gem.bat' : 'gem'
146
+ RCOV = "#{RUBY} -S rcov"
147
+ RDOC = "#{RUBY} -S rdoc"
148
+ GEM = "#{RUBY} -S gem"
156
149
 
157
- %w(rcov spec/rake/spectask rubyforge bones facets/ansicode).each do |lib|
150
+ %w(rcov spec/rake/spectask rubyforge bones facets/ansicode zentest).each do |lib|
158
151
  begin
159
152
  require lib
160
153
  Object.instance_eval {const_set "HAVE_#{lib.tr('/','_').upcase}", true}
@@ -254,9 +247,29 @@ end
254
247
  # Scans the current working directory and creates a list of files that are
255
248
  # candidates to be in the manifest.
256
249
  #
257
- def manifest_files
250
+ def manifest
258
251
  files = []
259
- exclude = Regexp.new(PROJ.exclude.join('|'))
252
+ exclude = PROJ.exclude.dup
253
+ comment = %r/^\s*#/
254
+
255
+ # process the ignore file and add the items there to the exclude list
256
+ if test(?f, PROJ.ignore_file)
257
+ ary = []
258
+ File.readlines(PROJ.ignore_file).each do |line|
259
+ next if line =~ comment
260
+ line.chomp!
261
+ line.strip!
262
+ next if line.nil? or line.empty?
263
+
264
+ glob = line =~ %r/\*\./ ? File.join('**', line) : line
265
+ Dir.glob(glob).each {|fn| ary << "^#{Regexp.escape(fn)}"}
266
+ end
267
+ exclude.concat ary
268
+ end
269
+
270
+ # generate a regular expression from the exclude list
271
+ exclude = Regexp.new(exclude.join('|'))
272
+
260
273
  Find.find '.' do |path|
261
274
  path.sub! %r/^(\.\/|\/)/o, ''
262
275
  next unless test ?f, path
@@ -0,0 +1,36 @@
1
+ if HAVE_ZENTEST
2
+
3
+ # --------------------------------------------------------------------------
4
+ if test(?e, PROJ.test.file) or not PROJ.test.files.to_a.empty?
5
+ require 'autotest'
6
+
7
+ namespace :test do
8
+ task :autotest do
9
+ Autotest.run
10
+ end
11
+ end
12
+
13
+ desc "Run the autotest loop"
14
+ task :autotest => 'test:autotest'
15
+
16
+ end # if test
17
+
18
+ # --------------------------------------------------------------------------
19
+ if HAVE_SPEC_RAKE_SPECTASK and not PROJ.spec.files.to_a.empty?
20
+ require 'autotest/rspec'
21
+
22
+ namespace :spec do
23
+ task :autotest do
24
+ load '.autotest' if test(?f, '.autotest')
25
+ Autotest::Rspec.run
26
+ end
27
+ end
28
+
29
+ desc "Run the autotest loop"
30
+ task :autotest => 'spec:autotest'
31
+
32
+ end # if rspec
33
+
34
+ end # if HAVE_ZENTEST
35
+
36
+ # EOF
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: directory_watcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Pease
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-14 00:00:00 -07:00
12
+ date: 2009-04-12 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 2.1.1
23
+ version: 2.5.0
24
24
  version:
25
25
  description: ""
26
26
  email: tim.pease@gmail.com
@@ -33,7 +33,6 @@ extra_rdoc_files:
33
33
  - README.txt
34
34
  files:
35
35
  - History.txt
36
- - Manifest.txt
37
36
  - README.txt
38
37
  - Rakefile
39
38
  - lib/directory_watcher.rb
@@ -41,7 +40,6 @@ files:
41
40
  - tasks/bones.rake
42
41
  - tasks/gem.rake
43
42
  - tasks/git.rake
44
- - tasks/manifest.rake
45
43
  - tasks/notes.rake
46
44
  - tasks/post_load.rake
47
45
  - tasks/rdoc.rake
@@ -50,6 +48,7 @@ files:
50
48
  - tasks/spec.rake
51
49
  - tasks/svn.rake
52
50
  - tasks/test.rake
51
+ - tasks/zentest.rake
53
52
  has_rdoc: true
54
53
  homepage: http://codeforpeople.rubyforge.org/directory_watcher
55
54
  post_install_message:
data/Manifest.txt DELETED
@@ -1,5 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- README.txt
4
- Rakefile
5
- lib/directory_watcher.rb
data/tasks/manifest.rake DELETED
@@ -1,48 +0,0 @@
1
-
2
- require 'find'
3
-
4
- namespace :manifest do
5
-
6
- desc 'Verify the manifest'
7
- task :check do
8
- fn = PROJ.manifest_file + '.tmp'
9
- files = manifest_files
10
-
11
- File.open(fn, 'w') {|fp| fp.puts files}
12
- lines = %x(#{DIFF} -du #{PROJ.manifest_file} #{fn}).split("\n")
13
- if HAVE_FACETS_ANSICODE and ENV.has_key?('TERM')
14
- lines.map! do |line|
15
- case line
16
- when %r/^(-{3}|\+{3})/; nil
17
- when %r/^@/; ANSICode.blue line
18
- when %r/^\+/; ANSICode.green line
19
- when %r/^\-/; ANSICode.red line
20
- else line end
21
- end
22
- end
23
- puts lines.compact
24
- rm fn rescue nil
25
- end
26
-
27
- desc 'Create a new manifest'
28
- task :create do
29
- files = manifest_files
30
- unless test(?f, PROJ.manifest_file)
31
- files << PROJ.manifest_file
32
- files.sort!
33
- end
34
- File.open(PROJ.manifest_file, 'w') {|fp| fp.puts files}
35
- end
36
-
37
- task :assert do
38
- files = manifest_files
39
- manifest = File.read(PROJ.manifest_file).split($/)
40
- raise "ERROR: #{PROJ.manifest_file} is out of date" unless files == manifest
41
- end
42
-
43
- end # namespace :manifest
44
-
45
- desc 'Alias to manifest:check'
46
- task :manifest => 'manifest:check'
47
-
48
- # EOF