rant 0.4.0 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/NEWS +16 -0
  2. data/README +3 -2
  3. data/Rantfile +3 -4
  4. data/doc/advanced.rdoc +18 -13
  5. data/doc/examples/c_cpp_examples/Rantfile +37 -0
  6. data/doc/examples/c_cpp_examples/c/problem_1_1/another_test.c +6 -0
  7. data/doc/examples/c_cpp_examples/c/problem_1_1/another_test.h +7 -0
  8. data/doc/examples/c_cpp_examples/c/problem_1_1/main.c +12 -0
  9. data/doc/examples/c_cpp_examples/c/problem_1_1/test.c +6 -0
  10. data/doc/examples/c_cpp_examples/c/problem_1_1/test.h +7 -0
  11. data/doc/examples/c_cpp_examples/c/template.rf +21 -0
  12. data/doc/examples/c_cpp_examples/c++/problem_1_1/another_test.cpp +6 -0
  13. data/doc/examples/c_cpp_examples/c++/problem_1_1/another_test.h +5 -0
  14. data/doc/examples/c_cpp_examples/c++/problem_1_1/main.cpp +12 -0
  15. data/doc/examples/c_cpp_examples/c++/problem_1_1/test.cpp +6 -0
  16. data/doc/examples/c_cpp_examples/c++/problem_1_1/test.h +5 -0
  17. data/doc/examples/c_cpp_examples/c++/template.rf +21 -0
  18. data/doc/examples/c_cpp_examples/rule.rf +7 -0
  19. data/doc/rantfile.rdoc +1 -0
  20. data/lib/rant/archive/rubyzip/tempfile_bugfixed.rb +10 -8
  21. data/lib/rant/archive/rubyzip.rb +3 -8
  22. data/lib/rant/import/archive.rb +8 -4
  23. data/lib/rant/import/rubydoc.rb +1 -1
  24. data/lib/rant/import/rubytest.rb +12 -17
  25. data/lib/rant/import.rb +3 -2
  26. data/lib/rant/rantenv.rb +7 -4
  27. data/lib/rant/rantfile.rb +41 -21
  28. data/lib/rant/rantlib.rb +166 -113
  29. data/lib/rant/rantsys.rb +32 -17
  30. data/lib/rant/rantvar.rb +15 -15
  31. data/lib/rant/tempfile.rb +12 -0
  32. data/test/Rantfile +33 -0
  33. data/test/import/directedrule/test_directedrule.rb +29 -0
  34. data/test/import/package/Rantfile +2 -0
  35. data/test/import/package/test_package.rb +10 -0
  36. data/test/import/subfile/test_subfile.rb +21 -0
  37. data/test/project1/test_project.rb +10 -30
  38. data/test/project2/test_project.rb +1 -1
  39. data/test/project_rb1/test_project_rb1.rb +2 -1
  40. data/test/rant-import/test_rant-import.rb +35 -1
  41. data/test/subdirs/test_subdirs.rb +1 -2
  42. data/test/test_dirtask.rb +42 -0
  43. data/test/test_examples.rb +67 -0
  44. data/test/test_filelist.rb +52 -0
  45. data/test/test_rantfile_api.rb +59 -0
  46. data/test/ts_all.rb +1 -0
  47. metadata +25 -3
data/NEWS CHANGED
@@ -1,6 +1,22 @@
1
1
 
2
2
  = Rant NEWS
3
3
 
4
+ == Rant 0.4.2
5
+
6
+ This is mainly a bugfix release and thus fully backwards compatible to
7
+ 0.4.0.
8
+
9
+ Fixes and minor improvements:
10
+ * Fixes for Ruby 1.8.1 compatibility.
11
+ * Fixes for Rules and multiple buildfiles per project.
12
+ * rant-import created scripts append inlined files to
13
+ $LOADED_FEATURES.
14
+
15
+ New features:
16
+ * The +make+ command.
17
+ * New method +sub_ext+ for filelists.
18
+ Read doc/advanced.rdoc[link:files/doc/advanced_rdoc.html].
19
+
4
20
  == Rant 0.4.0
5
21
 
6
22
  Unless you extended Rant with a custom generator, you can upgrade from
data/README CHANGED
@@ -39,7 +39,7 @@ Running rant in the directory of this file:
39
39
  will ensure that the "data" file in the "backup" directory is up to
40
40
  date.
41
41
 
42
- This document was written for version 0.4.0 of Rant. Most things
42
+ This document was written for version 0.4.2 of Rant. Most things
43
43
  described here will work for older/newer versions of Rant, but look at
44
44
  the README file in the Rant distribution you've installed for exact
45
45
  documentation of your Rant version.
@@ -204,7 +204,8 @@ Rant was tested on:
204
204
 
205
205
  System Ruby version
206
206
  =======================================================
207
- Linux 1.8.2
207
+ Linux 1.8.1
208
+ 1.8.2
208
209
  1.8.3 preview 1
209
210
  1.9
210
211
  MacOS X 1.8.2
data/Rantfile CHANGED
@@ -124,11 +124,10 @@ task "to-win" => :package do
124
124
  win_dir = "/mnt/data_fat/stefan/Ruby"
125
125
  Dir["pkg/*"].each { |f|
126
126
  target = File.join(win_dir, File.basename(f))
127
- file target => f do |t|
128
- sys.rm_rf target if test(?e, target)
129
- sys.cp_r f, t.name
127
+ make target => f do |t|
128
+ sys.rm_rf target if test(?e, target)
129
+ sys.cp_r f, t.name
130
130
  end
131
- rac.make target
132
131
  }
133
132
  end
134
133
 
data/doc/advanced.rdoc CHANGED
@@ -77,6 +77,10 @@ is a brief overview:
77
77
  # create a manifest file
78
78
  open("MANIFEST", "w") { |f| f.puts fl }
79
79
 
80
+ sources = sys["*.c"]
81
+ # substitute all filename extensions with .o
82
+ objs = sources.sub_ext "o"
83
+
80
84
  Additionally, you can use all methods available for an array. Lookup
81
85
  docs with ri for array methods:
82
86
  % ri Array
@@ -231,7 +235,7 @@ define the project version, e.g.:
231
235
  #define VERSION 2.3
232
236
  Many of your tools use this version number, so you have decided to
233
237
  duplicate it in a file called +version+, which contains just a line
234
- with the program version. On solution to automate the +version+ file
238
+ with the program version. One solution to automate the +version+ file
235
239
  creation would be to write a file task:
236
240
  file "version" => "config.h" do |t|
237
241
  puts "updating version file"
@@ -240,12 +244,15 @@ creation would be to write a file task:
240
244
  and make all other tasks that need this version dependent on it. But
241
245
  this can get very tedious if you have many tasks that need this
242
246
  version file. Another solution is to just run the task every time the
243
- Rantfile is sourced. This can be achieved by placing the following
244
- statement after the "version" task:
245
- rac.build "version"
246
- This tells rant to immediately invoke all tasks that are required to
247
- build the version file. But imagine your users just want to see the
248
- list of available tasks:
247
+ Rantfile is sourced. This can be achieved by replacing the +file+
248
+ command with the +make+ command:
249
+ make "version" => "config.h" do |t|
250
+ puts "updating version file"
251
+ open("w", t.name) { |f| f.puts(extract_config_version()) }
252
+ end
253
+ This creates a file task like before and tells rant to immediately
254
+ invoke all tasks that are required to build the version file. But
255
+ imagine your users just want to see the list of available tasks:
249
256
  % rant --tasks
250
257
  updating version file
251
258
  rant foo # build foo program
@@ -253,13 +260,11 @@ list of available tasks:
253
260
  rant clean # remove generated files
254
261
  Hmm, we really didn't need the version to show our users the available
255
262
  tasks. To avoid this, wrap such code in an Action:
256
- file "version" => "config.h" do |t|
257
- puts "updating version file"
258
- open("w", t.name) { |f| f.puts(extract_config_version()) }
259
- end
260
-
261
263
  gen Action do
262
- rac.build "version"
264
+ make "version" => "config.h" do |t|
265
+ puts "updating version file"
266
+ open("w", t.name) { |f| f.puts(extract_config_version()) }
267
+ end
263
268
  end
264
269
  And now on a clean source base:
265
270
  % rant --tasks
@@ -0,0 +1,37 @@
1
+
2
+ import "autoclean", "package/tgz"
3
+
4
+ cpp_dirs = sys["c++/problem_*"]
5
+ c_dirs = sys["c/problem_*"]
6
+ all_dirs = cpp_dirs + c_dirs
7
+
8
+ cpp_rf_template = "c++/template.rf"
9
+ c_rf_template = "c/template.rf"
10
+
11
+ desc "Run all C and C++ tests."
12
+ task :run => all_dirs.map{ |f| "#{f}/run" }
13
+ desc "Build all."
14
+ task :build => all_dirs.map{ |f| "#{f}/test" }
15
+
16
+ desc "Remove all autogenerated files."
17
+ gen AutoClean
18
+
19
+ source "rule.rf"
20
+
21
+ desc "Create source package."
22
+ gen Package::Tgz, "pkg/c_cpp_exercises",
23
+ :files => sys["Rantfile", "**/*.{c,cpp,h,rf}"]
24
+
25
+ gen Action do
26
+ cpp_dirs.each { |dir|
27
+ make "#{dir}/Rantfile" => cpp_rf_template do |t|
28
+ sys.cp t.source, t.name
29
+ end
30
+ }
31
+ c_dirs.each { |dir|
32
+ make "#{dir}/Rantfile" => c_rf_template do |t|
33
+ sys.cp t.source, t.name
34
+ end
35
+ }
36
+ subdirs cpp_dirs, c_dirs
37
+ end
@@ -0,0 +1,6 @@
1
+
2
+ #include "another_test.h"
3
+
4
+ void another_test()
5
+ {
6
+ }
@@ -0,0 +1,7 @@
1
+
2
+ #ifndef ANOTHER_TEST_H
3
+ #define ANOTHER_TEST_H
4
+
5
+ void another_test(void);
6
+
7
+ #endif
@@ -0,0 +1,12 @@
1
+
2
+ #include <stdio.h>
3
+ #include "test.h"
4
+ #include "another_test.h"
5
+
6
+ int main(char argc, char** argv)
7
+ {
8
+ test();
9
+ another_test();
10
+ printf("Hello, world!\n");
11
+ return 0;
12
+ }
@@ -0,0 +1,6 @@
1
+
2
+ #include "test.h"
3
+
4
+ void test()
5
+ {
6
+ }
@@ -0,0 +1,7 @@
1
+
2
+ #ifndef TEST_H
3
+ #define TEST_H
4
+
5
+ void test(void);
6
+
7
+ #endif
@@ -0,0 +1,21 @@
1
+ # Autogenerated. Do not modify!
2
+ # Create additional tasks and make other modifications in custom.rf.
3
+
4
+ import "c/dependencies", "autoclean"
5
+
6
+ task :run => "test" do
7
+ sys "./test"
8
+ end
9
+
10
+ gen C::Dependencies
11
+ gen Action do source "c_dependencies" end
12
+
13
+ file "test" => sys["*.c"].sub_ext("o") do |t|
14
+ sys "gcc -o #{t.name} #{t.prerequisites}"
15
+ end
16
+
17
+ gen AutoClean
18
+
19
+ source "../../rule.rf"
20
+
21
+ source "custom.rf" if File.exist? "custom.rf"
@@ -0,0 +1,6 @@
1
+
2
+ #include "another_test.h"
3
+
4
+ void another_test()
5
+ {
6
+ }
@@ -0,0 +1,5 @@
1
+
2
+ #ifndef ANOTHER_TEST_H
3
+ #define ANOTHER_TEST_H
4
+
5
+ #endif
@@ -0,0 +1,12 @@
1
+
2
+ #include <iostream>
3
+ #include "test.h"
4
+ #include "another_test.h"
5
+
6
+ using namespace std;
7
+
8
+ int main(char argc, char** argv)
9
+ {
10
+ cout << "Hello, world!" << endl;
11
+ return 0;
12
+ }
@@ -0,0 +1,6 @@
1
+
2
+ #include "test.h"
3
+
4
+ void test()
5
+ {
6
+ }
@@ -0,0 +1,5 @@
1
+
2
+ #ifndef TEST_H
3
+ #define TEST_H
4
+
5
+ #endif
@@ -0,0 +1,21 @@
1
+ # Autogenerated. Do not modify!
2
+ # Create additional tasks and make other modifications in custom.rf.
3
+
4
+ import "c/dependencies", "autoclean"
5
+
6
+ task :run => "test" do
7
+ sys "./test"
8
+ end
9
+
10
+ gen C::Dependencies
11
+ gen Action do source "c_dependencies" end
12
+
13
+ file "test" => sys["*.cpp"].sub_ext("o") do |t|
14
+ sys "g++ -o #{t.name} #{t.prerequisites}"
15
+ end
16
+
17
+ gen AutoClean
18
+
19
+ source "../../rule.rf"
20
+
21
+ source "custom.rf" if File.exist? "custom.rf"
@@ -0,0 +1,7 @@
1
+ gen Rule, '.o' => '.cpp' do |t|
2
+ sys "g++ -c -o #{t.name} #{t.source}"
3
+ end
4
+
5
+ gen Rule, '.o' => '.c' do |t|
6
+ sys "gcc -c -o #{t.name} #{t.source}"
7
+ end
data/doc/rantfile.rdoc CHANGED
@@ -36,6 +36,7 @@ methods with the Rant application:
36
36
  +var+:: Provides access to variables accessible in Rantfiles
37
37
  and from the commandline.
38
38
  +rac+:: The "Rant compiler" which is compiling the Rantfiles.
39
+ +make+:: Immediately build a target.
39
40
 
40
41
  === Defining a task
41
42
 
@@ -7,6 +7,7 @@
7
7
  require 'delegate'
8
8
  require 'tmpdir'
9
9
 
10
+ module Rant
10
11
  module BugFix #:nodoc:all
11
12
 
12
13
  # A class for managing temporary files. This library is written to be
@@ -184,12 +185,13 @@ class Tempfile < DelegateClass(File)
184
185
  end
185
186
 
186
187
  end # module BugFix
187
- if __FILE__ == $0
188
+ end # module Rant
189
+ #if __FILE__ == $0
188
190
  # $DEBUG = true
189
- f = Tempfile.new("foo")
190
- f.print("foo\n")
191
- f.close
192
- f.open
193
- p f.gets # => "foo\n"
194
- f.close!
195
- end
191
+ # f = Tempfile.new("foo")
192
+ # f.print("foo\n")
193
+ # f.close
194
+ # f.open
195
+ # p f.gets # => "foo\n"
196
+ # f.close!
197
+ #end
@@ -29,16 +29,11 @@
29
29
 
30
30
  require 'delegate'
31
31
  require 'singleton'
32
- require 'tempfile'
33
32
  require 'ftools'
34
33
  require 'zlib'
35
34
  require 'rant/archive/rubyzip/stdrubyext'
36
35
  require 'rant/archive/rubyzip/ioextras'
37
-
38
- if Tempfile.superclass == SimpleDelegator
39
- require 'rant/archive/rubyzip/tempfile_bugfixed'
40
- Tempfile = BugFix::Tempfile
41
- end
36
+ require 'rant/tempfile'
42
37
 
43
38
  module Zlib #:nodoc:all
44
39
  if ! const_defined? :MAX_WBITS
@@ -1270,7 +1265,7 @@ module Rant::Archive::Rubyzip
1270
1265
  end
1271
1266
 
1272
1267
  def get_tempfile
1273
- tempFile = Tempfile.new(File.basename(name), File.dirname(name))
1268
+ tempFile = Rant::Tempfile.new(File.basename(name), File.dirname(name))
1274
1269
  tempFile.binmode
1275
1270
  tempFile
1276
1271
  end
@@ -1320,7 +1315,7 @@ module Rant::Archive::Rubyzip
1320
1315
  class ZipStreamableStream < DelegateClass(ZipEntry) #nodoc:all
1321
1316
  def initialize(entry)
1322
1317
  super(entry)
1323
- @tempFile = Tempfile.new(File.basename(name), File.dirname(zipfile))
1318
+ @tempFile = Rant::Tempfile.new(File.basename(name), File.dirname(zipfile))
1324
1319
  @tempFile.binmode
1325
1320
  end
1326
1321
 
@@ -9,6 +9,7 @@
9
9
 
10
10
  require 'rant/rantlib'
11
11
  require 'rant/import/subfile'
12
+ #require 'rant/tempfile' #rant-import:uncomment
12
13
 
13
14
  module Rant::Generators::Archive
14
15
  # A subclass has to provide a +define_task+ method to act as a
@@ -131,6 +132,7 @@ module Rant::Generators::Archive
131
132
  get_archive_path
132
133
  end
133
134
  end
135
+ alias to_rant_target path
134
136
 
135
137
  # Path to archive without basedir.
136
138
  def get_archive_path
@@ -156,7 +158,9 @@ module Rant::Generators::Archive
156
158
  else
157
159
  fl = Rant::RacFileList.filelist(@rac, fl)
158
160
  end
159
- @res_files = fl.lazy_uniq!.lazy_sort!
161
+ # remove leading `./' relicts
162
+ @res_files = fl.lazy_map! { |fn| fn.sub(/^\.\/(?=.)/,'') }
163
+ @res_files.lazy_uniq!.lazy_sort!
160
164
  end
161
165
 
162
166
  # Creates an (eventually) temporary manifest file and yields
@@ -164,11 +168,11 @@ module Rant::Generators::Archive
164
168
  def with_manifest
165
169
  fl = get_files
166
170
  if @manifest
167
- rac.make @manifest
171
+ rac.build @manifest
168
172
  yield @manifest
169
173
  else
170
- require 'tempfile'
171
- tf = Tempfile.new "rant"
174
+ require 'rant/tempfile' #rant-import:remove
175
+ tf = Rant::Tempfile.new "rant"
172
176
  begin
173
177
  fl.each { |path| tf.puts path }
174
178
  tf.close
@@ -10,7 +10,7 @@ module Rant
10
10
  if !args || args.empty?
11
11
  self.new(app, ch, &block)
12
12
  elsif args.size == 1
13
- name, pre, file, ln = app.normalize_task_arg(args.first, ch)
13
+ name, pre = app.normalize_task_arg(args.first, ch)
14
14
  self.new(app, ch, name, pre, &block)
15
15
  else
16
16
  app.abort(app.pos_text(file, ln),
@@ -3,23 +3,18 @@ require 'rant/rantlib'
3
3
 
4
4
  module Rant
5
5
  class Generators::RubyTest
6
-
7
- class << self
8
-
9
- def rant_gen(app, ch, args, &block)
10
- if !args || args.empty?
11
- self.new(app, ch, &block)
12
- elsif args.size == 1
13
- name, pre, file, ln =
14
- app.normalize_task_arg(args.first, ch)
15
- self.new(app, ch, name, pre, &block)
16
- else
17
- app.abort(app.pos_text(file, ln),
18
- "RubyTest takes only one additional argument, " +
19
- "which should be like one given to the `task' command.")
20
- end
21
- end
22
- end
6
+ def self.rant_gen(app, ch, args, &block)
7
+ if !args || args.empty?
8
+ self.new(app, ch, &block)
9
+ elsif args.size == 1
10
+ name, pre = app.normalize_task_arg(args.first, ch)
11
+ self.new(app, ch, name, pre, &block)
12
+ else
13
+ app.abort_at(ch,
14
+ "RubyTest takes only one additional argument, " +
15
+ "which should be like one given to the `task' command.")
16
+ end
17
+ end
23
18
 
24
19
  attr_accessor :verbose
25
20
  attr_accessor :libs
data/lib/rant/import.rb CHANGED
@@ -125,6 +125,7 @@ EOH
125
125
  mf << mono_plugins
126
126
  mf << <<EOF
127
127
 
128
+ $".concat([#{@included_files.map{ |f| "'" + f + ".rb'" }.join(", ")}])
128
129
  Rant::CODE_IMPORTS.concat %w(#{@included_imports.join(' ')}
129
130
  #{(@included_plugins.map do |i| "plugin/" + i end).join(' ')})
130
131
 
@@ -142,7 +143,7 @@ def require libf
142
143
  end
143
144
  end
144
145
 
145
- Rant.run
146
+ exit Rant.run
146
147
  EOF
147
148
  }
148
149
  msg "Done.",
@@ -213,7 +214,7 @@ EOF
213
214
  done
214
215
  end
215
216
 
216
- def msg *args
217
+ def msg(*args)
217
218
  super unless @quiet
218
219
  end
219
220
 
data/lib/rant/rantenv.rb CHANGED
@@ -1,4 +1,7 @@
1
- #!/usr/bin/ruby
1
+
2
+ # rantenv.rb - Environment interface.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
2
5
 
3
6
  require 'rbconfig'
4
7
 
@@ -106,17 +109,17 @@ module Rant::Console
106
109
  RANT_PREFIX
107
110
  end
108
111
  end
109
- def msg *text
112
+ def msg(*text)
110
113
  pre = msg_prefix
111
114
  text = text.join("\n" + ' ' * pre.length)
112
115
  $stderr.puts(pre + text)
113
116
  end
114
- def err_msg *text
117
+ def err_msg(*text)
115
118
  pre = msg_prefix + ERROR_PREFIX
116
119
  text = text.join("\n" + ' ' * pre.length)
117
120
  $stderr.puts(pre + text)
118
121
  end
119
- def warn_msg *text
122
+ def warn_msg(*text)
120
123
  pre = msg_prefix + WARN_PREFIX
121
124
  text = text.join("\n" + ' ' * pre.length)
122
125
  $stderr.puts(pre + text)
data/lib/rant/rantfile.rb CHANGED
@@ -59,24 +59,26 @@ module Rant
59
59
  attr_accessor :rantfile
60
60
  # The linenumber in rantfile where this task was defined.
61
61
  attr_accessor :line_number
62
+ # The directory in which this task was defined, relative to
63
+ # the projects root directory.
64
+ attr_accessor :project_subdir
62
65
 
63
66
  def initialize
64
67
  @description = nil
65
68
  @rantfile = nil
66
69
  @line_number = nil
67
70
  @run = false
71
+ @project_subdir = ""
68
72
  end
69
73
 
70
- # Returns the full name of this task.
74
+ # Returns the name of this task.
71
75
  def to_s
72
- full_name
76
+ name
73
77
  end
74
78
 
75
- # The directory in which this task was defined, relative to
76
- # the projects root directory.
77
- def project_subdir
78
- @rantfile.nil? ? "" : @rantfile.project_subdir
79
- end
79
+ def to_rant_target
80
+ name
81
+ end
80
82
 
81
83
  # Basically project_subdir/name
82
84
  #
@@ -132,6 +134,7 @@ module Rant
132
134
  # Cause task to fail. Usually called from inside the block
133
135
  # given to +act+.
134
136
  def fail msg = nil, orig = nil
137
+ msg ||= ""
135
138
  raise TaskFail.new(self, orig), msg, caller
136
139
  end
137
140
 
@@ -197,11 +200,11 @@ module Rant
197
200
  @rac
198
201
  end
199
202
 
200
- def needed &block
203
+ def needed(&block)
201
204
  @needed = block
202
205
  end
203
206
 
204
- def act &block
207
+ def act(&block)
205
208
  @block = block
206
209
  end
207
210
 
@@ -481,11 +484,11 @@ module Rant
481
484
  yield self if block_given?
482
485
  end
483
486
 
484
- def act &block
487
+ def act(&block)
485
488
  @block = block
486
489
  end
487
490
 
488
- def needed &block
491
+ def needed(&block)
489
492
  @needed = block
490
493
  end
491
494
 
@@ -515,7 +518,7 @@ module Rant
515
518
 
516
519
  class FileTask < Task
517
520
 
518
- def initialize *args
521
+ def initialize(*args)
519
522
  super
520
523
  @ts = T0
521
524
  end
@@ -554,6 +557,7 @@ module Rant
554
557
  end
555
558
 
556
559
  def handle_non_node(dep, opt)
560
+ goto_task_home # !!??
557
561
  unless File.exist? dep
558
562
  err_msg @rac.pos_text(rantfile.path, line_number),
559
563
  "in prerequisites: no such file or task: `#{dep}'"
@@ -597,7 +601,7 @@ module Rant
597
601
  def rant_gen(rac, ch, args, &block)
598
602
  case args.size
599
603
  when 1
600
- name, pre, file, ln = rac.normalize_task_arg(args.first, ch)
604
+ name, pre = rac.normalize_task_arg(args.first, ch)
601
605
  self.task(rac, ch, name, pre, &block)
602
606
  when 2
603
607
  basedir = args.shift
@@ -607,11 +611,10 @@ module Rant
607
611
  rac.abort_at(ch,
608
612
  "Directory: basedir argument has to be a string.")
609
613
  end
610
- name, pre, file, ln = rac.normalize_task_arg(args.first, ch)
614
+ name, pre = rac.normalize_task_arg(args.first, ch)
611
615
  self.task(rac, ch, name, pre, basedir, &block)
612
616
  else
613
- rac.abort(rac.pos_text(ch[:file], ch[:ln]),
614
- "Directory takes one argument, " +
617
+ rac.abort_at(ch, "Directory takes one argument, " +
615
618
  "which should be like one given to the `task' command.")
616
619
  end
617
620
  end
@@ -647,7 +650,7 @@ module Rant
647
650
  end
648
651
  end
649
652
 
650
- def initialize *args
653
+ def initialize(*args)
651
654
  super
652
655
  @ts = T0
653
656
  @isdir = nil
@@ -678,6 +681,7 @@ module Rant
678
681
  end
679
682
 
680
683
  def handle_non_node(dep, opt)
684
+ goto_task_home
681
685
  unless File.exist? dep
682
686
  err_msg @rac.pos_text(rantfile.path, line_number),
683
687
  "in prerequisites: no such file or task: `#{dep}'"
@@ -849,10 +853,26 @@ module Rant
849
853
  end
850
854
  blk = self.new { |task_name|
851
855
  if target_rx =~ task_name
852
- [rac.file(:__caller__ => ch,
853
- task_name => src_proc[task_name], &block)]
854
- else
855
- nil
856
+ have_src = true
857
+ src = src_proc[task_name]
858
+ if src.respond_to? :to_ary
859
+ src.each { |f|
860
+ if rac.resolve(f).empty? && !test(?e, f)
861
+ have_src = false
862
+ break
863
+ end
864
+ }
865
+ else
866
+ if rac.resolve(src).empty? && !test(?e, src)
867
+ have_src = false
868
+ end
869
+ end
870
+ if have_src
871
+ t = rac.file(:__caller__ => ch,
872
+ task_name => src_proc[task_name], &block)
873
+ t.project_subdir = rac.current_subdir
874
+ [t]
875
+ end
856
876
  end
857
877
  }
858
878
  blk.target_rx = target_rx