rant 0.4.4 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/NEWS +38 -0
  2. data/README +4 -2
  3. data/Rantfile +50 -12
  4. data/doc/examples/c_cpp/c++/problem_1_1/another_test.cpp +6 -0
  5. data/doc/examples/c_cpp/c++/problem_1_1/another_test.h +5 -0
  6. data/doc/examples/c_cpp/c++/problem_1_1/main.cpp +12 -0
  7. data/doc/examples/c_cpp/c++/problem_1_1/test.cpp +6 -0
  8. data/doc/examples/c_cpp/c++/problem_1_1/test.h +5 -0
  9. data/doc/examples/c_cpp/c++/template.rf +15 -0
  10. data/doc/examples/c_cpp/c/problem_1_1/another_test.c +6 -0
  11. data/doc/examples/c_cpp/c/problem_1_1/another_test.h +7 -0
  12. data/doc/examples/c_cpp/c/problem_1_1/main.c +12 -0
  13. data/doc/examples/c_cpp/c/problem_1_1/test.c +6 -0
  14. data/doc/examples/c_cpp/c/problem_1_1/test.h +7 -0
  15. data/doc/examples/c_cpp/c/template.rf +15 -0
  16. data/doc/examples/c_cpp/root.rant +46 -0
  17. data/doc/homepage/index.html +115 -0
  18. data/doc/homepage/rant_home.css +98 -0
  19. data/doc/rant.1 +129 -0
  20. data/doc/rant.rdoc +5 -6
  21. data/doc/rantfile.rdoc +55 -32
  22. data/doc/subdirs.rdoc +147 -0
  23. data/lib/rant.rb +47 -49
  24. data/lib/rant/coregen.rb +20 -20
  25. data/lib/rant/import.rb +63 -11
  26. data/lib/rant/import/archive.rb +47 -15
  27. data/lib/rant/import/archive/tgz.rb +1 -1
  28. data/lib/rant/import/autoclean.rb +28 -26
  29. data/lib/rant/import/c/dependencies.rb +1 -1
  30. data/lib/rant/import/directedrule.rb +1 -4
  31. data/lib/rant/import/metadata.rb +30 -7
  32. data/lib/rant/import/nodes/default.rb +67 -13
  33. data/lib/rant/import/rubypackage.rb +1 -1
  34. data/lib/rant/import/rubytest.rb +25 -19
  35. data/lib/rant/import/signedfile.rb +14 -8
  36. data/lib/rant/import/sys/more.rb +22 -0
  37. data/lib/rant/import/sys/tgz.rb +43 -0
  38. data/lib/rant/import/sys/zip.rb +42 -0
  39. data/lib/rant/node.rb +19 -13
  40. data/lib/rant/plugin/configure.rb +1 -1
  41. data/lib/rant/progress.rb +33 -0
  42. data/lib/rant/rantenv.rb +7 -7
  43. data/lib/rant/rantlib.rb +246 -256
  44. data/lib/rant/rantsys.rb +61 -22
  45. data/lib/rant/rantvar.rb +7 -9
  46. data/misc/TODO +18 -0
  47. data/misc/devel-notes +4 -1
  48. data/test/Rantfile +17 -3
  49. data/test/deprecated/README +6 -0
  50. data/test/deprecated/test_0_4_8.rb +41 -0
  51. data/test/deprecated/test_0_5_2.rb +33 -0
  52. data/test/import/md5/root.rant +9 -0
  53. data/test/import/md5/test_md5.rb +45 -0
  54. data/test/import/metadata/Rantfile +2 -2
  55. data/test/import/metadata/test_metadata.rb +2 -2
  56. data/test/import/package/test_package.rb +40 -1
  57. data/test/import/signedfile/sub1/Rantfile +1 -1
  58. data/test/import/sys/data/pkg.tgz +0 -0
  59. data/test/import/sys/data/pkg.zip +0 -0
  60. data/test/import/sys/data/pkg/bin/test +0 -0
  61. data/test/import/sys/data/pkg/bin/test.o +0 -0
  62. data/test/import/sys/data/pkg/test.c +6 -0
  63. data/test/import/sys/data/pkg/test.h +7 -0
  64. data/test/import/sys/data/pkg2.zip +0 -0
  65. data/test/import/sys/test_tgz.rb +38 -0
  66. data/test/import/sys/test_zip.rb +68 -0
  67. data/test/import/sys/tgz.rf +6 -0
  68. data/test/import/sys/zip.rf +15 -0
  69. data/test/project2/{rantfile.rb → root.rant} +0 -0
  70. data/test/project2/test_project.rb +3 -8
  71. data/test/project_rb1/{rantfile.rb → rantfile} +1 -1
  72. data/test/project_rb1/test_project_rb1.rb +3 -5
  73. data/test/rant-import/test_rant-import.rb +22 -10
  74. data/test/subdirs/sub1/Rantfile +1 -1
  75. data/test/subdirs/sub2/{rantfile.rb → rantfile} +0 -0
  76. data/test/subdirs/sub2/sub/rantfile +1 -1
  77. data/test/subdirs2/root.rant +36 -0
  78. data/test/subdirs2/sub00/sub.rant +8 -0
  79. data/test/subdirs2/sub1/sub.rant +13 -0
  80. data/test/subdirs2/test_subdirs2.rb +239 -0
  81. data/test/test_examples.rb +91 -0
  82. data/test/test_filetask.rb +51 -11
  83. data/test/test_rant_interface.rb +24 -0
  84. data/test/test_rantfile_api.rb +54 -2
  85. data/test/test_sourcenode.rb +30 -0
  86. data/test/test_sys.rb +143 -15
  87. data/test/test_task.rb +16 -22
  88. data/test/tutil.rb +22 -38
  89. metadata +67 -9
@@ -102,7 +102,7 @@ class Rant::Generators::C::Dependencies
102
102
  end
103
103
  rf_str << file_deps(cf, deps) << "\n"
104
104
  }
105
- rac.msg 1, "writing C source dependencies to #{t.name}"
105
+ rac.vmsg 1, "writing C source dependencies to #{t.name}"
106
106
  open(t.name, "w") { |f|
107
107
  f.puts
108
108
  f.puts "# #{t.name}"
@@ -73,10 +73,7 @@ class Rant::Generators::DirectedRule
73
73
  @esc_target_dir = Regexp.escape(target_dir)
74
74
  @block = block
75
75
  end
76
- def call(name)
77
- self[name]
78
- end
79
- def [](name)
76
+ def [](name, rel_project_dir)
80
77
  #puts "rule (#@target) for #{name} ?"
81
78
  if name =~ /^#@esc_target_dir\// && name =~ @target_rx
82
79
  #puts " matches"
@@ -40,7 +40,7 @@ module Rant
40
40
  # => Dir.pwd has to be: /home/foo/myproject/bar
41
41
  #
42
42
  # Returns nil only if the value doesn't exist.
43
- def fetch(key, target, dir=@rac.current_subdir)
43
+ def fetch(key, target, dir=@rac.current_subdir, meta_dir=nil)
44
44
  # first check if a value for the given key, target and
45
45
  # dir already exists
46
46
  dstore = @store[dir]
@@ -53,7 +53,7 @@ module Rant
53
53
  end
54
54
  # check if the meta file in dir was already read
55
55
  unless @read_dirs.include? dir
56
- read_meta_file_in_dir(dir)
56
+ read_meta_file_in_dir(dir, meta_dir)
57
57
  end
58
58
  tstore = @store[dir][target]
59
59
  tstore[key] if tstore
@@ -82,6 +82,29 @@ module Rant
82
82
  nil
83
83
  end
84
84
 
85
+ def path_fetch(key, target_path)
86
+ tdir, fn = File.split target_path
87
+ sdir = @rac.current_subdir
88
+ if tdir == '.'
89
+ fetch(key, fn, sdir)
90
+ else
91
+ dir = sdir.empty? ? tdir : "#{sdir}/#{tdir}"
92
+ fetch(key, fn, dir, tdir)
93
+ end
94
+ end
95
+
96
+ def path_set(key, value, target_path)
97
+ tdir, fn = File.split target_path
98
+ sdir = @rac.current_subdir
99
+ if tdir == '.'
100
+ dir = sdir
101
+ else
102
+ dir = sdir.empty? ? tdir : "#{sdir}/#{tdir}"
103
+ end
104
+ #STDERR.puts "#{key}:#{value}:#{fn}:#{dir}"
105
+ set(key, value, fn, dir)
106
+ end
107
+
85
108
  # Assumes to be called from the projects root directory.
86
109
  def save
87
110
  @modified_dirs.each_key { |dir|
@@ -92,12 +115,12 @@ module Rant
92
115
 
93
116
  private
94
117
  # assumes that dir is already the current working
95
- # directory
96
- def read_meta_file_in_dir(dir)
118
+ # directory if meta_dir is nil
119
+ def read_meta_file_in_dir(dir, meta_dir)
97
120
  #puts "in dir: #{dir}, pwd: #{Dir.pwd}"
98
121
  @read_dirs[dir] = true
99
122
  #fn = dir.empty? ? META_FN : File.join(dir, META_FN)
100
- fn = META_FN
123
+ fn = meta_dir ? File.join(meta_dir, META_FN) : META_FN
101
124
  dstore = @store[dir]
102
125
  @store[dir] = dstore = {} unless dstore
103
126
  return unless File.exist? fn
@@ -151,8 +174,8 @@ module Rant
151
174
 
152
175
  def invalid_format(fn)
153
176
  raise Rant::Error, "The file `#{fn}' is used by " +
154
- "Rant to store meta information, it is in an " +
155
- "invalid state. Check that it doesn't contain " +
177
+ "Rant to store meta information, it is in an\n" +
178
+ "invalid state. Check that it doesn't contain\n" +
156
179
  "important data, remove it and retry."
157
180
  end
158
181
 
@@ -32,12 +32,11 @@ module Rant
32
32
 
33
33
  class Task
34
34
  include Node
35
- include Console
36
35
 
37
36
  def initialize(rac, name, prerequisites = [], &block)
38
37
  super()
39
- @rac = rac || Rant.rac
40
- @name = name or raise ArgumentError, "name not given"
38
+ @rac = rac or raise ArgumentError, "rac not given"
39
+ @name = name or raise ArgumentError, "name not given"
41
40
  @pre = prerequisites || []
42
41
  @pre_resolved = false
43
42
  @block = block
@@ -126,7 +125,7 @@ module Rant
126
125
  end
127
126
  end
128
127
 
129
- def internal_invoke opt, ud_init = true
128
+ def internal_invoke(opt, ud_init = true)
130
129
  goto_task_home
131
130
  update = ud_init || opt[:force]
132
131
  dep = nil
@@ -187,7 +186,7 @@ module Rant
187
186
  #
188
187
  # See also: handle_node, handle_timestamped
189
188
  def handle_non_node(dep, opt)
190
- err_msg "Unknown task `#{dep}',",
189
+ @rac.err_msg "Unknown task `#{dep}',",
191
190
  "referenced in `#{rantfile.path}', line #{@line_number}!"
192
191
  self.fail
193
192
  end
@@ -246,6 +245,7 @@ module Rant
246
245
  # used for initialization, not ment as action
247
246
  @block = nil
248
247
  @needed = nil
248
+ @target_files = nil
249
249
  # allow setting of @block and @needed
250
250
  yield self if block_given?
251
251
  end
@@ -257,6 +257,25 @@ module Rant
257
257
  def needed(&block)
258
258
  @needed = block
259
259
  end
260
+
261
+ def file_target?
262
+ @target_files and @target_files.include? @name
263
+ end
264
+
265
+ def each_target(&block)
266
+ goto_task_home
267
+ @target_files.each(&block) if @target_files
268
+ end
269
+
270
+ def file_target(*args)
271
+ args.flatten!
272
+ args << @name if args.empty?
273
+ if @target_files
274
+ @target_files.concat(args)
275
+ else
276
+ @target_files = args
277
+ end
278
+ end
260
279
 
261
280
  # We simply override this method and call internal_invoke with
262
281
  # the +ud_init+ flag according to the result of a call to the
@@ -289,6 +308,10 @@ module Rant
289
308
  @ts = T0
290
309
  end
291
310
 
311
+ def file_target?
312
+ true
313
+ end
314
+
292
315
  def needed?
293
316
  return false if done?
294
317
  invoke(:needed? => true)
@@ -312,20 +335,32 @@ module Rant
312
335
  end
313
336
  end
314
337
 
315
- def timestamp
338
+ def timestamp(opt = INVOKE_OPT)
316
339
  File.exist?(@name) ? File.mtime(@name) : T0
317
340
  end
318
341
 
342
+ def handle_node(dep, opt)
343
+ #STDERR.puts "treating #{dep.full_name} as file dependency"
344
+ return true if dep.file_target? && dep.invoke(opt)
345
+ if File.exist? dep.name
346
+ File.mtime(dep.name) > @ts
347
+ elsif !dep.file_target?
348
+ @rac.err_msg @rac.pos_text(rantfile.path, line_number),
349
+ "in prerequisites: no such file: `#{dep.full_name}'"
350
+ self.fail
351
+ end
352
+ end
353
+
319
354
  def handle_timestamped(dep, opt)
320
355
  return true if dep.invoke opt
321
356
  #puts "***`#{dep.name}' requires update" if dep.timestamp > @ts
322
- dep.timestamp > @ts
357
+ dep.timestamp(opt) > @ts
323
358
  end
324
359
 
325
360
  def handle_non_node(dep, opt)
326
361
  goto_task_home # !!??
327
362
  unless File.exist? dep
328
- err_msg @rac.pos_text(rantfile.path, line_number),
363
+ @rac.err_msg @rac.pos_text(rantfile.path, line_number),
329
364
  "in prerequisites: no such file or task: `#{dep}'"
330
365
  self.fail
331
366
  end
@@ -342,8 +377,9 @@ module Rant
342
377
  private
343
378
  def run
344
379
  goto_task_home
380
+ @rac.running_task(self)
345
381
  dir = File.dirname(name)
346
- @rac.build dir unless dir == "."
382
+ @rac.build dir unless dir == "." || dir == "/"
347
383
  return unless @block
348
384
  @block.arity == 0 ? @block.call : @block[self]
349
385
  end
@@ -382,15 +418,31 @@ module Rant
382
418
  end
383
419
  end
384
420
 
421
+ def file_target?
422
+ true
423
+ end
424
+
425
+ def handle_node(dep, opt)
426
+ #STDERR.puts "treating #{dep.full_name} as file dependency"
427
+ return true if dep.file_target? && dep.invoke(opt)
428
+ if File.exist? dep.name
429
+ File.mtime(dep.name) > @ts
430
+ elsif !dep.file_target?
431
+ @rac.err_msg @rac.pos_text(rantfile.path, line_number),
432
+ "in prerequisites: no such file: `#{dep.full_name}'"
433
+ self.fail
434
+ end
435
+ end
436
+
385
437
  def handle_timestamped(dep, opt)
386
438
  return @block if dep.invoke opt
387
- @block && dep.timestamp > @ts
439
+ @block && dep.timestamp(opt) > @ts
388
440
  end
389
441
 
390
442
  def handle_non_node(dep, opt)
391
443
  goto_task_home
392
444
  unless File.exist? dep
393
- err_msg @rac.pos_text(rantfile.path, line_number),
445
+ @rac.err_msg @rac.pos_text(rantfile.path, line_number),
394
446
  "in prerequisites: no such file or task: `#{dep}'"
395
447
  self.fail
396
448
  end
@@ -398,6 +450,7 @@ module Rant
398
450
  end
399
451
 
400
452
  def run
453
+ @rac.running_task(self)
401
454
  @rac.sys.mkdir @name unless @isdir
402
455
  if @block
403
456
  @block.arity == 0 ? @block.call : @block[self]
@@ -438,7 +491,7 @@ module Rant
438
491
  @pre
439
492
  end
440
493
  # Note: The timestamp will only be calculated once!
441
- def timestamp
494
+ def timestamp(opt = INVOKE_OPT)
442
495
  # Circular dependencies don't generate endless
443
496
  # recursion/loops because before calling the timestamp
444
497
  # method of any other node, we set @ts to some non-nil
@@ -464,8 +517,9 @@ module Rant
464
517
  end
465
518
  else
466
519
  nodes.each { |node|
520
+ node.invoke(opt)
467
521
  if node.respond_to? :timestamp
468
- node_ts = node.timestamp
522
+ node_ts = node.timestamp(opt)
469
523
  goto_task_home
470
524
  @ts = node_ts if node_ts > @ts
471
525
  else
@@ -106,7 +106,7 @@ class Rant::Generators::RubyPackage
106
106
  attr_accessor :pkg_dir
107
107
 
108
108
  def initialize(opts = {})
109
- @app = opts[:app] || Rant.rantapp
109
+ @app = opts[:app] or raise ":app argument required"
110
110
  @pkg_dir = "pkg"
111
111
  @pkg_dir_task = nil
112
112
  @gem_task = nil
@@ -46,18 +46,18 @@ module Rant
46
46
 
47
47
  @pre ||= []
48
48
  # define the task
49
- app.task({:__caller__ => cinf, @name => @pre}) { |t|
50
- arg = ""
51
- libpath = (@libs.nil? || @libs.empty?) ?
52
- nil : @libs.join(File::PATH_SEPARATOR)
53
- if libpath
54
- arg << "-I " << Env.shell_path(libpath) << " "
55
- end
56
- arg << "-S testrb " << optlist
49
+ app.task(:__caller__ => cinf, @name => @pre) { |t|
50
+ args = []
51
+ if @libs && !@libs.empty?
52
+ args << "-I#{@libs.join File::PATH_SEPARATOR}"
53
+ end
54
+ # TODO: don't use testrb
55
+ args << "-S" << "testrb"
56
+ args.concat optlist
57
57
  if @test_dir
58
- app.context.sys.cd(@test_dir) {
59
- arg << filelist.arglist
60
- app.context.sys.ruby arg
58
+ app.sys.cd(@test_dir) {
59
+ args.concat filelist
60
+ app.sys.ruby args
61
61
  }
62
62
  else
63
63
  if test(?d, "test")
@@ -65,26 +65,32 @@ module Rant
65
65
  elsif test(?d, "tests")
66
66
  @test_dirs << "tests"
67
67
  end
68
- arg << filelist.arglist
69
- app.context.sys.ruby arg
68
+ args.concat filelist
69
+ app.context.sys.ruby args
70
70
  end
71
71
  }
72
72
  end
73
73
  def optlist
74
- options = (@options.is_a? Array) ?
75
- @options.arglist : @options
76
- @rac.cx.var["TESTOPTS"] || options || ""
74
+ if @options.respond_to? :to_ary
75
+ @options.to_ary
76
+ elsif @options
77
+ [@options.to_str]
78
+ else
79
+ []
80
+ end
81
+ # previously Rant (0.4.4 and earlier versions) honoured
82
+ # var["TESTOPTS"]
77
83
  end
78
84
  def filelist
79
- return Dir[@rac.cx.var['TEST']] if @rac.cx.var['TEST']
85
+ return @rac.sys[@rac.var['TEST']] if @rac.var['TEST']
80
86
  filelist = @test_files || []
81
87
  if filelist.empty?
82
88
  if @test_dirs && !@test_dirs.empty?
83
89
  @test_dirs.each { |dir|
84
- filelist.concat(Dir[File.join(dir, @pattern)])
90
+ filelist.concat(@rac.sys[File.join(dir, @pattern)])
85
91
  }
86
92
  else
87
- filelist.concat(Dir[@pattern]) if @pattern
93
+ filelist.concat(@rac.sys[@pattern]) if @pattern
88
94
  end
89
95
  end
90
96
  filelist
@@ -43,6 +43,9 @@ module Rant
43
43
  def has_actions?
44
44
  !!@block
45
45
  end
46
+ def file_target?
47
+ true
48
+ end
46
49
  def <<(pre)
47
50
  @pre << pre
48
51
  end
@@ -94,8 +97,8 @@ module Rant
94
97
  check_str = @cur_checksums.join
95
98
  @cur_checksums = nil
96
99
  metadata = @rac.var._get("__metadata__")
97
- old_check_str = metadata.fetch(key, @name)
98
- old_target_str = metadata.fetch(target_key, @name)
100
+ old_check_str = metadata.path_fetch(key, @name)
101
+ old_target_str = metadata.path_fetch(target_key, @name)
99
102
  # check explicitely for plain file, thus allow the
100
103
  # target of a SignedFile to be a directory ;)
101
104
  if test(?f, @name)
@@ -116,10 +119,10 @@ module Rant
116
119
  @sigs.signature_for_file(@name) : ""
117
120
  target_changed = target_str != old_target_str
118
121
  if target_changed
119
- metadata.set(target_key, target_str, @name)
122
+ metadata.path_set(target_key, target_str, @name)
120
123
  end
121
124
  if check_str_changed
122
- metadata.set(key, check_str, @name)
125
+ metadata.path_set(key, check_str, @name)
123
126
  end
124
127
  return target_changed
125
128
  rescue TaskFail => e
@@ -135,7 +138,7 @@ module Rant
135
138
  goto_task_home
136
139
  yield @name
137
140
  end
138
- def timestamp
141
+ def timestamp(opt = INVOKE_OPT)
139
142
  File.exist?(@name) ? File.mtime(@name) : T0
140
143
  end
141
144
  def signature
@@ -143,7 +146,7 @@ module Rant
143
146
  sigs = @rac.var._get("__signature__")
144
147
  md = @rac.var._get("__metadata__")
145
148
  key = "target_sig_#{sigs.name}"
146
- md.fetch(key, @name)
149
+ md.path_fetch(key, @name)
147
150
  end
148
151
  private
149
152
  # returns true if update required
@@ -181,7 +184,7 @@ module Rant
181
184
  up
182
185
  end
183
186
  def handle_node(node, dep_str, opt)
184
- up = node.invoke(opt)
187
+ up = node.invoke(opt) if node.file_target?
185
188
  if node.respond_to? :signature
186
189
  @cur_checksums << node.signature
187
190
  elsif test(?f, dep_str)
@@ -189,6 +192,8 @@ module Rant
189
192
  handle_file(dep_str)
190
193
  elsif File.exist?(dep_str)
191
194
  @cur_checksums << @sigs.signature_for_string(dep_str)
195
+ elsif !node.file_target?
196
+ self.fail "can't handle prerequisite `#{dep_str}'"
192
197
  end
193
198
  goto_task_home
194
199
  up
@@ -218,10 +223,11 @@ module Rant
218
223
  sigs = @rac.var._get("__signature__")
219
224
  md = @rac.var._get("__metadata__")
220
225
  key = "prerequisites_sig_#{sigs.name}"
221
- md.fetch(key, @name)
226
+ md.path_fetch(key, @name)
222
227
  end
223
228
  private
224
229
  def run
230
+ @rac.running_task(self)
225
231
  @rac.cx.sys.mkdir @name unless test ?d, @name
226
232
  if @block
227
233
  @block.arity == 0 ? @block.call : @block[self]
@@ -0,0 +1,22 @@
1
+
2
+ # more.rb - Experimental sys methods.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant
7
+ module Sys
8
+ def write_to_file(fn, content)
9
+ fu_output_message "writing #{content.size} bytes to file `#{fn}'"
10
+ open fn, "w" do |f|
11
+ f.write content
12
+ end
13
+ end
14
+ def clean(entry)
15
+ if test ?f, entry
16
+ rm_f entry
17
+ elsif test ?e, entry
18
+ rm_rf entry
19
+ end
20
+ end
21
+ end # module Sys
22
+ end # module Rant