rant 0.3.2 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +22 -1
- data/README +9 -12
- data/Rantfile +32 -9
- data/devel-notes +16 -0
- data/doc/advanced.rdoc +55 -0
- data/doc/rant.rdoc +27 -2
- data/doc/rantfile.rdoc +104 -30
- data/install.rb +6 -0
- data/lib/rant.rb +5 -1
- data/lib/rant/import.rb +12 -4
- data/lib/rant/import/rubydoc.rb +1 -1
- data/lib/rant/import/rubypackage.rb +2 -2
- data/lib/rant/import/rubytest.rb +3 -2
- data/lib/rant/plugin/csharp.rb +5 -9
- data/lib/rant/rantenv.rb +1 -0
- data/lib/rant/rantfile.rb +184 -68
- data/lib/rant/rantlib.rb +203 -195
- data/lib/rant/rantsys.rb +87 -44
- data/lib/rant/rantvar.rb +236 -17
- data/rantmethods.rb +9 -4
- data/run_rant +1 -1
- data/test/Rantfile +16 -0
- data/test/plugin/csharp/test_csharp.rb +2 -1
- data/test/plugin/rantfile +1 -0
- data/test/project1/Rantfile +8 -4
- data/test/rule.rf +27 -0
- data/test/subdirs/Rantfile +2 -0
- data/test/subdirs/sub2/sub/rantfile +17 -0
- data/test/subdirs/test_subdirs.rb +46 -2
- data/test/test_dirtask.rb +33 -0
- data/test/test_filelist.rb +81 -0
- data/test/test_filetask.rb +6 -6
- data/test/test_rant_interface.rb +4 -3
- data/test/test_rule.rb +67 -0
- data/test/test_source.rb +26 -0
- data/test/test_task.rb +27 -6
- data/test/test_var.rb +102 -0
- data/test/toplevel.rf +1 -1
- data/test/var.rf +19 -0
- metadata +11 -2
data/lib/rant/rantsys.rb
CHANGED
@@ -4,15 +4,6 @@ require 'rant/rantenv'
|
|
4
4
|
|
5
5
|
module Rant
|
6
6
|
|
7
|
-
class Glob < String
|
8
|
-
class << self
|
9
|
-
# A synonym for +new+.
|
10
|
-
def [](pattern)
|
11
|
-
new(pattern)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
7
|
class FileList
|
17
8
|
include Enumerable
|
18
9
|
|
@@ -23,6 +14,8 @@ module Rant
|
|
23
14
|
# Flags for the File::fnmatch method.
|
24
15
|
# Initialized to 0.
|
25
16
|
attr_accessor :glob_flags
|
17
|
+
|
18
|
+
attr_reader :ignore_rx
|
26
19
|
|
27
20
|
class << self
|
28
21
|
def [](*patterns)
|
@@ -34,12 +27,21 @@ module Rant
|
|
34
27
|
@glob_flags = 0
|
35
28
|
@files = []
|
36
29
|
@actions = patterns.map { |pat| [:apply_include, pat] }
|
30
|
+
@ignore_rx = nil
|
37
31
|
@pending = true
|
38
32
|
yield self if block_given?
|
39
33
|
end
|
40
34
|
|
35
|
+
def dup
|
36
|
+
c = super
|
37
|
+
c.files = @files.dup
|
38
|
+
c.actions = @actions.dup
|
39
|
+
c.ignore_rx = @ignore_rx.dup if @ignore_rx
|
40
|
+
c
|
41
|
+
end
|
42
|
+
|
41
43
|
protected
|
42
|
-
|
44
|
+
attr_accessor :actions, :files
|
43
45
|
attr_accessor :pending
|
44
46
|
|
45
47
|
public
|
@@ -75,7 +77,14 @@ module Rant
|
|
75
77
|
end
|
76
78
|
|
77
79
|
def <<(file)
|
78
|
-
@files << file
|
80
|
+
@files << file unless file =~ ignore_rx
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
def concat(ary)
|
85
|
+
resolve if @pending
|
86
|
+
ix = ignore_rx
|
87
|
+
@files.concat(ary.to_ary.reject { |f| f =~ ix })
|
79
88
|
self
|
80
89
|
end
|
81
90
|
|
@@ -87,7 +96,9 @@ module Rant
|
|
87
96
|
def method_missing(sym, *args, &block)
|
88
97
|
if @files.respond_to? sym
|
89
98
|
resolve if @pending
|
99
|
+
fh = @files.hash
|
90
100
|
@files.send(sym, *args, &block)
|
101
|
+
@pending = true unless @files.hash == fh
|
91
102
|
else
|
92
103
|
super
|
93
104
|
end
|
@@ -100,6 +111,10 @@ module Rant
|
|
100
111
|
self.send(*action)
|
101
112
|
}
|
102
113
|
@actions.clear
|
114
|
+
ix = ignore_rx
|
115
|
+
if ix
|
116
|
+
@files.reject! { |f| f =~ ix }
|
117
|
+
end
|
103
118
|
end
|
104
119
|
|
105
120
|
def include(*patterns)
|
@@ -128,6 +143,24 @@ module Rant
|
|
128
143
|
self
|
129
144
|
end
|
130
145
|
|
146
|
+
def ignore(*patterns)
|
147
|
+
patterns.each { |pat|
|
148
|
+
add_ignore_rx(Regexp === pat ? pat : mk_all_rx(pat))
|
149
|
+
}
|
150
|
+
@pending = true
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
def add_ignore_rx(rx)
|
155
|
+
@ignore_rx =
|
156
|
+
if @ignore_rx
|
157
|
+
Regexp.union(@ignore_rx, rx)
|
158
|
+
else
|
159
|
+
rx
|
160
|
+
end
|
161
|
+
end
|
162
|
+
private :add_ignore_rx
|
163
|
+
|
131
164
|
def apply_exclude(pattern)
|
132
165
|
@files.reject! { |elem|
|
133
166
|
File.fnmatch? pattern, elem, @glob_flags
|
@@ -270,34 +303,35 @@ module Rant
|
|
270
303
|
def arglist
|
271
304
|
to_ary.arglist
|
272
305
|
end
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
if entry.include? ' '
|
283
|
-
'"' + entry + '"'
|
284
|
-
else
|
285
|
-
entry
|
286
|
-
end
|
287
|
-
}
|
288
|
-
else
|
289
|
-
self.collect { |entry|
|
290
|
-
if entry.include? ' '
|
291
|
-
"'" + entry + "'"
|
292
|
-
else
|
293
|
-
entry
|
294
|
-
end
|
295
|
-
}
|
296
|
-
end
|
306
|
+
end # class FileList
|
307
|
+
|
308
|
+
class RacFileList < FileList
|
309
|
+
|
310
|
+
def initialize(rac, *patterns)
|
311
|
+
@rac = rac
|
312
|
+
super(*patterns)
|
313
|
+
@ignore_hash = nil
|
314
|
+
update_ignore_rx
|
297
315
|
end
|
298
|
-
=end
|
299
316
|
|
300
|
-
|
317
|
+
private :ignore
|
318
|
+
|
319
|
+
def ignore_rx
|
320
|
+
update_ignore_rx
|
321
|
+
@ignore_rx
|
322
|
+
end
|
323
|
+
|
324
|
+
private
|
325
|
+
def update_ignore_rx
|
326
|
+
ri = @rac.var[:ignore]
|
327
|
+
rh = ri.hash
|
328
|
+
unless rh == @ignore_hash
|
329
|
+
@ignore_rx = nil
|
330
|
+
ignore(*ri) if ri
|
331
|
+
@ignore_hash = rh
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
301
335
|
|
302
336
|
class CommandError < StandardError
|
303
337
|
attr_reader :cmd
|
@@ -338,7 +372,7 @@ module Rant
|
|
338
372
|
# We override the output method of the FileUtils module to
|
339
373
|
# allow the Rant application to control output.
|
340
374
|
def fu_output_message(msg) #:nodoc:
|
341
|
-
::Rant.
|
375
|
+
::Rant.rac.cmd_msg msg if ::Rant.rac
|
342
376
|
end
|
343
377
|
|
344
378
|
def sh(*cmd_args, &block)
|
@@ -396,18 +430,27 @@ module Rant
|
|
396
430
|
class SysObject
|
397
431
|
include Sys
|
398
432
|
|
399
|
-
#
|
400
|
-
|
401
|
-
attr_reader :controller
|
433
|
+
# The controlling Rant compiler.
|
434
|
+
attr_reader :rac
|
402
435
|
|
403
|
-
def initialize(
|
404
|
-
@
|
436
|
+
def initialize(rac)
|
437
|
+
@rac = rac or
|
405
438
|
raise ArgumentError, "controller required"
|
406
439
|
end
|
407
440
|
|
441
|
+
def glob(*args, &block)
|
442
|
+
fl = RacFileList.new(@rac, *args)
|
443
|
+
fl.instance_eval(&block) if block
|
444
|
+
fl
|
445
|
+
end
|
446
|
+
|
447
|
+
def [](*patterns)
|
448
|
+
RacFileList.new(@rac, *patterns)
|
449
|
+
end
|
450
|
+
|
408
451
|
private
|
409
452
|
def fu_output_message(cmd)
|
410
|
-
@
|
453
|
+
@rac.cmd_msg cmd
|
411
454
|
end
|
412
455
|
end
|
413
456
|
end # module Rant
|
data/lib/rant/rantvar.rb
CHANGED
@@ -1,24 +1,95 @@
|
|
1
1
|
|
2
|
+
# rantvar.rb - Constants required by all Rant code.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
5
|
+
#
|
6
|
+
# This program is free software.
|
7
|
+
# You can distribute/modify this program under the terms of
|
8
|
+
# the GNU LGPL, Lesser General Public License version 2.1.
|
9
|
+
#
|
2
10
|
# This file provides support for the +var+ attribute of the Rant
|
3
11
|
# application (Rant::RantApp#var).
|
4
12
|
|
5
13
|
module Rant
|
14
|
+
VERSION = '0.3.4'
|
15
|
+
|
16
|
+
# Those are the filenames for rantfiles.
|
17
|
+
# Case matters!
|
18
|
+
RANTFILES = [ "Rantfile",
|
19
|
+
"rantfile",
|
20
|
+
"Rantfile.rb",
|
21
|
+
"rantfile.rb",
|
22
|
+
]
|
23
|
+
|
24
|
+
# Names of plugins and imports for which code was loaded.
|
25
|
+
# Files that where loaded with the `import' commant are directly
|
26
|
+
# added; files loaded with the `plugin' command are prefixed with
|
27
|
+
# "plugin/".
|
28
|
+
CODE_IMPORTS = []
|
29
|
+
|
30
|
+
class RantAbortException < StandardError
|
31
|
+
end
|
32
|
+
|
33
|
+
class RantDoneException < StandardError
|
34
|
+
end
|
35
|
+
|
36
|
+
class RantError < StandardError
|
37
|
+
end
|
38
|
+
|
39
|
+
class RantfileException < RantError
|
40
|
+
end
|
41
|
+
|
42
|
+
# This module is a namespace for generator classes.
|
43
|
+
module Generators
|
44
|
+
end
|
45
|
+
|
6
46
|
module RantVar
|
7
47
|
|
8
|
-
class Error <
|
48
|
+
class Error < RantError
|
9
49
|
end
|
10
50
|
|
11
51
|
class ConstraintError < Error
|
52
|
+
|
53
|
+
attr_reader :constraint, :val
|
54
|
+
|
55
|
+
def initialize(constraint, val, msg = nil)
|
56
|
+
#super(msg)
|
57
|
+
@msg = msg
|
58
|
+
@constraint = constraint
|
59
|
+
@val = val
|
60
|
+
end
|
61
|
+
|
62
|
+
def message
|
63
|
+
# TODO: handle @msg
|
64
|
+
val_desc = @val.inspect
|
65
|
+
val_desc[7..-1] = "..." if val_desc.length > 10
|
66
|
+
"#{val_desc} doesn't match constraint: #@constraint"
|
67
|
+
end
|
12
68
|
end
|
13
69
|
|
14
70
|
class InvalidVidError < Error
|
71
|
+
def initialize(vid, msg = nil)
|
72
|
+
@msg = msg
|
73
|
+
@vid = vid
|
74
|
+
end
|
75
|
+
def message
|
76
|
+
# TODO: handle @msg
|
77
|
+
vid_desc = @vid.inspect
|
78
|
+
vid_desc[7..-1] = "..." if vid_desc.length > 10
|
79
|
+
"#{vid_desc} is not a valid var identifier"
|
80
|
+
end
|
15
81
|
end
|
16
82
|
|
17
83
|
class InvalidConstraintError < Error
|
18
84
|
end
|
19
85
|
|
86
|
+
class QueryError < Error
|
87
|
+
end
|
88
|
+
|
20
89
|
class Space
|
21
90
|
|
91
|
+
@@env_ref = Object.new
|
92
|
+
|
22
93
|
def initialize
|
23
94
|
# holds all values
|
24
95
|
@store = {}
|
@@ -26,44 +97,190 @@ module Rant
|
|
26
97
|
@constraints = {}
|
27
98
|
end
|
28
99
|
|
100
|
+
def query(*args, &block)
|
101
|
+
# currently ignoring block
|
102
|
+
case args.size
|
103
|
+
when 0
|
104
|
+
raise QueryError, "no arguments", caller
|
105
|
+
when 1
|
106
|
+
arg = args.first
|
107
|
+
if Hash === arg
|
108
|
+
init_all arg
|
109
|
+
else
|
110
|
+
self[arg]
|
111
|
+
end
|
112
|
+
when 2..3
|
113
|
+
vid, constraint, val = *args
|
114
|
+
begin
|
115
|
+
constraint =
|
116
|
+
Constraints.const_get(constraint).new
|
117
|
+
rescue
|
118
|
+
raise QueryError,
|
119
|
+
"no such constraint: #{constraint}", caller
|
120
|
+
end
|
121
|
+
constrain vid, constraint
|
122
|
+
self[vid] = val if val
|
123
|
+
else
|
124
|
+
raise QueryError, "to many arguments"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
29
128
|
# Get var with name +vid+.
|
30
129
|
def [](vid)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@store[vid]
|
130
|
+
vid = RantVar.valid_vid vid
|
131
|
+
val = @store[vid]
|
132
|
+
val.equal?(@@env_ref) ? ENV[vid] : val
|
35
133
|
end
|
36
134
|
|
37
135
|
# Set var with name +vid+ to val. Throws a ConstraintError
|
38
136
|
# if +val+ doesn't match the constraint on +vid+ (if a
|
39
137
|
# constraint is registered for +vid+).
|
40
138
|
def []=(vid, val)
|
41
|
-
|
42
|
-
raise InvalidVidError, vid
|
43
|
-
end
|
139
|
+
vid = RantVar.valid_vid(vid)
|
44
140
|
c = @constraints[vid]
|
45
|
-
@store[vid]
|
141
|
+
if @store[vid] == @@env_ref
|
142
|
+
ENV[vid] = c ? c.filter(val) : val
|
143
|
+
else
|
144
|
+
@store[vid] = c ? c.filter(val) : val
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Use ENV instead of internal store for given vars.
|
149
|
+
# Probably useful for vars like CC, CFLAGS, etc.
|
150
|
+
def env *vars
|
151
|
+
vars.flatten.each { |var|
|
152
|
+
vid = RantVar.valid_vid(var)
|
153
|
+
cur_val = @store[vid]
|
154
|
+
next if cur_val == @@env_ref
|
155
|
+
ENV[vid] = cur_val unless cur_val.nil?
|
156
|
+
@store[vid] = @@env_ref
|
157
|
+
}
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
|
161
|
+
def set_all hash
|
162
|
+
unless Hash === hash
|
163
|
+
raise QueryError,
|
164
|
+
"set_all argument has to be a hash"
|
165
|
+
end
|
166
|
+
hash.each_pair { |k, v|
|
167
|
+
self[k] = v
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
171
|
+
def init_all hash
|
172
|
+
unless Hash === hash
|
173
|
+
raise QueryError,
|
174
|
+
"init_all argument has to be a hash"
|
175
|
+
end
|
176
|
+
hash.each_pair { |k, v|
|
177
|
+
self[k] = v if self[k].nil?
|
178
|
+
}
|
46
179
|
end
|
47
180
|
|
48
181
|
# Add +constraint+ for var with id +vid+.
|
49
182
|
def constrain vid, constraint
|
50
|
-
|
51
|
-
raise InvalidVidError, vid
|
52
|
-
end
|
183
|
+
vid = RantVar.valid_vid(vid)
|
53
184
|
unless RantVar.valid_constraint? constraint
|
54
185
|
raise InvalidConstraintError, constraint
|
55
186
|
end
|
56
187
|
@constraints[vid] = constraint
|
188
|
+
if @store.member? vid
|
189
|
+
begin
|
190
|
+
val = @store[vid]
|
191
|
+
@store[vid] = constraint.filter(@store[vid])
|
192
|
+
rescue
|
193
|
+
@store[vid] = constraint.default
|
194
|
+
raise ConstraintError.new(constraint, val)
|
195
|
+
end
|
196
|
+
else
|
197
|
+
@store[vid] = constraint.default
|
198
|
+
end
|
57
199
|
end
|
58
200
|
|
59
201
|
end # class Space
|
60
202
|
|
61
203
|
module Constraint
|
62
|
-
|
204
|
+
def matches? val
|
205
|
+
filter val
|
206
|
+
true
|
207
|
+
rescue
|
208
|
+
return false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
module Constraints
|
213
|
+
|
214
|
+
class Integer
|
215
|
+
include Constraint
|
216
|
+
|
217
|
+
def filter(val)
|
218
|
+
Kernel::Integer(val)
|
219
|
+
rescue
|
220
|
+
raise ConstraintError.new(self, val)
|
221
|
+
end
|
222
|
+
def default
|
223
|
+
0
|
224
|
+
end
|
225
|
+
def to_s
|
226
|
+
"integer"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class AutoList
|
231
|
+
include Constraint
|
232
|
+
|
233
|
+
def filter(val)
|
234
|
+
if val.respond_to? :to_ary
|
235
|
+
val.to_ary
|
236
|
+
elsif val.nil?
|
237
|
+
raise ConstraintError.new(self, val)
|
238
|
+
else
|
239
|
+
[val]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
def default
|
243
|
+
[]
|
244
|
+
end
|
245
|
+
def to_s
|
246
|
+
"list or single, non-nil value"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
class List
|
251
|
+
include Constraint
|
252
|
+
|
253
|
+
def filter(val)
|
254
|
+
if val.respond_to? :to_ary
|
255
|
+
val.to_ary
|
256
|
+
else
|
257
|
+
raise ConstraintError.new(self, val)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
def default
|
261
|
+
[]
|
262
|
+
end
|
263
|
+
def to_s
|
264
|
+
"list (Array)"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
Array = List
|
269
|
+
|
270
|
+
end # module Constraints
|
63
271
|
|
64
272
|
# A +vid+ has to be a String to be valid.
|
65
|
-
def valid_vid
|
66
|
-
|
273
|
+
def valid_vid(obj)
|
274
|
+
case obj
|
275
|
+
when String: obj
|
276
|
+
when Symbol: obj.to_s
|
277
|
+
else
|
278
|
+
if obj.respond_to? :to_str
|
279
|
+
obj.to_str
|
280
|
+
else
|
281
|
+
raise InvalidVidError.new(obj)
|
282
|
+
end
|
283
|
+
end
|
67
284
|
end
|
68
285
|
|
69
286
|
# A constraint has to respond to the following methods:
|
@@ -74,9 +291,11 @@ module Rant
|
|
74
291
|
# Return true if _val_ matches constraint.
|
75
292
|
def valid_constraint?(obj)
|
76
293
|
# TODO: check for arity
|
77
|
-
obj.respond_to?(:filter) &&
|
294
|
+
obj.respond_to?(:filter) &&
|
295
|
+
obj.respond_to?(:matches?) &&
|
296
|
+
obj.respond_to?(:default)
|
78
297
|
end
|
79
298
|
|
80
|
-
module_function :valid_constraint?, :valid_vid
|
299
|
+
module_function :valid_constraint?, :valid_vid
|
81
300
|
end # module RantVar
|
82
301
|
end # module Rant
|