rant 0.4.4 → 0.4.6

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.
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