rant 0.3.4 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +13 -0
- data/README +1 -1
- data/Rantfile +24 -16
- data/doc/advanced.rdoc +188 -0
- data/doc/examples/directedrule/Rantfile +23 -0
- data/doc/examples/directedrule/src_a/a_1.c +0 -0
- data/doc/examples/directedrule/src_a/a_2.c +5 -0
- data/doc/examples/directedrule/src_b/b_1.c +0 -0
- data/doc/jamis.rb +590 -0
- data/doc/rantfile.rdoc +29 -9
- data/lib/rant/import.rb +19 -9
- data/lib/rant/import/autoclean.rb +65 -0
- data/lib/rant/import/clean.rb +45 -0
- data/lib/rant/import/directedrule.rb +122 -0
- data/lib/rant/import/package.rb +258 -0
- data/lib/rant/import/rubydoc.rb +5 -0
- data/lib/rant/import/rubypackage.rb +1 -1
- data/lib/rant/import/truth.rb +24 -0
- data/lib/rant/plugin/configure.rb +1 -0
- data/lib/rant/rantfile.rb +77 -26
- data/lib/rant/rantlib.rb +116 -21
- data/lib/rant/rantsys.rb +92 -4
- data/lib/rant/rantvar.rb +252 -11
- data/rantmethods.rb +2 -2
- data/test/Rantfile +35 -1
- data/test/import/directedrule/Rantfile +27 -0
- data/test/import/directedrule/test_directedrule.rb +31 -0
- data/test/import/truth/Rantfile +16 -0
- data/test/import/truth/test_truth.rb +23 -0
- data/test/rant-import/Rantfile +15 -0
- data/test/rant-import/test_rant-import.rb +65 -0
- data/test/test_clean.rb +134 -0
- data/test/test_examples.rb +47 -0
- data/test/test_filelist.rb +58 -0
- data/test/test_rac.rb +59 -0
- data/test/test_rantfile_api.rb +47 -0
- data/test/test_var.rb +176 -0
- data/test/tutil.rb +18 -2
- data/test/var.rf +23 -0
- metadata +29 -2
data/lib/rant/rantsys.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
|
2
|
+
# rantsys.rb - Support for the +sys+ method/object.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
5
|
+
|
2
6
|
require 'fileutils'
|
3
7
|
require 'rant/rantenv'
|
4
8
|
|
@@ -65,7 +69,7 @@ module Rant
|
|
65
69
|
case other
|
66
70
|
when Array
|
67
71
|
dup.files.concat(other)
|
68
|
-
when
|
72
|
+
when FileList
|
69
73
|
c = other.dup
|
70
74
|
c.actions.concat(@actions)
|
71
75
|
c.files.concat(@files)
|
@@ -97,8 +101,9 @@ module Rant
|
|
97
101
|
if @files.respond_to? sym
|
98
102
|
resolve if @pending
|
99
103
|
fh = @files.hash
|
100
|
-
@files.send(sym, *args, &block)
|
104
|
+
rv = @files.send(sym, *args, &block)
|
101
105
|
@pending = true unless @files.hash == fh
|
106
|
+
rv.equal?(@files) ? self : rv
|
102
107
|
else
|
103
108
|
super
|
104
109
|
end
|
@@ -118,7 +123,7 @@ module Rant
|
|
118
123
|
end
|
119
124
|
|
120
125
|
def include(*patterns)
|
121
|
-
patterns.each { |pat|
|
126
|
+
patterns.flatten.each { |pat|
|
122
127
|
@actions << [:apply_include, pat]
|
123
128
|
}
|
124
129
|
@pending = true
|
@@ -201,6 +206,17 @@ module Rant
|
|
201
206
|
end
|
202
207
|
private :mk_all_rx
|
203
208
|
|
209
|
+
def select &block
|
210
|
+
d = dup
|
211
|
+
d.actions << [:apply_select, block]
|
212
|
+
d
|
213
|
+
end
|
214
|
+
|
215
|
+
def apply_select blk
|
216
|
+
@files = @files.select &blk
|
217
|
+
end
|
218
|
+
private :apply_select
|
219
|
+
|
204
220
|
# Remove all entries which contain a directory with the
|
205
221
|
# given name.
|
206
222
|
# If no argument or +nil+ given, remove all directories.
|
@@ -307,8 +323,13 @@ module Rant
|
|
307
323
|
|
308
324
|
class RacFileList < FileList
|
309
325
|
|
326
|
+
attr_reader :subdir
|
327
|
+
attr_reader :basedir
|
328
|
+
|
310
329
|
def initialize(rac, *patterns)
|
311
330
|
@rac = rac
|
331
|
+
@subdir = @rac.current_subdir
|
332
|
+
@basedir = Dir.pwd
|
312
333
|
super(*patterns)
|
313
334
|
@ignore_hash = nil
|
314
335
|
update_ignore_rx
|
@@ -321,6 +342,21 @@ module Rant
|
|
321
342
|
@ignore_rx
|
322
343
|
end
|
323
344
|
|
345
|
+
alias filelist_resolve resolve
|
346
|
+
def resolve
|
347
|
+
Dir.chdir(@basedir) { filelist_resolve }
|
348
|
+
end
|
349
|
+
|
350
|
+
def each &block
|
351
|
+
old_pwd = Dir.pwd
|
352
|
+
resolve if @pending
|
353
|
+
Dir.chdir(@basedir)
|
354
|
+
filelist_resolve
|
355
|
+
@files.each(&block)
|
356
|
+
ensure
|
357
|
+
Dir.chdir(old_pwd)
|
358
|
+
end
|
359
|
+
|
324
360
|
private
|
325
361
|
def update_ignore_rx
|
326
362
|
ri = @rac.var[:ignore]
|
@@ -331,7 +367,44 @@ module Rant
|
|
331
367
|
@ignore_hash = rh
|
332
368
|
end
|
333
369
|
end
|
334
|
-
end
|
370
|
+
end # class RacFileList
|
371
|
+
|
372
|
+
class MultiFileList
|
373
|
+
|
374
|
+
attr_reader :cur_list
|
375
|
+
|
376
|
+
def initialize(rac)
|
377
|
+
@rac = rac
|
378
|
+
@cur_list = RacFileList.new(@rac)
|
379
|
+
@lists = [@cur_list]
|
380
|
+
end
|
381
|
+
|
382
|
+
def each_entry &block
|
383
|
+
@lists.each { |list|
|
384
|
+
list.each &block
|
385
|
+
}
|
386
|
+
end
|
387
|
+
|
388
|
+
def add(filelist)
|
389
|
+
# TODO: validate filelist
|
390
|
+
@cur_list = filelist
|
391
|
+
@lists << filelist
|
392
|
+
self
|
393
|
+
end
|
394
|
+
|
395
|
+
def method_missing(sym, *args, &block)
|
396
|
+
if @cur_list && @cur_list.respond_to?(sym)
|
397
|
+
if @cur_list.subdir == @rac.current_subdir
|
398
|
+
@cur_list.send(sym, *args, &block)
|
399
|
+
else
|
400
|
+
add(RacFileList.new(@rac))
|
401
|
+
@cur_list.send(sym, *args, &block)
|
402
|
+
end
|
403
|
+
else
|
404
|
+
super
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end # class MultiFileList
|
335
408
|
|
336
409
|
class CommandError < StandardError
|
337
410
|
attr_reader :cmd
|
@@ -375,6 +448,13 @@ module Rant
|
|
375
448
|
::Rant.rac.cmd_msg msg if ::Rant.rac
|
376
449
|
end
|
377
450
|
|
451
|
+
# Run an external command. When given one argument, this is
|
452
|
+
# subject to shell interpretation. Otherwise the first
|
453
|
+
# argument is the program to run, following arguments are
|
454
|
+
# given as arguments to the program.
|
455
|
+
#
|
456
|
+
# Note: This method is called on +sys <some_string>+
|
457
|
+
# invocation in an Rantfile.
|
378
458
|
def sh(*cmd_args, &block)
|
379
459
|
cmd_args.flatten!
|
380
460
|
cmd = cmd_args.join(" ")
|
@@ -386,6 +466,8 @@ module Rant
|
|
386
466
|
end
|
387
467
|
end
|
388
468
|
|
469
|
+
# Run a new Ruby interpreter with the given arguments:
|
470
|
+
# sys.ruby "install.rb"
|
389
471
|
def ruby(*args, &block)
|
390
472
|
if args.size > 1
|
391
473
|
sh([Env::RUBY] + args, &block)
|
@@ -427,6 +509,11 @@ module Rant
|
|
427
509
|
|
428
510
|
end # module Sys
|
429
511
|
|
512
|
+
# An instance of this class is returned from the +sys+ method in
|
513
|
+
# Rantfiles (when called without arguments).
|
514
|
+
# sys.rm_rf "tmp"
|
515
|
+
# In this (Rantfile) example, the +rm_rf+ message is sent to an
|
516
|
+
# instance of this class.
|
430
517
|
class SysObject
|
431
518
|
include Sys
|
432
519
|
|
@@ -449,6 +536,7 @@ module Rant
|
|
449
536
|
end
|
450
537
|
|
451
538
|
private
|
539
|
+
# Delegates FileUtils messages to +rac+.
|
452
540
|
def fu_output_message(cmd)
|
453
541
|
@rac.cmd_msg cmd
|
454
542
|
end
|
data/lib/rant/rantvar.rb
CHANGED
@@ -10,8 +10,13 @@
|
|
10
10
|
# This file provides support for the +var+ attribute of the Rant
|
11
11
|
# application (Rant::RantApp#var).
|
12
12
|
|
13
|
+
# Most constants (classes, modules etc.) of Rant live in this module,
|
14
|
+
# thus it acts as a namespace.
|
15
|
+
#
|
16
|
+
# If you're looking for general info about Rant, read the
|
17
|
+
# README[link:files/README.html].
|
13
18
|
module Rant
|
14
|
-
VERSION = '0.3.
|
19
|
+
VERSION = '0.3.6'
|
15
20
|
|
16
21
|
# Those are the filenames for rantfiles.
|
17
22
|
# Case matters!
|
@@ -67,6 +72,20 @@ module Rant
|
|
67
72
|
end
|
68
73
|
end
|
69
74
|
|
75
|
+
class NotAConstraintFactoryError < Error
|
76
|
+
attr_reader :obj
|
77
|
+
def initialize(obj, msg = nil)
|
78
|
+
@msg = msg
|
79
|
+
@obj = obj
|
80
|
+
end
|
81
|
+
def message
|
82
|
+
# TODO: handle @msg
|
83
|
+
obj_desc = @obj.inspect
|
84
|
+
obj_desc[7..-1] = "..." if obj_desc.length > 10
|
85
|
+
"#{obj_desc} is not a valid constraint factory"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
70
89
|
class InvalidVidError < Error
|
71
90
|
def initialize(vid, msg = nil)
|
72
91
|
@msg = msg
|
@@ -95,6 +114,8 @@ module Rant
|
|
95
114
|
@store = {}
|
96
115
|
# holds constraints for values in @store
|
97
116
|
@constraints = {}
|
117
|
+
# set by default query
|
118
|
+
@current_var = nil
|
98
119
|
end
|
99
120
|
|
100
121
|
def query(*args, &block)
|
@@ -105,25 +126,57 @@ module Rant
|
|
105
126
|
when 1
|
106
127
|
arg = args.first
|
107
128
|
if Hash === arg
|
108
|
-
|
129
|
+
if arg.size == 1
|
130
|
+
arg.each { |k,v|
|
131
|
+
@current_var = k
|
132
|
+
self[k] = v if self[k].nil?
|
133
|
+
}
|
134
|
+
self
|
135
|
+
else
|
136
|
+
init_all arg
|
137
|
+
end
|
109
138
|
else
|
110
139
|
self[arg]
|
111
140
|
end
|
112
141
|
when 2..3
|
113
|
-
|
142
|
+
@current_var, cf, val = *args
|
143
|
+
self.is cf
|
144
|
+
self[@current_var] = val if val
|
145
|
+
else
|
146
|
+
raise QueryError, "to many arguments"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def is ct, *ct_args
|
151
|
+
constrain @current_var,
|
152
|
+
get_factory(ct).rant_constraint(*ct_args)
|
153
|
+
self
|
154
|
+
end
|
155
|
+
|
156
|
+
def restrict vid, ct, *ct_args
|
157
|
+
if vid.respond_to? :to_ary
|
158
|
+
vid.to_ary.each { |v| restrict(v, ct, *ct_args) }
|
159
|
+
else
|
160
|
+
constrain vid,
|
161
|
+
get_factory(ct).rant_constraint(*ct_args)
|
162
|
+
end
|
163
|
+
self
|
164
|
+
end
|
165
|
+
|
166
|
+
def get_factory id
|
167
|
+
if String === id || Symbol === id
|
114
168
|
begin
|
115
|
-
|
116
|
-
Constraints.const_get(constraint).new
|
169
|
+
id = Constraints.const_get(id)
|
117
170
|
rescue
|
118
|
-
raise
|
119
|
-
"no such constraint: #{constraint}", caller
|
171
|
+
raise NotAConstraintFactoryError.new(ct), caller
|
120
172
|
end
|
121
|
-
constrain vid, constraint
|
122
|
-
self[vid] = val if val
|
123
|
-
else
|
124
|
-
raise QueryError, "to many arguments"
|
125
173
|
end
|
174
|
+
unless id.respond_to? :rant_constraint
|
175
|
+
raise NotAConstraintFactoryError.new(id), caller
|
176
|
+
end
|
177
|
+
id
|
126
178
|
end
|
179
|
+
private :get_factory
|
127
180
|
|
128
181
|
# Get var with name +vid+.
|
129
182
|
def [](vid)
|
@@ -198,6 +251,10 @@ module Rant
|
|
198
251
|
end
|
199
252
|
end
|
200
253
|
|
254
|
+
def has_var?(vid)
|
255
|
+
!self[vid].nil?
|
256
|
+
end
|
257
|
+
|
201
258
|
end # class Space
|
202
259
|
|
203
260
|
module Constraint
|
@@ -211,9 +268,65 @@ module Rant
|
|
211
268
|
|
212
269
|
module Constraints
|
213
270
|
|
271
|
+
class String
|
272
|
+
include Constraint
|
273
|
+
|
274
|
+
class << self
|
275
|
+
alias rant_constraint new
|
276
|
+
end
|
277
|
+
|
278
|
+
def filter(val)
|
279
|
+
if val.respond_to? :to_str
|
280
|
+
val.to_str
|
281
|
+
elsif Symbol === val
|
282
|
+
val.to_s
|
283
|
+
else
|
284
|
+
raise ConstraintError.new(self, val)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
def default
|
288
|
+
""
|
289
|
+
end
|
290
|
+
def to_s
|
291
|
+
"string"
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
class ToString < String
|
296
|
+
class << self
|
297
|
+
alias rant_constraint new
|
298
|
+
end
|
299
|
+
def filter(val)
|
300
|
+
val.to_s
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class ::Range
|
305
|
+
def rant_constraint
|
306
|
+
case first
|
307
|
+
when ::Integer
|
308
|
+
IntegerInRange.new(self)
|
309
|
+
when ::Float
|
310
|
+
FloatInRange.new(self)
|
311
|
+
else
|
312
|
+
raise NotAConstraintFactoryError.new(self)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
214
317
|
class Integer
|
215
318
|
include Constraint
|
216
319
|
|
320
|
+
class << self
|
321
|
+
def rant_constraint(range = nil)
|
322
|
+
if range
|
323
|
+
IntegerInRange.new(range)
|
324
|
+
else
|
325
|
+
self.new
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
217
330
|
def filter(val)
|
218
331
|
Kernel::Integer(val)
|
219
332
|
rescue
|
@@ -227,9 +340,79 @@ module Rant
|
|
227
340
|
end
|
228
341
|
end
|
229
342
|
|
343
|
+
class IntegerInRange < Integer
|
344
|
+
def initialize(range)
|
345
|
+
@range = range
|
346
|
+
end
|
347
|
+
def filter(val)
|
348
|
+
i = super
|
349
|
+
if @range === i
|
350
|
+
i
|
351
|
+
else
|
352
|
+
raise ConstraintError.new(self, val)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
def default
|
356
|
+
@range.min
|
357
|
+
end
|
358
|
+
def to_s
|
359
|
+
super + " #{@range}"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
class Float
|
364
|
+
include Constraint
|
365
|
+
|
366
|
+
class << self
|
367
|
+
def rant_constraint(range = nil)
|
368
|
+
if range
|
369
|
+
FloatInRange.new(range)
|
370
|
+
else
|
371
|
+
self.new
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def filter(val)
|
377
|
+
Kernel::Float(val)
|
378
|
+
rescue
|
379
|
+
raise ConstraintError.new(self, val)
|
380
|
+
end
|
381
|
+
def default
|
382
|
+
0.0
|
383
|
+
end
|
384
|
+
def to_s
|
385
|
+
"float"
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
class FloatInRange < Float
|
390
|
+
def initialize(range)
|
391
|
+
@range = range
|
392
|
+
end
|
393
|
+
def filter(val)
|
394
|
+
i = super
|
395
|
+
if @range === i
|
396
|
+
i
|
397
|
+
else
|
398
|
+
raise ConstraintError.new(self, val)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
def default
|
402
|
+
@range.first
|
403
|
+
end
|
404
|
+
def to_s
|
405
|
+
super + " #{@range}"
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
230
409
|
class AutoList
|
231
410
|
include Constraint
|
232
411
|
|
412
|
+
class << self
|
413
|
+
alias rant_constraint new
|
414
|
+
end
|
415
|
+
|
233
416
|
def filter(val)
|
234
417
|
if val.respond_to? :to_ary
|
235
418
|
val.to_ary
|
@@ -250,6 +433,10 @@ module Rant
|
|
250
433
|
class List
|
251
434
|
include Constraint
|
252
435
|
|
436
|
+
class << self
|
437
|
+
alias rant_constraint new
|
438
|
+
end
|
439
|
+
|
253
440
|
def filter(val)
|
254
441
|
if val.respond_to? :to_ary
|
255
442
|
val.to_ary
|
@@ -267,6 +454,60 @@ module Rant
|
|
267
454
|
|
268
455
|
Array = List
|
269
456
|
|
457
|
+
class Bool
|
458
|
+
include Constraint
|
459
|
+
class << self
|
460
|
+
alias rant_constraint new
|
461
|
+
end
|
462
|
+
def filter(val)
|
463
|
+
if ::Symbol === val or ::Integer === val
|
464
|
+
val = val.to_s
|
465
|
+
end
|
466
|
+
if val == true
|
467
|
+
true
|
468
|
+
elsif val == false || val == nil
|
469
|
+
false
|
470
|
+
elsif val.respond_to? :to_str
|
471
|
+
case val.to_str
|
472
|
+
when /^\s*true\s*$/i: true
|
473
|
+
when /^\s*false\s*$/i: false
|
474
|
+
when /^\s*y(es)?\s*$/i: true
|
475
|
+
when /^\s*n(o)?\s*$/: false
|
476
|
+
when /^\s*on\s*$/i: true
|
477
|
+
when /^\s*off\s*$/i: false
|
478
|
+
when /^\s*1\s*$/: true
|
479
|
+
when /^\s*0\s*$/: false
|
480
|
+
else
|
481
|
+
raise ConstraintError.new(self, val)
|
482
|
+
end
|
483
|
+
else
|
484
|
+
raise ConstraintError.new(self, val)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
def default
|
488
|
+
false
|
489
|
+
end
|
490
|
+
def to_s
|
491
|
+
"bool"
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
class BoolTrue < Bool
|
496
|
+
def default
|
497
|
+
true
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
#--
|
502
|
+
# perhaps this should stay a secret ;)
|
503
|
+
#++
|
504
|
+
def true.rant_constraint
|
505
|
+
BoolTrue.rant_constraint
|
506
|
+
end
|
507
|
+
def false.rant_constraint
|
508
|
+
Bool.rant_constraint
|
509
|
+
end
|
510
|
+
|
270
511
|
end # module Constraints
|
271
512
|
|
272
513
|
# A +vid+ has to be a String to be valid.
|