rant 0.3.2 → 0.3.4
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 +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
|