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.
- data/NEWS +38 -0
- data/README +4 -2
- data/Rantfile +50 -12
- data/doc/examples/c_cpp/c++/problem_1_1/another_test.cpp +6 -0
- data/doc/examples/c_cpp/c++/problem_1_1/another_test.h +5 -0
- data/doc/examples/c_cpp/c++/problem_1_1/main.cpp +12 -0
- data/doc/examples/c_cpp/c++/problem_1_1/test.cpp +6 -0
- data/doc/examples/c_cpp/c++/problem_1_1/test.h +5 -0
- data/doc/examples/c_cpp/c++/template.rf +15 -0
- data/doc/examples/c_cpp/c/problem_1_1/another_test.c +6 -0
- data/doc/examples/c_cpp/c/problem_1_1/another_test.h +7 -0
- data/doc/examples/c_cpp/c/problem_1_1/main.c +12 -0
- data/doc/examples/c_cpp/c/problem_1_1/test.c +6 -0
- data/doc/examples/c_cpp/c/problem_1_1/test.h +7 -0
- data/doc/examples/c_cpp/c/template.rf +15 -0
- data/doc/examples/c_cpp/root.rant +46 -0
- data/doc/homepage/index.html +115 -0
- data/doc/homepage/rant_home.css +98 -0
- data/doc/rant.1 +129 -0
- data/doc/rant.rdoc +5 -6
- data/doc/rantfile.rdoc +55 -32
- data/doc/subdirs.rdoc +147 -0
- data/lib/rant.rb +47 -49
- data/lib/rant/coregen.rb +20 -20
- data/lib/rant/import.rb +63 -11
- data/lib/rant/import/archive.rb +47 -15
- data/lib/rant/import/archive/tgz.rb +1 -1
- data/lib/rant/import/autoclean.rb +28 -26
- data/lib/rant/import/c/dependencies.rb +1 -1
- data/lib/rant/import/directedrule.rb +1 -4
- data/lib/rant/import/metadata.rb +30 -7
- data/lib/rant/import/nodes/default.rb +67 -13
- data/lib/rant/import/rubypackage.rb +1 -1
- data/lib/rant/import/rubytest.rb +25 -19
- data/lib/rant/import/signedfile.rb +14 -8
- data/lib/rant/import/sys/more.rb +22 -0
- data/lib/rant/import/sys/tgz.rb +43 -0
- data/lib/rant/import/sys/zip.rb +42 -0
- data/lib/rant/node.rb +19 -13
- data/lib/rant/plugin/configure.rb +1 -1
- data/lib/rant/progress.rb +33 -0
- data/lib/rant/rantenv.rb +7 -7
- data/lib/rant/rantlib.rb +246 -256
- data/lib/rant/rantsys.rb +61 -22
- data/lib/rant/rantvar.rb +7 -9
- data/misc/TODO +18 -0
- data/misc/devel-notes +4 -1
- data/test/Rantfile +17 -3
- data/test/deprecated/README +6 -0
- data/test/deprecated/test_0_4_8.rb +41 -0
- data/test/deprecated/test_0_5_2.rb +33 -0
- data/test/import/md5/root.rant +9 -0
- data/test/import/md5/test_md5.rb +45 -0
- data/test/import/metadata/Rantfile +2 -2
- data/test/import/metadata/test_metadata.rb +2 -2
- data/test/import/package/test_package.rb +40 -1
- data/test/import/signedfile/sub1/Rantfile +1 -1
- data/test/import/sys/data/pkg.tgz +0 -0
- data/test/import/sys/data/pkg.zip +0 -0
- data/test/import/sys/data/pkg/bin/test +0 -0
- data/test/import/sys/data/pkg/bin/test.o +0 -0
- data/test/import/sys/data/pkg/test.c +6 -0
- data/test/import/sys/data/pkg/test.h +7 -0
- data/test/import/sys/data/pkg2.zip +0 -0
- data/test/import/sys/test_tgz.rb +38 -0
- data/test/import/sys/test_zip.rb +68 -0
- data/test/import/sys/tgz.rf +6 -0
- data/test/import/sys/zip.rf +15 -0
- data/test/project2/{rantfile.rb → root.rant} +0 -0
- data/test/project2/test_project.rb +3 -8
- data/test/project_rb1/{rantfile.rb → rantfile} +1 -1
- data/test/project_rb1/test_project_rb1.rb +3 -5
- data/test/rant-import/test_rant-import.rb +22 -10
- data/test/subdirs/sub1/Rantfile +1 -1
- data/test/subdirs/sub2/{rantfile.rb → rantfile} +0 -0
- data/test/subdirs/sub2/sub/rantfile +1 -1
- data/test/subdirs2/root.rant +36 -0
- data/test/subdirs2/sub00/sub.rant +8 -0
- data/test/subdirs2/sub1/sub.rant +13 -0
- data/test/subdirs2/test_subdirs2.rb +239 -0
- data/test/test_examples.rb +91 -0
- data/test/test_filetask.rb +51 -11
- data/test/test_rant_interface.rb +24 -0
- data/test/test_rantfile_api.rb +54 -2
- data/test/test_sourcenode.rb +30 -0
- data/test/test_sys.rb +143 -15
- data/test/test_task.rb +16 -22
- data/test/tutil.rb +22 -38
- metadata +67 -9
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
# tgz.rb - +sys+ methods for tgz archiving.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
|
5
|
+
|
|
6
|
+
#require 'rant/archive/minitar' #rant-import:uncomment
|
|
7
|
+
|
|
8
|
+
module Rant
|
|
9
|
+
module Sys
|
|
10
|
+
# Unpack the gzipped tar archive, to which the +archive+ path
|
|
11
|
+
# points. Use the <tt>:in => "some/dir"</tt> option to specify
|
|
12
|
+
# a output directory. It defaults to the working directory.
|
|
13
|
+
def unpack_tgz(archive, opts={})
|
|
14
|
+
output_dir = opts[:to] || opts[:in] || "."
|
|
15
|
+
mkpath output_dir unless test ?d, output_dir
|
|
16
|
+
if Env.have_tar?
|
|
17
|
+
sh "tar", "-xzf", archive, "-C", output_dir
|
|
18
|
+
else
|
|
19
|
+
minitar_unpack(archive, output_dir)
|
|
20
|
+
end
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
private
|
|
24
|
+
def minitar_tgz(fn, files, opts)
|
|
25
|
+
require 'zlib'
|
|
26
|
+
require 'rant/archive/minitar' #rant-import:remove
|
|
27
|
+
fu_output_message "minitar #{fn}"
|
|
28
|
+
files = files.to_ary if files.respond_to? :to_ary
|
|
29
|
+
tgz = Zlib::GzipWriter.new(File.open(fn, 'wb'))
|
|
30
|
+
# pack closes tgz
|
|
31
|
+
Rant::Archive::Minitar.pack(files, tgz, opts[:recurse])
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
def minitar_unpack(archive, output_dir)
|
|
35
|
+
fu_output_message "unpacking #{archive} in #{output_dir}"
|
|
36
|
+
require 'zlib'
|
|
37
|
+
require 'rant/archive/minitar' #rant-import:remove
|
|
38
|
+
tgz = Zlib::GzipReader.new(File.open(archive, 'rb'))
|
|
39
|
+
# unpack closes tgz
|
|
40
|
+
Archive::Minitar.unpack(tgz, output_dir)
|
|
41
|
+
end
|
|
42
|
+
end # module Sys
|
|
43
|
+
end # module Rant
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
# zip.rb - +sys+ methods for zip archiving.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
|
5
|
+
|
|
6
|
+
#require 'rant/archive/rubyzip' #rant-import:uncomment
|
|
7
|
+
|
|
8
|
+
module Rant
|
|
9
|
+
module Sys
|
|
10
|
+
# Unpack the zip archive, to which the +archive+ path points.
|
|
11
|
+
# Use the <tt>:in => "some/dir"</tt> option to specify a
|
|
12
|
+
# output directory. It defaults to the working directory.
|
|
13
|
+
def unpack_zip(archive, opts={})
|
|
14
|
+
output_dir = opts[:to] || opts[:in] || "."
|
|
15
|
+
mkpath output_dir unless test ?d, output_dir
|
|
16
|
+
if Env.find_bin("unzip")
|
|
17
|
+
sh "unzip", "-q", archive, "-d", output_dir
|
|
18
|
+
else
|
|
19
|
+
rubyzip_unpack(archive, output_dir)
|
|
20
|
+
end
|
|
21
|
+
nil
|
|
22
|
+
end
|
|
23
|
+
private
|
|
24
|
+
def rubyzip_unpack(archive, output_dir)
|
|
25
|
+
fu_output_message "unpacking #{archive} in #{output_dir}"
|
|
26
|
+
require 'rant/archive/rubyzip' #rant-import:remove
|
|
27
|
+
f = Archive::Rubyzip::ZipFile.open archive
|
|
28
|
+
f.entries.each { |e|
|
|
29
|
+
fn = e.name
|
|
30
|
+
dir = File.dirname fn
|
|
31
|
+
if dir == "."
|
|
32
|
+
dir = output_dir
|
|
33
|
+
elsif output_dir != "."
|
|
34
|
+
dir = File.join(output_dir, dir)
|
|
35
|
+
end
|
|
36
|
+
FileUtils.mkpath dir unless test ?d, dir
|
|
37
|
+
f.extract(e, File.join(output_dir, fn))
|
|
38
|
+
}
|
|
39
|
+
f.close
|
|
40
|
+
end
|
|
41
|
+
end # module Sys
|
|
42
|
+
end # module Rant
|
data/lib/rant/node.rb
CHANGED
|
@@ -37,9 +37,8 @@ module Rant
|
|
|
37
37
|
@tasks = []
|
|
38
38
|
@project_subdir = nil
|
|
39
39
|
end
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
40
|
+
alias to_s path
|
|
41
|
+
alias to_str path
|
|
43
42
|
end # class Rantfile
|
|
44
43
|
|
|
45
44
|
# Any +object+ is considered a _task_ if
|
|
@@ -76,15 +75,18 @@ module Rant
|
|
|
76
75
|
@project_subdir = ""
|
|
77
76
|
end
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
78
|
+
def reference_name
|
|
79
|
+
sd = rac.current_subdir
|
|
80
|
+
case sd
|
|
81
|
+
when "": full_name
|
|
82
|
+
when project_subdir: name
|
|
83
|
+
else "@#{full_name}".sub(/^@#{Regexp.escape sd}\//, '')
|
|
84
|
+
end
|
|
86
85
|
end
|
|
87
86
|
|
|
87
|
+
alias to_s reference_name
|
|
88
|
+
alias to_rant_target name
|
|
89
|
+
|
|
88
90
|
# Basically project_subdir/name
|
|
89
91
|
#
|
|
90
92
|
# The Rant compiler (or application) references tasks by their
|
|
@@ -103,6 +105,10 @@ module Rant
|
|
|
103
105
|
@rac.goto_project_dir project_subdir
|
|
104
106
|
end
|
|
105
107
|
|
|
108
|
+
def file_target?
|
|
109
|
+
false
|
|
110
|
+
end
|
|
111
|
+
|
|
106
112
|
def done?
|
|
107
113
|
@done
|
|
108
114
|
end
|
|
@@ -149,17 +155,17 @@ module Rant
|
|
|
149
155
|
def each_target
|
|
150
156
|
end
|
|
151
157
|
|
|
158
|
+
private
|
|
152
159
|
def run
|
|
153
160
|
return unless @block
|
|
154
161
|
goto_task_home
|
|
162
|
+
@rac.running_task(self)
|
|
155
163
|
@block.arity == 0 ? @block.call : @block[self]
|
|
156
164
|
end
|
|
157
|
-
private :run
|
|
158
165
|
|
|
159
166
|
def circular_dep
|
|
160
167
|
rac.warn_msg "Circular dependency on task `#{full_name}'."
|
|
161
168
|
false
|
|
162
169
|
end
|
|
163
|
-
private :circular_dep
|
|
164
170
|
end # module Node
|
|
165
|
-
end
|
|
171
|
+
end # module Rant
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
# progress.rb - Simple progress bar features for Rant.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
|
5
|
+
|
|
6
|
+
module Rant
|
|
7
|
+
class ProgressCountdown
|
|
8
|
+
attr_reader :total, :current
|
|
9
|
+
def initialize(total, rant=nil)
|
|
10
|
+
@total = total
|
|
11
|
+
@step = @total / 10
|
|
12
|
+
@fraction = 10
|
|
13
|
+
@rant = rant
|
|
14
|
+
@current = 0
|
|
15
|
+
end
|
|
16
|
+
def inc
|
|
17
|
+
@current += 1
|
|
18
|
+
if @step > 0 and @current % @step == 0
|
|
19
|
+
@fraction -= 1
|
|
20
|
+
print_progress "#@fraction " if @fraction >= 0
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
private
|
|
24
|
+
def print_progress(text)
|
|
25
|
+
if @rant
|
|
26
|
+
@rant.cmd_print(text)
|
|
27
|
+
else
|
|
28
|
+
print text
|
|
29
|
+
$stdout.flush
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end # class ProgressCountdown
|
|
33
|
+
end # module Rant
|
data/lib/rant/rantenv.rb
CHANGED
|
@@ -111,18 +111,18 @@ module Rant::Console
|
|
|
111
111
|
end
|
|
112
112
|
def msg(*text)
|
|
113
113
|
pre = msg_prefix
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
$stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}"
|
|
115
|
+
end
|
|
116
|
+
def vmsg(importance, *text)
|
|
117
|
+
msg(*text) if verbose >= importance
|
|
116
118
|
end
|
|
117
119
|
def err_msg(*text)
|
|
118
120
|
pre = msg_prefix + ERROR_PREFIX
|
|
119
|
-
|
|
120
|
-
$stderr.puts(pre + text)
|
|
121
|
+
$stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}"
|
|
121
122
|
end
|
|
122
123
|
def warn_msg(*text)
|
|
123
124
|
pre = msg_prefix + WARN_PREFIX
|
|
124
|
-
|
|
125
|
-
$stderr.puts(pre + text)
|
|
125
|
+
$stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}"
|
|
126
126
|
end
|
|
127
127
|
def ask_yes_no text
|
|
128
128
|
$stderr.print msg_prefix + text + " [y|n] "
|
|
@@ -152,7 +152,7 @@ module Rant::Console
|
|
|
152
152
|
next unless desc # "private" option
|
|
153
153
|
optstr = ""
|
|
154
154
|
arg = nil
|
|
155
|
-
if mode
|
|
155
|
+
if mode != GetoptLong::NO_ARGUMENT
|
|
156
156
|
if desc =~ /(\b[A-Z_]{2,}\b)/
|
|
157
157
|
arg = $1
|
|
158
158
|
end
|
data/lib/rant/rantlib.rb
CHANGED
|
@@ -27,7 +27,7 @@ Rant::MAIN_OBJECT = self
|
|
|
27
27
|
|
|
28
28
|
unless Process::Status.method_defined?(:success?) # new in 1.8.2
|
|
29
29
|
class Process::Status
|
|
30
|
-
def success?;
|
|
30
|
+
def success?; exitstatus == 0; end
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
unless Regexp.respond_to? :union # new in 1.8.1
|
|
@@ -155,55 +155,63 @@ module RantContext
|
|
|
155
155
|
|
|
156
156
|
# Define a basic task.
|
|
157
157
|
def task(targ, &block)
|
|
158
|
-
|
|
158
|
+
rant.task(targ, &block)
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
# Define a file task.
|
|
162
162
|
def file(targ, &block)
|
|
163
|
-
|
|
163
|
+
rant.file(targ, &block)
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
# Add code and/or prerequisites to existing task.
|
|
167
167
|
def enhance(targ, &block)
|
|
168
|
-
|
|
168
|
+
rant.enhance(targ, &block)
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
def desc(*args)
|
|
172
|
-
|
|
172
|
+
rant.desc(*args)
|
|
173
173
|
end
|
|
174
174
|
|
|
175
175
|
def gen(*args, &block)
|
|
176
|
-
|
|
176
|
+
rant.gen(*args, &block)
|
|
177
177
|
end
|
|
178
178
|
|
|
179
179
|
def import(*args, &block)
|
|
180
|
-
|
|
180
|
+
rant.import(*args, &block)
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def plugin(*args, &block)
|
|
184
|
-
|
|
184
|
+
rant.plugin(*args, &block)
|
|
185
185
|
end
|
|
186
186
|
|
|
187
187
|
# Look in the subdirectories, given by args,
|
|
188
188
|
# for rantfiles.
|
|
189
189
|
def subdirs(*args)
|
|
190
|
-
|
|
190
|
+
rant.subdirs(*args)
|
|
191
191
|
end
|
|
192
192
|
|
|
193
193
|
def source(opt, rantfile = nil)
|
|
194
|
-
|
|
194
|
+
rant.source(opt, rantfile)
|
|
195
195
|
end
|
|
196
196
|
|
|
197
197
|
def sys(*args, &block)
|
|
198
|
-
|
|
198
|
+
rant.sys(*args, &block)
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
def var(*args, &block)
|
|
202
|
-
|
|
202
|
+
rant.var(*args, &block)
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
def make(*args, &block)
|
|
206
|
-
|
|
206
|
+
rant.make(*args, &block)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# +rac+ stands for "rant compiler"
|
|
210
|
+
def rac
|
|
211
|
+
ch = Rant::Lib.parse_caller_elem caller[0]
|
|
212
|
+
rant.warn_msg(@__rant__.pos_text(ch[:file], ch[:ln]),
|
|
213
|
+
"Method `rac' is deprecated. Use `rant' instead.")
|
|
214
|
+
rant
|
|
207
215
|
end
|
|
208
216
|
end # module RantContext
|
|
209
217
|
|
|
@@ -211,12 +219,11 @@ class RantAppContext
|
|
|
211
219
|
include RantContext
|
|
212
220
|
|
|
213
221
|
def initialize(app)
|
|
214
|
-
@
|
|
222
|
+
@__rant__ = app
|
|
215
223
|
end
|
|
216
224
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
@__rac__
|
|
225
|
+
def rant
|
|
226
|
+
@__rant__
|
|
220
227
|
end
|
|
221
228
|
|
|
222
229
|
def method_missing(sym, *args)
|
|
@@ -233,10 +240,6 @@ end
|
|
|
233
240
|
|
|
234
241
|
module Rant
|
|
235
242
|
|
|
236
|
-
# In the class definition of Rant::RantApp, this will be set to a
|
|
237
|
-
# new application object.
|
|
238
|
-
@@rac = nil
|
|
239
|
-
|
|
240
243
|
class << self
|
|
241
244
|
|
|
242
245
|
# Run a new rant application in the current working directory.
|
|
@@ -265,36 +268,32 @@ module Rant
|
|
|
265
268
|
def run(first_arg=nil, *other_args)
|
|
266
269
|
other_args = other_args.flatten
|
|
267
270
|
args = first_arg.nil? ? ARGV.dup : ([first_arg] + other_args)
|
|
268
|
-
if
|
|
269
|
-
|
|
270
|
-
@@rac.run
|
|
271
|
+
if rant && !rant.run?
|
|
272
|
+
rant.run(args.flatten)
|
|
271
273
|
else
|
|
272
|
-
|
|
273
|
-
|
|
274
|
+
Rant::MAIN_OBJECT.instance_variable_set(
|
|
275
|
+
:@__rant__, Rant::RantApp.new)
|
|
276
|
+
rant.run(args)
|
|
274
277
|
end
|
|
275
278
|
end
|
|
276
279
|
|
|
277
|
-
def
|
|
278
|
-
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def rac=(app)
|
|
282
|
-
@@rac = app
|
|
280
|
+
def rant
|
|
281
|
+
Rant::MAIN_OBJECT.instance_variable_get(:@__rant__)
|
|
283
282
|
end
|
|
284
283
|
end
|
|
285
284
|
|
|
286
|
-
end
|
|
285
|
+
end # module Rant
|
|
287
286
|
|
|
288
287
|
class Rant::RantApp
|
|
289
288
|
include Rant::Console
|
|
290
289
|
|
|
291
290
|
class AutoLoadNodeFactory
|
|
292
|
-
def initialize(
|
|
293
|
-
@
|
|
291
|
+
def initialize(rant)
|
|
292
|
+
@rant = rant
|
|
294
293
|
end
|
|
295
294
|
def method_missing(sym, *args, &block)
|
|
296
|
-
@
|
|
297
|
-
@
|
|
295
|
+
@rant.import "nodes/default"
|
|
296
|
+
@rant.node_factory.send(sym, *args, &block)
|
|
298
297
|
end
|
|
299
298
|
end
|
|
300
299
|
|
|
@@ -320,9 +319,13 @@ class Rant::RantApp
|
|
|
320
319
|
"Print failed commands and their exit status." ],
|
|
321
320
|
[ "--directory","-C", GetoptLong::REQUIRED_ARGUMENT,
|
|
322
321
|
"Run rant in DIRECTORY." ],
|
|
322
|
+
[ "--cd-parent","-c", GetoptLong::NO_ARGUMENT,
|
|
323
|
+
"Run rant in parent directory with Rantfile." ],
|
|
324
|
+
[ "--look-up", "-u", GetoptLong::NO_ARGUMENT,
|
|
325
|
+
"Look in parent directories for root Rantfile." ],
|
|
323
326
|
[ "--rantfile", "-f", GetoptLong::REQUIRED_ARGUMENT,
|
|
324
327
|
"Process RANTFILE instead of standard rantfiles.\n" +
|
|
325
|
-
"Multiple files may be specified with this option"
|
|
328
|
+
"Multiple files may be specified with this option." ],
|
|
326
329
|
[ "--force-run","-a", GetoptLong::REQUIRED_ARGUMENT,
|
|
327
330
|
"Force rebuild of TARGET and all dependencies." ],
|
|
328
331
|
[ "--tasks", "-T", GetoptLong::NO_ARGUMENT,
|
|
@@ -340,7 +343,7 @@ class Rant::RantApp
|
|
|
340
343
|
|
|
341
344
|
# Reference project's root directory in task names by preceding
|
|
342
345
|
# them with this character.
|
|
343
|
-
ROOT_DIR_ID = "
|
|
346
|
+
ROOT_DIR_ID = "@"
|
|
344
347
|
ESCAPE_ID = "\\"
|
|
345
348
|
|
|
346
349
|
# Arguments, usually those given on commandline.
|
|
@@ -374,6 +377,11 @@ class Rant::RantApp
|
|
|
374
377
|
#
|
|
375
378
|
# Note: Might change before 1.0
|
|
376
379
|
attr_reader :resolve_hooks
|
|
380
|
+
# Root directory of project. Will be initialized to working
|
|
381
|
+
# directory in #initialize. This is always an absolute path
|
|
382
|
+
# beginning with a <tt>/</tt> and not ending in a slash (unless
|
|
383
|
+
# rootdir is <tt>/</tt>).
|
|
384
|
+
attr_reader :rootdir
|
|
377
385
|
|
|
378
386
|
attr_accessor :node_factory
|
|
379
387
|
|
|
@@ -387,28 +395,26 @@ class Rant::RantApp
|
|
|
387
395
|
# Rantfiles will be loaded in the context of this object.
|
|
388
396
|
@context = RantAppContext.new(self)
|
|
389
397
|
@sys = ::Rant::SysObject.new(self)
|
|
390
|
-
Rant.rac ||= self
|
|
391
398
|
@rantfiles = []
|
|
392
399
|
@tasks = {}
|
|
393
400
|
@opts = {
|
|
394
|
-
:verbose
|
|
395
|
-
:quiet
|
|
396
|
-
:directory => "",
|
|
401
|
+
:verbose => 0,
|
|
402
|
+
:quiet => false,
|
|
397
403
|
}
|
|
404
|
+
@rootdir = Dir.pwd # root directory of project
|
|
398
405
|
@arg_rantfiles = [] # rantfiles given in args
|
|
399
406
|
@arg_targets = [] # targets given in args
|
|
400
|
-
@force_targets = []
|
|
401
|
-
@run = false
|
|
402
|
-
@done = false
|
|
407
|
+
@force_targets = [] # targets given with -a option
|
|
408
|
+
@run = false # run method was called at least once
|
|
409
|
+
@done = false # run method was successful
|
|
403
410
|
@plugins = []
|
|
404
411
|
@var = Rant::RantVar::Space.new
|
|
405
412
|
@var.query :ignore, :AutoList, []
|
|
406
413
|
@imports = []
|
|
407
414
|
|
|
408
|
-
#@task_show = nil
|
|
409
415
|
@task_desc = nil
|
|
416
|
+
@last_build_subdir = ""
|
|
410
417
|
|
|
411
|
-
@orig_pwd = nil
|
|
412
418
|
@current_subdir = ""
|
|
413
419
|
@resolve_hooks = []
|
|
414
420
|
|
|
@@ -420,41 +426,17 @@ class Rant::RantApp
|
|
|
420
426
|
end
|
|
421
427
|
|
|
422
428
|
def []=(opt, val)
|
|
423
|
-
|
|
424
|
-
when :directory
|
|
425
|
-
self.rootdir = val
|
|
426
|
-
else
|
|
427
|
-
@opts[opt] = val
|
|
428
|
-
end
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
def rootdir
|
|
432
|
-
@opts[:directory]
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
def rootdir=(newdir)
|
|
436
|
-
if @run
|
|
437
|
-
raise "rootdir of rant application can't " +
|
|
438
|
-
"be changed after calling `run'"
|
|
439
|
-
end
|
|
440
|
-
unless String === newdir
|
|
441
|
-
raise "rootdir has to be a String"
|
|
442
|
-
end
|
|
443
|
-
@opts[:directory] = newdir.dup
|
|
429
|
+
@opts[opt] = val
|
|
444
430
|
end
|
|
445
431
|
|
|
446
432
|
### support for subdirectories ###################################
|
|
447
|
-
def expand_project_path(path)
|
|
448
|
-
expand_path(@current_subdir, path)
|
|
449
|
-
end
|
|
450
433
|
def expand_path(subdir, path)
|
|
451
434
|
case path
|
|
452
435
|
when nil: subdir.dup
|
|
453
436
|
when "": subdir.dup
|
|
454
|
-
when
|
|
455
|
-
when /^\\#/: path.sub(/^\\/, '')
|
|
437
|
+
when /^@/: path.sub(/^@/, '')
|
|
456
438
|
else
|
|
457
|
-
|
|
439
|
+
path = path.sub(/^\\(?=@)/, '')
|
|
458
440
|
if subdir.empty?
|
|
459
441
|
# we are in project's root directory
|
|
460
442
|
path
|
|
@@ -467,37 +449,42 @@ class Rant::RantApp
|
|
|
467
449
|
# method ensures that the returned absolute path doesn't end in a
|
|
468
450
|
# slash.
|
|
469
451
|
def project_to_fs_path(path)
|
|
470
|
-
|
|
471
|
-
sub
|
|
472
|
-
sub.empty? ? base : File.join(base, sub)
|
|
452
|
+
sub = expand_path(@current_subdir, path)
|
|
453
|
+
sub.empty? ? @rootdir : File.join(@rootdir, sub)
|
|
473
454
|
end
|
|
474
455
|
def goto(dir)
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
456
|
+
goto_project_dir(expand_path(@current_subdir, dir))
|
|
457
|
+
end
|
|
458
|
+
# +dir+ is a path relative to +rootdir+. It has to be a "clean"
|
|
459
|
+
# path string, i.e. it mustn't start with <tt>./</tt>, contain any
|
|
460
|
+
# <tt>..</tt> parent reference and it mustn't have a trailing
|
|
461
|
+
# slash.
|
|
462
|
+
#
|
|
463
|
+
# To go to the root directory, dir has to be an empty string,
|
|
464
|
+
# which is the default value.
|
|
465
|
+
def goto_project_dir(dir='')
|
|
466
|
+
@current_subdir = dir
|
|
467
|
+
abs_path = @current_subdir.empty? ?
|
|
468
|
+
@rootdir : File.join(@rootdir, @current_subdir)
|
|
480
469
|
unless Dir.pwd == abs_path
|
|
481
|
-
#puts "pwd: #{Dir.pwd}; abs_path: #{abs_path}"
|
|
482
|
-
#puts " current subdir: #@current_subdir"
|
|
483
470
|
Dir.chdir abs_path
|
|
484
|
-
|
|
485
|
-
#STDERR.puts "rant: in #{p_dir}"
|
|
471
|
+
vmsg 1, "in #{abs_path}"
|
|
486
472
|
end
|
|
487
473
|
end
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
#
|
|
494
|
-
def
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
474
|
+
=begin
|
|
475
|
+
# Execute block in subdirectory context to subdir, relative to
|
|
476
|
+
# project root directory. Important: Does NOT change the process
|
|
477
|
+
# working directory. Not thread safe.
|
|
478
|
+
#
|
|
479
|
+
# For Rant internal use only!
|
|
480
|
+
def define_in_project_dir(dir)
|
|
481
|
+
old_subdir = @current_subdir
|
|
482
|
+
@current_subdir = dir
|
|
483
|
+
yield
|
|
498
484
|
ensure
|
|
499
|
-
|
|
485
|
+
@current_subdir = old_subdir
|
|
500
486
|
end
|
|
487
|
+
=end
|
|
501
488
|
##################################################################
|
|
502
489
|
|
|
503
490
|
def run?
|
|
@@ -508,27 +495,20 @@ class Rant::RantApp
|
|
|
508
495
|
@done
|
|
509
496
|
end
|
|
510
497
|
|
|
498
|
+
# Run this Rant application with the given arguments. The process
|
|
499
|
+
# working directory after this method returns, will be the same as
|
|
500
|
+
# before invocation.
|
|
501
|
+
#
|
|
511
502
|
# Returns 0 on success and 1 on failure.
|
|
512
503
|
def run(*args)
|
|
513
504
|
@run = true
|
|
514
505
|
@args.concat(args.flatten)
|
|
515
506
|
# remind pwd
|
|
516
|
-
|
|
507
|
+
orig_pwd = @rootdir = Dir.pwd
|
|
517
508
|
# Process commandline.
|
|
518
509
|
process_args
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
if !(opts_dir.empty? || opts_dir.nil?)
|
|
522
|
-
opts_dir = File.expand_path(opts_dir)
|
|
523
|
-
unless test(?d, opts_dir)
|
|
524
|
-
abort("No such directory - #{opts_dir}")
|
|
525
|
-
end
|
|
526
|
-
Dir.chdir(opts_dir) if opts_dir != @orig_pwd
|
|
527
|
-
@opts[:directory] = opts_dir
|
|
528
|
-
else
|
|
529
|
-
@opts[:directory] = @orig_pwd
|
|
530
|
-
end
|
|
531
|
-
# read rantfiles
|
|
510
|
+
Dir.chdir(@rootdir)
|
|
511
|
+
# read rantfiles, might change @rootdir and Dir.pwd
|
|
532
512
|
load_rantfiles
|
|
533
513
|
|
|
534
514
|
raise Rant::RantDoneException if @opts[:stop_after_load]
|
|
@@ -541,12 +521,10 @@ class Rant::RantApp
|
|
|
541
521
|
end
|
|
542
522
|
# run tasks
|
|
543
523
|
run_tasks
|
|
544
|
-
goto "#"
|
|
545
524
|
raise Rant::RantDoneException
|
|
546
525
|
rescue Rant::RantDoneException
|
|
547
526
|
@done = true
|
|
548
527
|
# Notify plugins
|
|
549
|
-
goto "#"
|
|
550
528
|
@plugins.each { |plugin| plugin.rant_done }
|
|
551
529
|
return 0
|
|
552
530
|
rescue Rant::RantAbortException
|
|
@@ -563,13 +541,13 @@ class Rant::RantApp
|
|
|
563
541
|
return 1
|
|
564
542
|
ensure
|
|
565
543
|
# TODO: exception handling!
|
|
544
|
+
Dir.chdir @rootdir
|
|
566
545
|
hooks = var._get("__at_return__")
|
|
567
546
|
hooks.each { |hook| hook.call } if hooks
|
|
568
547
|
@plugins.each { |plugin| plugin.rant_plugin_stop }
|
|
569
548
|
@plugins.each { |plugin| plugin.rant_quit }
|
|
570
549
|
# restore pwd
|
|
571
|
-
|
|
572
|
-
Rant.rac = self.class.new
|
|
550
|
+
Dir.chdir orig_pwd
|
|
573
551
|
end
|
|
574
552
|
|
|
575
553
|
###### methods accessible through RantContext ####################
|
|
@@ -621,7 +599,7 @@ class Rant::RantApp
|
|
|
621
599
|
unless @imports.include? arg
|
|
622
600
|
unless Rant::CODE_IMPORTS.include? arg
|
|
623
601
|
begin
|
|
624
|
-
|
|
602
|
+
vmsg 2, "import #{arg}"
|
|
625
603
|
require "rant/import/#{arg}"
|
|
626
604
|
rescue LoadError => e
|
|
627
605
|
abort_at(ch, "No such import - #{arg}")
|
|
@@ -673,7 +651,7 @@ class Rant::RantApp
|
|
|
673
651
|
plugin = pl_class.rant_plugin_new(self, ch, *args, &block)
|
|
674
652
|
# TODO: check for rant_plugin?
|
|
675
653
|
@plugins << plugin
|
|
676
|
-
|
|
654
|
+
vmsg 2, "Plugin `#{plugin.rant_plugin_name}' registered."
|
|
677
655
|
plugin.rant_plugin_init
|
|
678
656
|
# return plugin instance
|
|
679
657
|
plugin
|
|
@@ -731,32 +709,41 @@ class Rant::RantApp
|
|
|
731
709
|
loaded = false
|
|
732
710
|
prev_subdir = @current_subdir
|
|
733
711
|
begin
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
712
|
+
#puts "* subdir *",
|
|
713
|
+
# " rootdir: #{rootdir}",
|
|
714
|
+
# " current subdir: #@current_subdir",
|
|
715
|
+
# " pwd: #{Dir.pwd}",
|
|
716
|
+
# " arg: #{arg}"
|
|
739
717
|
goto arg
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
718
|
+
if test(?f, Rant::SUB_RANTFILE)
|
|
719
|
+
path = Rant::SUB_RANTFILE
|
|
720
|
+
else
|
|
721
|
+
path = rantfile_in_dir
|
|
722
|
+
end
|
|
723
|
+
if path
|
|
724
|
+
if defined? @initial_subdir and
|
|
725
|
+
@initial_subdir == @current_subdir
|
|
726
|
+
rf, is_new = rantfile_for_path(path, false)
|
|
727
|
+
@rantfiles.unshift rf if is_new
|
|
728
|
+
else
|
|
729
|
+
rf, is_new = rantfile_for_path(path)
|
|
730
|
+
end
|
|
743
731
|
load_file rf if is_new
|
|
744
|
-
|
|
732
|
+
elsif !@opts[:no_warn_subdir]
|
|
733
|
+
warn_msg(pos_text(ch[:file], ch[:ln]),
|
|
734
|
+
"subdirs: No Rantfile in subdir `#{arg}'.")
|
|
735
|
+
end
|
|
745
736
|
ensure
|
|
746
|
-
|
|
737
|
+
#puts " going back to project dir: #{prev_subdir}"
|
|
747
738
|
goto_project_dir prev_subdir
|
|
748
739
|
end
|
|
749
|
-
unless loaded || @opts[:no_warn_subdir]
|
|
750
|
-
warn_msg(pos_text(ch[:file], ch[:ln]),
|
|
751
|
-
"subdirs: No Rantfile in subdir `#{arg}'.")
|
|
752
|
-
end
|
|
753
740
|
}
|
|
754
741
|
rescue SystemCallError => e
|
|
755
742
|
abort_at(ch, "subdirs: " + e.message)
|
|
756
743
|
end
|
|
757
744
|
|
|
758
745
|
def sys(*args, &block)
|
|
759
|
-
args.empty? ? @sys : @sys.sh(*args)
|
|
746
|
+
args.empty? ? @sys : @sys.sh(*args, &block)
|
|
760
747
|
end
|
|
761
748
|
|
|
762
749
|
# The [] and []= operators may be used to set/get values from this
|
|
@@ -807,26 +794,21 @@ class Rant::RantApp
|
|
|
807
794
|
end
|
|
808
795
|
prefix = "rant "
|
|
809
796
|
infix = " # "
|
|
810
|
-
|
|
811
|
-
tlist.each { |t|
|
|
812
|
-
if t.full_name.length > name_length
|
|
813
|
-
name_length = t.full_name.length
|
|
814
|
-
end
|
|
815
|
-
}
|
|
816
|
-
name_length < 7 && name_length = 7
|
|
797
|
+
name_length = (tlist.map{ |t| t.to_s.length } << 7).max
|
|
817
798
|
cmd_length = prefix.length + name_length
|
|
818
|
-
unless tlist.first.
|
|
799
|
+
unless tlist.first.to_s == def_target
|
|
819
800
|
defaults = list_task_names(
|
|
820
801
|
resolve(def_target)).join(', ')
|
|
821
802
|
puts "#{prefix}#{' ' * name_length}#{infix}=> #{defaults}"
|
|
822
803
|
end
|
|
823
804
|
tlist.each { |t|
|
|
824
|
-
print(prefix + t.
|
|
805
|
+
print(prefix + t.to_s.ljust(name_length) + infix)
|
|
825
806
|
dt = t.description.sub(/\s+$/, "")
|
|
826
807
|
puts dt.sub(/\n/, "\n" + ' ' * cmd_length + infix + " ")
|
|
827
808
|
}
|
|
828
809
|
true
|
|
829
810
|
end
|
|
811
|
+
|
|
830
812
|
def list_task_names(*tasks)
|
|
831
813
|
rsl = []
|
|
832
814
|
tasks.flatten.each { |t|
|
|
@@ -836,7 +818,10 @@ class Rant::RantApp
|
|
|
836
818
|
if t.prerequisites.empty?
|
|
837
819
|
rsl << t
|
|
838
820
|
else
|
|
839
|
-
|
|
821
|
+
t.prerequisites.each { |pre|
|
|
822
|
+
rsl.concat(list_task_names(
|
|
823
|
+
resolve(pre, t.project_subdir)))
|
|
824
|
+
}
|
|
840
825
|
end
|
|
841
826
|
else
|
|
842
827
|
rsl << t
|
|
@@ -862,50 +847,31 @@ class Rant::RantApp
|
|
|
862
847
|
t << ": "
|
|
863
848
|
end
|
|
864
849
|
|
|
865
|
-
def msg(*args)
|
|
866
|
-
verbose_level = args[0]
|
|
867
|
-
if verbose_level.is_a? Integer
|
|
868
|
-
super(args[1..-1]) if verbose_level <= verbose
|
|
869
|
-
else
|
|
870
|
-
super
|
|
871
|
-
end
|
|
872
|
-
end
|
|
873
|
-
|
|
874
850
|
# Print a command message as would be done from a call to a
|
|
875
|
-
#
|
|
851
|
+
# sys method.
|
|
876
852
|
def cmd_msg(cmd)
|
|
877
853
|
puts cmd unless quiet?
|
|
878
854
|
end
|
|
879
855
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
warn_msg(*args)
|
|
884
|
-
end
|
|
885
|
-
# The preferred way for a plugin to report an error.
|
|
886
|
-
def plugin_err(*args)
|
|
887
|
-
err_msg(*args)
|
|
856
|
+
def cmd_print(text)
|
|
857
|
+
print text unless quiet?
|
|
858
|
+
$stdout.flush
|
|
888
859
|
end
|
|
889
860
|
|
|
890
|
-
# Get the plugin with the given name or nil. Yields the plugin
|
|
891
|
-
# object if block given.
|
|
892
|
-
def plugin_named(name)
|
|
893
|
-
@plugins.each { |plugin|
|
|
894
|
-
if plugin.rant_plugin_name == name
|
|
895
|
-
yield plugin if block_given?
|
|
896
|
-
return plugin
|
|
897
|
-
end
|
|
898
|
-
}
|
|
899
|
-
nil
|
|
900
|
-
end
|
|
901
|
-
##################################################################
|
|
902
|
-
|
|
903
861
|
# All targets given on commandline, including those given
|
|
904
862
|
# with the -a option. The list will be in processing order.
|
|
905
863
|
def cmd_targets
|
|
906
864
|
@force_targets + @arg_targets
|
|
907
865
|
end
|
|
908
866
|
|
|
867
|
+
def running_task(task)
|
|
868
|
+
if @current_subdir != @last_build_subdir
|
|
869
|
+
cmd_msg "(in #{@current_subdir.empty? ?
|
|
870
|
+
@rootdir : @current_subdir})"
|
|
871
|
+
@last_build_subdir = @current_subdir
|
|
872
|
+
end
|
|
873
|
+
end
|
|
874
|
+
|
|
909
875
|
private
|
|
910
876
|
def have_any_task?
|
|
911
877
|
!@tasks.empty?
|
|
@@ -921,15 +887,16 @@ class Rant::RantApp
|
|
|
921
887
|
# run default task, if not given:
|
|
922
888
|
# run first defined task.
|
|
923
889
|
target_list = @force_targets + @arg_targets
|
|
924
|
-
# The target list is a list of strings, not
|
|
890
|
+
# The target list is a list of strings, not node objects!
|
|
925
891
|
if target_list.empty?
|
|
926
892
|
def_tasks = resolve "default"
|
|
927
893
|
unless def_tasks.empty?
|
|
928
894
|
target_list << "default"
|
|
929
895
|
else
|
|
930
896
|
@rantfiles.each { |f|
|
|
931
|
-
|
|
932
|
-
|
|
897
|
+
first = f.tasks.first
|
|
898
|
+
if first
|
|
899
|
+
target_list << first.reference_name
|
|
933
900
|
break
|
|
934
901
|
end
|
|
935
902
|
}
|
|
@@ -938,17 +905,18 @@ class Rant::RantApp
|
|
|
938
905
|
target_list
|
|
939
906
|
end
|
|
940
907
|
|
|
908
|
+
# If this method returns (i.e. no exception was risen),
|
|
909
|
+
# current_subdir is the same as before invocation.
|
|
941
910
|
def run_tasks
|
|
942
911
|
# Now, run all specified tasks in all rantfiles,
|
|
943
912
|
# rantfiles in reverse order.
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
goto "#"
|
|
913
|
+
target_list.each { |target|
|
|
914
|
+
# build ensures that current_subdir is the same before
|
|
915
|
+
# and after invocation
|
|
948
916
|
if build(target) == 0
|
|
949
917
|
abort("Don't know how to make `#{target}'.")
|
|
950
918
|
end
|
|
951
|
-
|
|
919
|
+
}
|
|
952
920
|
end
|
|
953
921
|
|
|
954
922
|
def make(target, *args, &block)
|
|
@@ -1026,7 +994,7 @@ class Rant::RantApp
|
|
|
1026
994
|
when nil
|
|
1027
995
|
@resolve_hooks.each { |s|
|
|
1028
996
|
# Note: will probably change to get more params
|
|
1029
|
-
s = s[task_name]
|
|
997
|
+
s = s[task_name, rel_project_dir]
|
|
1030
998
|
#if s
|
|
1031
999
|
# puts s.size
|
|
1032
1000
|
# t = s.first
|
|
@@ -1053,7 +1021,7 @@ class Rant::RantApp
|
|
|
1053
1021
|
end
|
|
1054
1022
|
public :at_resolve
|
|
1055
1023
|
|
|
1056
|
-
# block will be called before this
|
|
1024
|
+
# block will be called before this rant returns from #run
|
|
1057
1025
|
# pwd will be the projects root directory
|
|
1058
1026
|
def at_return(&block)
|
|
1059
1027
|
hooks = var._get("__at_return__")
|
|
@@ -1083,79 +1051,107 @@ class Rant::RantApp
|
|
|
1083
1051
|
# some "rant code" could already have run!
|
|
1084
1052
|
# We run the default Rantfiles only if no tasks where
|
|
1085
1053
|
# already defined and no Rantfile was given in args.
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1054
|
+
unless @arg_rantfiles.empty?
|
|
1055
|
+
@arg_rantfiles.each { |fn|
|
|
1056
|
+
if test(?f, fn)
|
|
1057
|
+
rf, is_new = rantfile_for_path(fn)
|
|
1058
|
+
load_file rf if is_new
|
|
1059
|
+
else
|
|
1060
|
+
abort "No such file -- #{rf}"
|
|
1061
|
+
end
|
|
1062
|
+
}
|
|
1063
|
+
return
|
|
1064
|
+
end
|
|
1065
|
+
return if have_any_task?
|
|
1066
|
+
# look for standard Rantfile in working directory
|
|
1067
|
+
fn = rantfile_in_dir
|
|
1068
|
+
if @opts[:cd_parent]
|
|
1069
|
+
# search for Rantfile in parent directories
|
|
1070
|
+
old_root = @rootdir
|
|
1071
|
+
until fn or @rootdir == "/"
|
|
1072
|
+
@rootdir = File.dirname(@rootdir)
|
|
1073
|
+
fn = rantfile_in_dir(@rootdir)
|
|
1074
|
+
end
|
|
1075
|
+
if @rootdir != old_root and fn
|
|
1076
|
+
Dir.chdir @rootdir
|
|
1077
|
+
cmd_msg "(in #@rootdir)"
|
|
1078
|
+
end
|
|
1079
|
+
end
|
|
1080
|
+
if fn
|
|
1081
|
+
rf, is_new = rantfile_for_path(fn)
|
|
1082
|
+
load_file rf if is_new
|
|
1083
|
+
return
|
|
1084
|
+
end
|
|
1085
|
+
have_sub_rantfile = test(?f, Rant::SUB_RANTFILE)
|
|
1086
|
+
if have_sub_rantfile || @opts[:look_up]
|
|
1087
|
+
# search for "root" Rantfile in parent directories, treat
|
|
1088
|
+
# current working directory as project subdirectory
|
|
1089
|
+
cur_dir = Dir.pwd
|
|
1090
|
+
until cur_dir == "/"
|
|
1091
|
+
cur_dir = File.dirname(cur_dir)
|
|
1092
|
+
Dir.chdir cur_dir
|
|
1093
|
+
fn = rantfile_in_dir
|
|
1094
|
+
if fn
|
|
1095
|
+
@initial_subdir = @rootdir.sub(
|
|
1096
|
+
/^#{Regexp.escape cur_dir}\//, '')
|
|
1097
|
+
# adjust rootdir
|
|
1098
|
+
@rootdir = cur_dir
|
|
1099
|
+
cmd_msg "(root is #@rootdir, in #@initial_subdir)"
|
|
1100
|
+
@last_build_subdir = @initial_subdir
|
|
1101
|
+
rf, is_new = rantfile_for_path(fn)
|
|
1102
|
+
load_file rf if is_new
|
|
1103
|
+
goto_project_dir @initial_subdir
|
|
1104
|
+
# ensure to read sub.rant in initial subdir even
|
|
1105
|
+
# if it wasn't mentioned with +subdirs+.
|
|
1106
|
+
if have_sub_rantfile
|
|
1107
|
+
rf, is_new = rantfile_for_path(
|
|
1108
|
+
Rant::SUB_RANTFILE, false)
|
|
1109
|
+
if is_new
|
|
1110
|
+
@rantfiles.unshift rf
|
|
1111
|
+
load_file rf
|
|
1112
|
+
end
|
|
1113
|
+
end
|
|
1114
|
+
break
|
|
1115
|
+
end
|
|
1116
|
+
end
|
|
1117
|
+
end
|
|
1118
|
+
if @rantfiles.empty?
|
|
1119
|
+
abort("No Rantfile found, looking for:",
|
|
1120
|
+
Rant::RANTFILES.join(", "))
|
|
1121
|
+
end
|
|
1111
1122
|
end
|
|
1112
1123
|
|
|
1113
1124
|
# Returns the value of the last expression executed in +rantfile+.
|
|
1114
1125
|
# +rantfile+ has to be an Rant::Rantfile instance.
|
|
1115
1126
|
def load_file(rantfile)
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
begin
|
|
1119
|
-
path = rantfile.path
|
|
1120
|
-
rv = @context.instance_eval(File.read(path), path)
|
|
1121
|
-
rescue NameError => e
|
|
1122
|
-
abort("Name error when loading `#{rantfile}':",
|
|
1123
|
-
e.message, e.backtrace)
|
|
1124
|
-
rescue LoadError => e
|
|
1125
|
-
abort("Load error when loading `#{rantfile}':",
|
|
1126
|
-
e.message, e.backtrace)
|
|
1127
|
-
rescue ScriptError => e
|
|
1128
|
-
abort("Script error when loading `#{rantfile}':",
|
|
1129
|
-
e.message, e.backtrace)
|
|
1130
|
-
end
|
|
1131
|
-
unless @rantfiles.include?(rantfile)
|
|
1132
|
-
@rantfiles << rantfile
|
|
1133
|
-
end
|
|
1134
|
-
rv
|
|
1127
|
+
vmsg 1, "source #{rantfile}"
|
|
1128
|
+
@context.instance_eval(File.read(rantfile), rantfile)
|
|
1135
1129
|
end
|
|
1136
1130
|
private :load_file
|
|
1137
1131
|
|
|
1138
|
-
# Get
|
|
1132
|
+
# Get path to Rantfile in +dir+ or nil if dir doesn't contain an
|
|
1133
|
+
# Rantfile.
|
|
1134
|
+
#
|
|
1139
1135
|
# If dir is nil, look in current directory.
|
|
1140
|
-
|
|
1141
|
-
# to the rantfiles.
|
|
1142
|
-
def rantfiles_in_dir(dir=nil)
|
|
1143
|
-
files = []
|
|
1136
|
+
def rantfile_in_dir(dir=nil)
|
|
1144
1137
|
::Rant::RANTFILES.each { |rfn|
|
|
1145
1138
|
path = dir ? File.join(dir, rfn) : rfn
|
|
1146
|
-
|
|
1147
|
-
# in case. This protects from loading the same file twice
|
|
1148
|
-
# on case insensitive file systems.
|
|
1149
|
-
unless files.find { |f| f.downcase == path.downcase }
|
|
1150
|
-
files << path if test(?f, path)
|
|
1151
|
-
end
|
|
1139
|
+
return path if test ?f, path
|
|
1152
1140
|
}
|
|
1153
|
-
|
|
1141
|
+
::Rant::DEPRECATED_RANTFILES.each { |rfn|
|
|
1142
|
+
path = dir ? File.join(dir, rfn) : rfn
|
|
1143
|
+
if test ?f, path
|
|
1144
|
+
warn_msg "filename deprecated -- #{path}",
|
|
1145
|
+
"please rename it to `Rantfile' or `root.rant'!"
|
|
1146
|
+
return path
|
|
1147
|
+
end
|
|
1148
|
+
}
|
|
1149
|
+
nil
|
|
1154
1150
|
end
|
|
1155
1151
|
|
|
1156
1152
|
def process_args
|
|
1157
1153
|
# WARNING: we currently have to fool getoptlong,
|
|
1158
|
-
# by
|
|
1154
|
+
# by temporary changing ARGV!
|
|
1159
1155
|
# This could cause problems (e.g. multithreading).
|
|
1160
1156
|
old_argv = ARGV.dup
|
|
1161
1157
|
ARGV.replace(@args.dup)
|
|
@@ -1171,9 +1167,7 @@ class Rant::RantApp
|
|
|
1171
1167
|
show_help
|
|
1172
1168
|
raise Rant::RantDoneException
|
|
1173
1169
|
when "--directory"
|
|
1174
|
-
|
|
1175
|
-
# because @run is true
|
|
1176
|
-
@opts[:directory] = value
|
|
1170
|
+
@rootdir = File.expand_path(value)
|
|
1177
1171
|
when "--rantfile"
|
|
1178
1172
|
@arg_rantfiles << value
|
|
1179
1173
|
when "--force-run"
|
|
@@ -1192,7 +1186,7 @@ class Rant::RantApp
|
|
|
1192
1186
|
ARGV.replace(old_argv)
|
|
1193
1187
|
rem_args.each { |ra|
|
|
1194
1188
|
if ra =~ /(^[^=]+)=([^=]+)$/
|
|
1195
|
-
|
|
1189
|
+
vmsg 2, "var: #$1=#$2"
|
|
1196
1190
|
@var[$1] = $2
|
|
1197
1191
|
else
|
|
1198
1192
|
@arg_targets << ra
|
|
@@ -1216,7 +1210,8 @@ class Rant::RantApp
|
|
|
1216
1210
|
file, is_new = rantfile_for_path(ch[:file])
|
|
1217
1211
|
nt = yield(name, pre, block)
|
|
1218
1212
|
nt.rantfile = file
|
|
1219
|
-
nt.project_subdir = file.project_subdir
|
|
1213
|
+
#nt.project_subdir = file.project_subdir
|
|
1214
|
+
nt.project_subdir = @current_subdir
|
|
1220
1215
|
nt.line_number = ch[:ln]
|
|
1221
1216
|
nt.description = @task_desc
|
|
1222
1217
|
@task_desc = nil
|
|
@@ -1302,17 +1297,17 @@ class Rant::RantApp
|
|
|
1302
1297
|
# and a boolean value as second. If the second is true,
|
|
1303
1298
|
# the rantfile was created and added, otherwise the rantfile
|
|
1304
1299
|
# already existed.
|
|
1305
|
-
def rantfile_for_path(path)
|
|
1300
|
+
def rantfile_for_path(path, register=true)
|
|
1306
1301
|
# all rantfiles have an absolute path as path attribute
|
|
1307
1302
|
abs_path = File.expand_path(path)
|
|
1308
|
-
|
|
1309
|
-
|
|
1303
|
+
file = @rantfiles.find { |rf| rf.path == abs_path }
|
|
1304
|
+
if file
|
|
1310
1305
|
[file, false]
|
|
1311
1306
|
else
|
|
1312
1307
|
# create new Rantfile object
|
|
1313
1308
|
file = Rant::Rantfile.new abs_path
|
|
1314
1309
|
file.project_subdir = @current_subdir
|
|
1315
|
-
@rantfiles << file
|
|
1310
|
+
@rantfiles << file if register
|
|
1316
1311
|
[file, true]
|
|
1317
1312
|
end
|
|
1318
1313
|
end
|
|
@@ -1363,10 +1358,5 @@ class Rant::RantApp
|
|
|
1363
1358
|
err_msg msg unless msg.empty?
|
|
1364
1359
|
err_msg t_msg
|
|
1365
1360
|
end
|
|
1366
|
-
|
|
1367
|
-
# Just ensure that Rant.rac holds an RantApp after loading
|
|
1368
|
-
# this file. The code in initialize will register the new app with
|
|
1369
|
-
# Rant.rac= if necessary.
|
|
1370
|
-
self.new
|
|
1371
|
-
|
|
1372
1361
|
end # class Rant::RantApp
|
|
1362
|
+
# this line prevents ruby 1.8.3 from segfaulting
|