rant 0.4.8 → 0.5.0

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.
Files changed (49) hide show
  1. data/NEWS +31 -0
  2. data/README +3 -1
  3. data/Rantfile +53 -2
  4. data/doc/advanced.rdoc +86 -1
  5. data/doc/c.rdoc +8 -0
  6. data/doc/homepage/index.html +2 -0
  7. data/doc/rant.1 +4 -0
  8. data/doc/rant.rdoc +38 -0
  9. data/doc/rant_vs_rake.rdoc +13 -0
  10. data/doc/rantfile.rdoc +93 -63
  11. data/doc/sys.rdoc +568 -0
  12. data/lib/rant/coregen.rb +43 -16
  13. data/lib/rant/import/command.rb +7 -4
  14. data/lib/rant/import/filelist/more.rb +57 -0
  15. data/lib/rant/import/metadata.rb +5 -1
  16. data/lib/rant/import/nodes/default.rb +3 -24
  17. data/lib/rant/import/signedfile.rb +1 -8
  18. data/lib/rant/import/sys/more.rb +2 -1
  19. data/lib/rant/import/var/booleans.rb +65 -0
  20. data/lib/rant/import/var/lists.rb +34 -0
  21. data/lib/rant/import/var/numbers.rb +116 -0
  22. data/lib/rant/import/var/strings.rb +43 -0
  23. data/lib/rant/import.rb +19 -3
  24. data/lib/rant/node.rb +39 -6
  25. data/lib/rant/rantlib.rb +44 -8
  26. data/lib/rant/rantsys.rb +22 -54
  27. data/lib/rant/rantvar.rb +89 -256
  28. data/misc/TODO +18 -0
  29. data/misc/devel-notes +26 -1
  30. data/test/action.rant +24 -0
  31. data/test/deprecated/test_0_5_4.rb +53 -0
  32. data/test/deprecated/test_0_6_0.rb +1 -1
  33. data/test/dryrun/Rantfile +10 -0
  34. data/test/dryrun/foo.c +8 -0
  35. data/test/dryrun/test_dryrun.rb +31 -0
  36. data/test/import/c/dependencies/Rantfile +1 -1
  37. data/test/import/command/Rantfile +1 -1
  38. data/test/import/sys/test_tgz.rb +22 -0
  39. data/test/subdirs2/root.rant +11 -1
  40. data/test/subdirs2/sub1/sub.rant +3 -0
  41. data/test/subdirs2/test_subdirs2.rb +19 -0
  42. data/test/test_action.rb +75 -0
  43. data/test/test_filelist.rb +13 -10
  44. data/test/test_rant_interface.rb +2 -2
  45. data/test/test_rule.rb +121 -3
  46. data/test/test_sys_methods.rb +558 -0
  47. data/test/test_var.rb +10 -0
  48. data/test/tutil.rb +81 -8
  49. metadata +19 -2
@@ -0,0 +1,57 @@
1
+
2
+ # more.rb - More Rant::FileList methods.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant
7
+ class FileList
8
+ # Remove all files which have the given name.
9
+ def no_file(name)
10
+ @actions << [:apply_ary_method, :reject!,
11
+ lambda { |entry|
12
+ entry == name && !@keep[entry] && test(?f, entry)
13
+ }]
14
+ @pending = true
15
+ self
16
+ end
17
+
18
+ # Remove all entries which contain an element
19
+ # with the given suffix.
20
+ def no_suffix(suffix)
21
+ @actions << [:no_suffix, suffix]
22
+ @pending = true
23
+ self
24
+ end
25
+
26
+ def apply_no_suffix(suffix)
27
+ elems = nil
28
+ elem = nil
29
+ @files.reject! { |entry|
30
+ elems = Sys.split_all(entry)
31
+ elems.any? { |elem|
32
+ elem =~ /#{suffix}$/ && !@keep[entry]
33
+ }
34
+ }
35
+ end
36
+ private :apply_no_suffix
37
+
38
+ # Remove all entries which contain an element
39
+ # with the given prefix.
40
+ def no_prefix(prefix)
41
+ @actions << [:no_prefix, prefix]
42
+ @pending = true
43
+ self
44
+ end
45
+
46
+ def apply_no_prefix(prefix)
47
+ elems = elem = nil
48
+ @files.reject! { |entry|
49
+ elems = Sys.split_all(entry)
50
+ elems.any? { |elem|
51
+ elem =~ /^#{prefix}/ && !@keep[entry]
52
+ }
53
+ }
54
+ end
55
+ private :apply_no_prefix
56
+ end # class FileList
57
+ end # module Rant
@@ -8,7 +8,7 @@ module Rant
8
8
  def self.init_import_metadata(rac, *rest)
9
9
  mi = MetaData::Interface.new(rac)
10
10
  rac.var._set("__metadata__", mi)
11
- rac.at_return(&mi.method(:save))
11
+ rac.at_return(&mi.method(:at_rant_return))
12
12
  rac.var._init("__autoclean_common__", []) << MetaData::META_FN
13
13
  end
14
14
 
@@ -105,6 +105,10 @@ module Rant
105
105
  set(key, value, fn, dir)
106
106
  end
107
107
 
108
+ def at_rant_return
109
+ save unless @rac[:dry_run]
110
+ end
111
+
108
112
  # Assumes to be called from the projects root directory.
109
113
  def save
110
114
  @modified_dirs.each_key { |dir|
@@ -43,11 +43,6 @@ module Rant
43
43
  @pre_resolved = false
44
44
  @block = block
45
45
  @run = false
46
- # success has one of three values:
47
- # nil no invoke
48
- # false invoked, but fail
49
- # true invoked and run successfully
50
- @success = nil
51
46
  @receiver = nil
52
47
  end
53
48
 
@@ -87,11 +82,6 @@ module Rant
87
82
  @success == false
88
83
  end
89
84
 
90
- # Task was run and didn't fail.
91
- def done?
92
- @success
93
- end
94
-
95
85
  # Enhance this task with the given dependencies and blk.
96
86
  def enhance(deps = nil, &blk)
97
87
  if deps
@@ -111,10 +101,6 @@ module Rant
111
101
  end
112
102
  end
113
103
 
114
- def needed?
115
- invoke(:needed? => true)
116
- end
117
-
118
104
  # Returns a true value if task was acutally run.
119
105
  # Raises Rant::TaskFail to signal task (or prerequiste) failure.
120
106
  def invoke(opt = INVOKE_OPT)
@@ -319,11 +305,6 @@ module Rant
319
305
  true
320
306
  end
321
307
 
322
- def needed?
323
- return false if done?
324
- invoke(:needed? => true)
325
- end
326
-
327
308
  def invoke(opt = INVOKE_OPT)
328
309
  return circular_dep if @run
329
310
  @run = true
@@ -384,7 +365,7 @@ module Rant
384
365
  private
385
366
  def run
386
367
  goto_task_home
387
- @rac.running_task(self)
368
+ return if @rac.running_task(self)
388
369
  dir = File.dirname(name)
389
370
  @rac.build dir unless dir == "." || dir == "/"
390
371
  return unless @block
@@ -457,7 +438,7 @@ module Rant
457
438
  end
458
439
 
459
440
  def run
460
- @rac.running_task(self)
441
+ return if @rac.running_task(self)
461
442
  @rac.sys.mkdir @name unless @isdir
462
443
  if @block
463
444
  @block.arity == 0 ? @block.call : @block[self]
@@ -537,10 +518,8 @@ module Rant
537
518
  }
538
519
  @ts
539
520
  end
540
- def needed?
541
- false
542
- end
543
521
  def invoke(opt = INVOKE_OPT)
522
+ # self.timestamp would be required for correctness...
544
523
  false
545
524
  end
546
525
  def related_sources
@@ -31,7 +31,6 @@ module Rant
31
31
  raise ArgumentError, "prerequisites required"
32
32
  @block = block
33
33
  @run = false
34
- @success = nil
35
34
  @receiver = nil
36
35
  end
37
36
  def prerequisites
@@ -57,9 +56,6 @@ module Rant
57
56
  def fail?
58
57
  @success == false
59
58
  end
60
- def done?
61
- @success
62
- end
63
59
  def enhance(deps = nil, &blk)
64
60
  @pre.concat(deps) if deps
65
61
  if @block
@@ -74,9 +70,6 @@ module Rant
74
70
  @block = blk
75
71
  end
76
72
  end
77
- def needed?
78
- invoke(:needed? => true)
79
- end
80
73
  def invoke(opt = INVOKE_OPT)
81
74
  return circular_dep if @run
82
75
  @run = true
@@ -226,7 +219,7 @@ module Rant
226
219
  end
227
220
  private
228
221
  def run
229
- @rac.running_task(self)
222
+ return if @rac.running_task(self)
230
223
  @rac.cx.sys.mkdir @name unless test ?d, @name
231
224
  if @block
232
225
  @block.arity == 0 ? @block.call : @block[self]
@@ -6,8 +6,9 @@
6
6
  module Rant
7
7
  module Sys
8
8
  def write_to_file(fn, content)
9
+ content = content.to_str
9
10
  fu_output_message "writing #{content.size} bytes to file `#{fn}'"
10
- open fn, "w" do |f|
11
+ File.open fn, "w" do |f|
11
12
  f.write content
12
13
  end
13
14
  end
@@ -0,0 +1,65 @@
1
+
2
+ # booleans.rb - Constraints for Rantfile boolean variables.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant
7
+ module RantVar
8
+ module Constraints
9
+ class Bool
10
+ include Constraint
11
+ class << self
12
+ alias rant_constraint new
13
+ end
14
+ def filter(val)
15
+ if ::Symbol === val or ::Integer === val
16
+ val = val.to_s
17
+ end
18
+ if val == true
19
+ true
20
+ elsif val == false || val == nil
21
+ false
22
+ elsif val.respond_to? :to_str
23
+ case val.to_str
24
+ when /^\s*true\s*$/i: true
25
+ when /^\s*false\s*$/i: false
26
+ when /^\s*y(es)?\s*$/i: true
27
+ when /^\s*n(o)?\s*$/: false
28
+ when /^\s*on\s*$/i: true
29
+ when /^\s*off\s*$/i: false
30
+ when /^\s*1\s*$/: true
31
+ when /^\s*0\s*$/: false
32
+ else
33
+ raise ConstraintError.new(self, val)
34
+ end
35
+ else
36
+ raise ConstraintError.new(self, val)
37
+ end
38
+ end
39
+ def default
40
+ false
41
+ end
42
+ def to_s
43
+ "bool"
44
+ end
45
+ end
46
+
47
+ class BoolTrue < Bool
48
+ def default
49
+ true
50
+ end
51
+ end
52
+
53
+ #--
54
+ # perhaps this should stay a secret ;)
55
+ #++
56
+ def true.rant_constraint
57
+ BoolTrue.rant_constraint
58
+ end
59
+ def false.rant_constraint
60
+ Bool.rant_constraint
61
+ end
62
+
63
+ end # module Constraints
64
+ end # module RantVar
65
+ end # module Rant
@@ -0,0 +1,34 @@
1
+
2
+ # lists.rb - Constraints for Rantfile list variables.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant
7
+ module RantVar
8
+ module Constraints
9
+ class List
10
+ include Constraint
11
+
12
+ class << self
13
+ alias rant_constraint new
14
+ end
15
+
16
+ def filter(val)
17
+ if val.respond_to? :to_ary
18
+ val.to_ary
19
+ else
20
+ raise ConstraintError.new(self, val)
21
+ end
22
+ end
23
+ def default
24
+ []
25
+ end
26
+ def to_s
27
+ "list (Array)"
28
+ end
29
+ end
30
+
31
+ Array = List
32
+ end # module Constraints
33
+ end # module RantVar
34
+ end # module Rant
@@ -0,0 +1,116 @@
1
+
2
+ # numbers.rb - Constraints for numeric Rantfile variables.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant
7
+ module RantVar
8
+ module Constraints
9
+
10
+ class Integer
11
+ include Constraint
12
+
13
+ class << self
14
+ def rant_constraint(range = nil)
15
+ if range
16
+ IntegerInRange.new(range)
17
+ else
18
+ self.new
19
+ end
20
+ end
21
+ end
22
+
23
+ def filter(val)
24
+ Kernel::Integer(val)
25
+ rescue
26
+ raise ConstraintError.new(self, val)
27
+ end
28
+ def default
29
+ 0
30
+ end
31
+ def to_s
32
+ "integer"
33
+ end
34
+ end
35
+
36
+ class IntegerInRange < Integer
37
+ def initialize(range)
38
+ @range = range
39
+ end
40
+ def filter(val)
41
+ i = super
42
+ if @range === i
43
+ i
44
+ else
45
+ raise ConstraintError.new(self, val)
46
+ end
47
+ end
48
+ def default
49
+ @range.min
50
+ end
51
+ def to_s
52
+ super + " #{@range}"
53
+ end
54
+ end
55
+
56
+ class Float
57
+ include Constraint
58
+
59
+ class << self
60
+ def rant_constraint(range = nil)
61
+ if range
62
+ FloatInRange.new(range)
63
+ else
64
+ self.new
65
+ end
66
+ end
67
+ end
68
+
69
+ def filter(val)
70
+ Kernel::Float(val)
71
+ rescue
72
+ raise ConstraintError.new(self, val)
73
+ end
74
+ def default
75
+ 0.0
76
+ end
77
+ def to_s
78
+ "float"
79
+ end
80
+ end
81
+
82
+ class FloatInRange < Float
83
+ def initialize(range)
84
+ @range = range
85
+ end
86
+ def filter(val)
87
+ i = super
88
+ if @range === i
89
+ i
90
+ else
91
+ raise ConstraintError.new(self, val)
92
+ end
93
+ end
94
+ def default
95
+ @range.first
96
+ end
97
+ def to_s
98
+ super + " #{@range}"
99
+ end
100
+ end
101
+ end # module Constraints
102
+ end # module RantVar
103
+ end # module Rant
104
+
105
+ class Range
106
+ def rant_constraint
107
+ case first
108
+ when ::Integer
109
+ Rant::RantVar::Constraints::IntegerInRange.new(self)
110
+ when ::Float
111
+ Rant::RantVar::Constraints::FloatInRange.new(self)
112
+ else
113
+ raise NotAConstraintFactoryError.new(self)
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,43 @@
1
+
2
+ # strings.rb - Constraints for Rantfile string variables.
3
+ #
4
+ # Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
5
+
6
+ module Rant
7
+ module RantVar
8
+ module Constraints
9
+ class String
10
+ include Constraint
11
+
12
+ class << self
13
+ alias rant_constraint new
14
+ end
15
+
16
+ def filter(val)
17
+ if val.respond_to? :to_str
18
+ val.to_str
19
+ elsif Symbol === val
20
+ val.to_s
21
+ else
22
+ raise ConstraintError.new(self, val)
23
+ end
24
+ end
25
+ def default
26
+ ""
27
+ end
28
+ def to_s
29
+ "string"
30
+ end
31
+ end
32
+
33
+ class ToString < String
34
+ class << self
35
+ alias rant_constraint new
36
+ end
37
+ def filter(val)
38
+ val.to_s
39
+ end
40
+ end
41
+ end # module Constraints
42
+ end # module RantVar
43
+ end # module Rant
data/lib/rant/import.rb CHANGED
@@ -218,7 +218,12 @@ EOF
218
218
  cmd_opts.quiet = true
219
219
  cmd_opts.each { |opt, value|
220
220
  case opt
221
- when "--version", "-v":
221
+ when "--version":
222
+ puts "rant-import #{Rant::VERSION}"
223
+ done
224
+ when "-v":
225
+ warn_msg "Option `-v' is deprecated and won't be in",
226
+ "release 0.6.0. Use `-V' or `--version' instead!."
222
227
  puts "rant-import #{Rant::VERSION}"
223
228
  done
224
229
  when "--help": help
@@ -436,10 +441,20 @@ EOF
436
441
  # Note:: The comment with the module name in line 3 of the
437
442
  # input is very important.
438
443
  def filter_reopen_module(script)
444
+ loop {
445
+ script, done = filter_reopen_module_onepass(script)
446
+ break(script) if done
447
+ }
448
+ end
449
+
450
+ # Returns true as second return value if at no useless
451
+ # statement was removed.
452
+ def filter_reopen_module_onepass(script)
439
453
  lines = []
440
454
  buffer = []
441
455
  identifier = nil # class/module name
442
- keyword = nil # class or module
456
+ keyword = nil # `class' or `module'
457
+ done = true
443
458
  script.split(/\n/).each { |line|
444
459
  if identifier
445
460
  if line.strip.empty?
@@ -449,6 +464,7 @@ EOF
449
464
  lines << ""
450
465
  buffer.clear
451
466
  identifier = keyword = nil
467
+ done = false
452
468
  else
453
469
  lines.concat buffer
454
470
  buffer.clear
@@ -463,7 +479,7 @@ EOF
463
479
  lines << line
464
480
  end
465
481
  }
466
- lines.join("\n") << "\n"
482
+ [lines.join("\n") << "\n", done]
467
483
  end
468
484
 
469
485
  end # class RantImport
data/lib/rant/node.rb CHANGED
@@ -73,6 +73,11 @@ module Rant
73
73
  @line_number = nil
74
74
  @run = false
75
75
  @project_subdir = ""
76
+ # success has one of three values:
77
+ # nil no invoke
78
+ # false invoked, but fail
79
+ # true invoked and run successfully
80
+ @success = nil
76
81
  end
77
82
 
78
83
  def reference_name
@@ -113,12 +118,13 @@ module Rant
113
118
  false
114
119
  end
115
120
 
121
+ # Task was run and didn't fail.
116
122
  def done?
117
- @done
123
+ @success
118
124
  end
119
125
 
120
126
  def needed?
121
- !done?
127
+ invoke(:needed? => true)
122
128
  end
123
129
 
124
130
  # True during invoke. Used to encounter circular dependencies.
@@ -139,8 +145,11 @@ module Rant
139
145
  return circular_dep if run?
140
146
  @run = true
141
147
  begin
142
- return needed? if opt[:needed?]
143
- self.run if opt[:force] || self.needed?
148
+ return !done? if opt[:needed?]
149
+ # we don't need to check for opt[:force] here
150
+ # since a plain Node is run anyway.
151
+ self.run if !done?
152
+ @success = true
144
153
  ensure
145
154
  @run = false
146
155
  end
@@ -163,15 +172,39 @@ module Rant
163
172
  defined? @block and @block
164
173
  end
165
174
 
175
+ def dry_run
176
+ text = "Executing #{name.dump}"
177
+ text << " [NOOP]" unless has_actions?
178
+ @rac.cmd_msg text
179
+ action_descs.each { |ad|
180
+ @rac.cmd_print " - "
181
+ @rac.cmd_msg ad.sub(/\n$/, '').gsub(/\n/, "\n ")
182
+ }
183
+ end
184
+
166
185
  private
167
186
  def run
168
- return unless has_actions?
169
187
  goto_task_home
170
- @rac.running_task(self)
188
+ return if @rac.running_task(self)
189
+ return unless has_actions?
171
190
  @receiver.pre_run(self) if defined? @receiver and @receiver
172
191
  @block.arity == 0 ? @block.call : @block[self] if @block
173
192
  end
174
193
 
194
+ def action_descs
195
+ descs = []
196
+ if defined? @receiver and @receiver
197
+ descs.concat(@receiver.pre_action_descs)
198
+ end
199
+ @block ? descs << action_block_desc : descs
200
+ end
201
+
202
+ def action_block_desc
203
+ @block.inspect =~ /^#<Proc:[\da-z]+@(.+):(\d+)>$/i
204
+ fn, ln = $1, $2
205
+ "Ruby Proc at #{fn.sub(/^#{Regexp.escape @rac.rootdir}\//, '')}:#{ln}"
206
+ end
207
+
175
208
  def circular_dep
176
209
  rac.warn_msg "Circular dependency on task `#{full_name}'."
177
210
  false