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/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
- attr_reader :actions, :files
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
- =begin
274
- def arglist
275
- self.list.join(' ')
276
- end
277
-
278
- def list
279
- if ::Rant::Env.on_windows?
280
- self.collect { |entry|
281
- entry = entry.tr("/", "\\")
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
- end # class FileList
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.rantapp.cmd_msg msg if ::Rant.rantapp
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
- # This could be an Rant application. It has to respond to
400
- # +:cmd_msg+.
401
- attr_reader :controller
433
+ # The controlling Rant compiler.
434
+ attr_reader :rac
402
435
 
403
- def initialize(controller)
404
- @controller = controller or
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
- @controller.cmd_msg cmd
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 < StandardError
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
- unless RantVar.valid_vid? vid
32
- raise InvalidVidError, vid
33
- end
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
- unless RantVar.valid_vid? vid
42
- raise InvalidVidError, vid
43
- end
139
+ vid = RantVar.valid_vid(vid)
44
140
  c = @constraints[vid]
45
- @store[vid] = c ? c.filter(val) : val
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
- unless RantVar.valid_vid? vid
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
- end # module Constraint
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?(obj)
66
- String === obj
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) && obj.respond_to?(:matches?)
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