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/import/rubydoc.rb
CHANGED
@@ -55,6 +55,11 @@ module Rant
|
|
55
55
|
# define task task with given name first, so that it takes
|
56
56
|
# any previously set description
|
57
57
|
t = app.task(:__caller__ => ch, @name => [])
|
58
|
+
t.instance_variable_set(:@rdoc_op_dir, @op_dir)
|
59
|
+
def t.each_target
|
60
|
+
super
|
61
|
+
yield @rdoc_op_dir if @rdoc_op_dir
|
62
|
+
end
|
58
63
|
# The task which will actually run rdoc.
|
59
64
|
t << app.file(:__caller__ => ch, index => @pre) { |t|
|
60
65
|
# We delay the require of the RDoc code until it is
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
#--
|
3
|
+
# truth.rb - Import truth into rant ;)
|
4
|
+
#
|
5
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
6
|
+
|
7
|
+
module Rant
|
8
|
+
module Worker
|
9
|
+
def %(desc)
|
10
|
+
@description = case @description
|
11
|
+
when nil: desc
|
12
|
+
when /\n$/: @description + desc
|
13
|
+
else "#@description\n#{desc}"
|
14
|
+
end
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
module RantContext
|
20
|
+
def drag(name, *args, &block)
|
21
|
+
import(name.to_s.downcase)
|
22
|
+
gen(::Rant::Generators.const_get(name), *args, &block)
|
23
|
+
end
|
24
|
+
end
|
data/lib/rant/rantfile.rb
CHANGED
@@ -1,11 +1,16 @@
|
|
1
1
|
|
2
|
+
# rantfile.rb - Define task core for rant.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
5
|
+
|
2
6
|
require 'rant/rantenv'
|
3
7
|
|
4
8
|
module Rant
|
5
9
|
class TaskFail < StandardError
|
6
10
|
def initialize(*args)
|
7
11
|
@task = args.shift
|
8
|
-
super(args.shift)
|
12
|
+
#super(args.shift)
|
13
|
+
@orig = args.shift
|
9
14
|
end
|
10
15
|
def task
|
11
16
|
@task
|
@@ -13,6 +18,10 @@ module Rant
|
|
13
18
|
def tname
|
14
19
|
@task ? @task.name : nil
|
15
20
|
end
|
21
|
+
# the exception which caused the task to fail
|
22
|
+
def orig
|
23
|
+
@orig
|
24
|
+
end
|
16
25
|
end
|
17
26
|
|
18
27
|
class Rantfile < Path
|
@@ -29,6 +38,9 @@ module Rant
|
|
29
38
|
|
30
39
|
# Any +object+ is considered a _task_ if
|
31
40
|
# <tt>Rant::Worker === object</tt> is true.
|
41
|
+
#
|
42
|
+
# Most important classes including this module are the Rant::Task
|
43
|
+
# class and the Rant::FileTask class.
|
32
44
|
module Worker
|
33
45
|
|
34
46
|
INVOKE_OPT = {}.freeze
|
@@ -57,15 +69,26 @@ module Rant
|
|
57
69
|
full_name
|
58
70
|
end
|
59
71
|
|
72
|
+
# The directory in which this task was defined, relative to
|
73
|
+
# the projects root directory.
|
60
74
|
def project_subdir
|
61
75
|
@rantfile.nil? ? "" : @rantfile.project_subdir
|
62
76
|
end
|
63
77
|
|
78
|
+
# Basically project_subdir/name
|
79
|
+
#
|
80
|
+
# The Rant compiler (or application) references tasks by their
|
81
|
+
# full_name.
|
64
82
|
def full_name
|
65
83
|
sd = project_subdir
|
66
84
|
sd.empty? ? name : File.join(sd, name)
|
67
85
|
end
|
68
86
|
|
87
|
+
# Change current working directory to the directory this task
|
88
|
+
# was defined in.
|
89
|
+
#
|
90
|
+
# Important for subclasses: Call this method always before
|
91
|
+
# invoking code from Rantfiles (e.g. task action blocks).
|
69
92
|
def goto_task_home
|
70
93
|
@app.goto_project_dir project_subdir
|
71
94
|
end
|
@@ -103,8 +126,17 @@ module Rant
|
|
103
126
|
end
|
104
127
|
end
|
105
128
|
|
106
|
-
|
107
|
-
|
129
|
+
# Cause task to fail. Usually called from inside the block
|
130
|
+
# given to +act+.
|
131
|
+
def fail msg = nil, orig = nil
|
132
|
+
raise TaskFail.new(self, orig), msg, caller
|
133
|
+
end
|
134
|
+
|
135
|
+
# Change pwd to task home directory and yield for each created
|
136
|
+
# file/directory.
|
137
|
+
#
|
138
|
+
# Override in subclasses if your task instances create files.
|
139
|
+
def each_target
|
108
140
|
end
|
109
141
|
|
110
142
|
def run
|
@@ -120,8 +152,9 @@ module Rant
|
|
120
152
|
end
|
121
153
|
private :circular_dep
|
122
154
|
|
155
|
+
# Tasks are hashed by their full_name.
|
123
156
|
def hash
|
124
|
-
|
157
|
+
full_name.hash
|
125
158
|
end
|
126
159
|
|
127
160
|
def eql? other
|
@@ -129,7 +162,7 @@ module Rant
|
|
129
162
|
end
|
130
163
|
end # module Worker
|
131
164
|
|
132
|
-
# A list of tasks with an equal
|
165
|
+
# A list of tasks with an equal full_name.
|
133
166
|
class MetaTask < Array
|
134
167
|
include Worker
|
135
168
|
|
@@ -196,6 +229,10 @@ module Rant
|
|
196
229
|
def app
|
197
230
|
empty? ? nil : first.app
|
198
231
|
end
|
232
|
+
|
233
|
+
def each_target &block
|
234
|
+
self.each { |t| t.each_target &block }
|
235
|
+
end
|
199
236
|
end # class MetaTask
|
200
237
|
|
201
238
|
# A very lightweight task for special purposes.
|
@@ -246,12 +283,6 @@ module Rant
|
|
246
283
|
@block = block
|
247
284
|
end
|
248
285
|
|
249
|
-
# Cause task to fail. Usually called from inside the block
|
250
|
-
# given to +act+.
|
251
|
-
def fail msg = nil
|
252
|
-
raise TaskFail.new(self), msg, caller
|
253
|
-
end
|
254
|
-
|
255
286
|
def needed?
|
256
287
|
return false if done?
|
257
288
|
return true if @needed.nil?
|
@@ -279,10 +310,10 @@ module Rant
|
|
279
310
|
end
|
280
311
|
rescue CommandError => e
|
281
312
|
err_msg e.message if app[:err_commands]
|
282
|
-
self.fail
|
313
|
+
self.fail(nil, e)
|
283
314
|
rescue SystemCallError => e
|
284
315
|
err_msg e.message
|
285
|
-
self.fail
|
316
|
+
self.fail(nil, e)
|
286
317
|
ensure
|
287
318
|
@run = false
|
288
319
|
end
|
@@ -327,6 +358,7 @@ module Rant
|
|
327
358
|
def prerequisites
|
328
359
|
@pre.collect { |pre| pre.to_s }
|
329
360
|
end
|
361
|
+
alias deps prerequisites
|
330
362
|
|
331
363
|
# First prerequisite.
|
332
364
|
def source
|
@@ -421,16 +453,7 @@ module Rant
|
|
421
453
|
update
|
422
454
|
rescue StandardError => e
|
423
455
|
@success = false
|
424
|
-
|
425
|
-
when TaskFail: raise
|
426
|
-
when CommandError
|
427
|
-
err_msg e.message if app[:err_commands]
|
428
|
-
when SystemCallError
|
429
|
-
err_msg e.message
|
430
|
-
else
|
431
|
-
err_msg e.message, e.backtrace
|
432
|
-
end
|
433
|
-
self.fail
|
456
|
+
self.fail(nil, e)
|
434
457
|
end
|
435
458
|
private :internal_invoke
|
436
459
|
|
@@ -633,6 +656,11 @@ module Rant
|
|
633
656
|
end
|
634
657
|
[dep, dep.mtime > @ts]
|
635
658
|
end
|
659
|
+
|
660
|
+
def each_target
|
661
|
+
goto_task_home
|
662
|
+
yield name
|
663
|
+
end
|
636
664
|
end # class FileTask
|
637
665
|
|
638
666
|
# An instance of this class is a task to create a _single_
|
@@ -741,17 +769,24 @@ module Rant
|
|
741
769
|
@app.sys.mkdir @name unless @isdir
|
742
770
|
if @block
|
743
771
|
@block.arity == 0 ? @block.call : @block[self]
|
772
|
+
goto_task_home
|
744
773
|
@app.sys.touch @name
|
745
774
|
end
|
746
775
|
end
|
776
|
+
|
777
|
+
def each_target
|
778
|
+
goto_task_home
|
779
|
+
yield name
|
780
|
+
end
|
747
781
|
end # class DirTask
|
748
782
|
module Generators
|
749
783
|
Task = ::Rant::Task
|
750
784
|
LightTask = ::Rant::LightTask
|
751
785
|
Directory = ::Rant::DirTask
|
752
786
|
|
753
|
-
class Rule
|
754
|
-
#
|
787
|
+
class Rule < ::Proc
|
788
|
+
# Generate a rule by installing an at_resolve hook for
|
789
|
+
# +rac+.
|
755
790
|
def self.rant_generate(rac, ch, args, &block)
|
756
791
|
unless args.size == 1
|
757
792
|
rac.abort_at(ch, "Rule takes only one argument.")
|
@@ -799,7 +834,7 @@ module Rant
|
|
799
834
|
rac.abort_at(ch, "rule source has to be " +
|
800
835
|
"String or Proc")
|
801
836
|
end
|
802
|
-
|
837
|
+
blk = self.new { |task_name|
|
803
838
|
if target_rx =~ task_name
|
804
839
|
[rac.file(:__caller__ => ch,
|
805
840
|
task_name => src_proc[task_name], &block)]
|
@@ -807,7 +842,23 @@ module Rant
|
|
807
842
|
nil
|
808
843
|
end
|
809
844
|
}
|
845
|
+
blk.target_rx = target_rx
|
846
|
+
rac.at_resolve &blk
|
847
|
+
nil
|
810
848
|
end
|
849
|
+
attr_accessor :target_rx
|
811
850
|
end # class Rule
|
851
|
+
|
852
|
+
class Action
|
853
|
+
def self.rant_generate(rac, ch, args, &block)
|
854
|
+
unless args.empty?
|
855
|
+
rac.warn_msg(rac.pos_text(ch[:file], ch[:ln]),
|
856
|
+
"Action doesn't take arguments.")
|
857
|
+
end
|
858
|
+
unless (rac[:tasks] || rac[:stop_after_load])
|
859
|
+
yield
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|
812
863
|
end # module Generators
|
813
864
|
end # module Rant
|
data/lib/rant/rantlib.rb
CHANGED
@@ -32,9 +32,10 @@ class Array
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def shell_pathes
|
35
|
+
entry = nil
|
35
36
|
if ::Rant::Env.on_windows?
|
36
37
|
self.collect { |entry|
|
37
|
-
entry = entry.tr("/", "\\")
|
38
|
+
entry = entry.to_s.tr("/", "\\")
|
38
39
|
if entry.include? ' '
|
39
40
|
'"' + entry + '"'
|
40
41
|
else
|
@@ -43,6 +44,7 @@ class Array
|
|
43
44
|
}
|
44
45
|
else
|
45
46
|
self.collect { |entry|
|
47
|
+
entry = entry.to_s
|
46
48
|
if entry.include? ' '
|
47
49
|
"'" + entry + "'"
|
48
50
|
else
|
@@ -71,9 +73,21 @@ module Rant::Lib
|
|
71
73
|
# p parse_caller_elem "/usr/local/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'"
|
72
74
|
# prints:
|
73
75
|
# {:ln=>52, :file=>"/usr/local/lib/ruby/1.8/irb/workspace.rb"}
|
76
|
+
#
|
77
|
+
# Note: This method splits on the pattern <tt>:(\d+)(:|$)</tt>,
|
78
|
+
# assuming anything before is the filename.
|
74
79
|
def parse_caller_elem elem
|
75
|
-
|
76
|
-
|
80
|
+
return { :file => "", :ln => 0 } if elem.nil?
|
81
|
+
if elem =~ /^(.+):(\d+)(:|$)/
|
82
|
+
{ :file => $1, :ln => $2.to_i }
|
83
|
+
else
|
84
|
+
# should never occur
|
85
|
+
$stderr.puts "parse_caller_elem: #{elem.inspect}"
|
86
|
+
{ :file => elem, :ln => 0 }
|
87
|
+
end
|
88
|
+
|
89
|
+
#parts = elem.split(":")
|
90
|
+
#{ :file => parts[0], :ln => parts[1].to_i }
|
77
91
|
end
|
78
92
|
module_function :parse_caller_elem
|
79
93
|
|
@@ -195,7 +209,7 @@ module Rant
|
|
195
209
|
def run(first_arg=nil, *other_args)
|
196
210
|
other_args = other_args.flatten
|
197
211
|
args = first_arg.nil? ? ARGV.dup : ([first_arg] + other_args)
|
198
|
-
if @@rac && !@@rac.
|
212
|
+
if @@rac && !@@rac.run?
|
199
213
|
@@rac.args.replace(args.flatten)
|
200
214
|
@@rac.run
|
201
215
|
else
|
@@ -293,6 +307,11 @@ class Rant::RantApp
|
|
293
307
|
# Current subdirectory relative to project's root directory
|
294
308
|
# (#rootdir).
|
295
309
|
attr_reader :current_subdir
|
310
|
+
# List of proc objects used to automatically create required
|
311
|
+
# tasks. (Especially used for Rules.)
|
312
|
+
#
|
313
|
+
# Note: Might change before 1.0
|
314
|
+
attr_reader :resolve_hooks
|
296
315
|
|
297
316
|
def initialize *args
|
298
317
|
@args = args.flatten
|
@@ -305,11 +324,12 @@ class Rant::RantApp
|
|
305
324
|
@opts = {
|
306
325
|
:verbose => 0,
|
307
326
|
:quiet => false,
|
327
|
+
:directory => "",
|
308
328
|
}
|
309
329
|
@arg_rantfiles = [] # rantfiles given in args
|
310
330
|
@arg_targets = [] # targets given in args
|
311
331
|
@force_targets = []
|
312
|
-
@
|
332
|
+
@run = false
|
313
333
|
@done = false
|
314
334
|
@plugins = []
|
315
335
|
@var = Rant::RantVar::Space.new
|
@@ -338,19 +358,23 @@ class Rant::RantApp
|
|
338
358
|
end
|
339
359
|
|
340
360
|
def rootdir
|
341
|
-
od = @opts[:directory]
|
342
|
-
od ? od.dup : ""
|
361
|
+
#od = @opts[:directory]
|
362
|
+
#od ? od.dup : ""
|
363
|
+
@opts[:directory]
|
343
364
|
end
|
344
365
|
|
345
366
|
def rootdir=(newdir)
|
346
|
-
if @
|
367
|
+
if @run
|
347
368
|
raise "rootdir of rant application can't " +
|
348
369
|
"be changed after calling `run'"
|
349
370
|
end
|
371
|
+
unless String === newdir
|
372
|
+
raise "rootdir has to be a String"
|
373
|
+
end
|
350
374
|
@opts[:directory] = newdir.dup
|
351
375
|
end
|
352
376
|
|
353
|
-
###
|
377
|
+
### support for subdirectories ###################################
|
354
378
|
def expand_project_path(path)
|
355
379
|
expand_path(@current_subdir, path)
|
356
380
|
end
|
@@ -397,10 +421,18 @@ class Rant::RantApp
|
|
397
421
|
# TODO: optimize
|
398
422
|
goto "##{dir}"
|
399
423
|
end
|
424
|
+
# Execute the give block in project directory dir.
|
425
|
+
def in_project_dir(dir)
|
426
|
+
prev_subdir = @current_subdir
|
427
|
+
goto_project_dir(dir)
|
428
|
+
yield
|
429
|
+
ensure
|
430
|
+
goto_project_dir(prev_subdir)
|
431
|
+
end
|
400
432
|
##################################################################
|
401
433
|
|
402
|
-
def
|
403
|
-
@
|
434
|
+
def run?
|
435
|
+
@run
|
404
436
|
end
|
405
437
|
|
406
438
|
def done?
|
@@ -409,14 +441,14 @@ class Rant::RantApp
|
|
409
441
|
|
410
442
|
# Returns 0 on success and 1 on failure.
|
411
443
|
def run
|
412
|
-
@
|
444
|
+
@run = true
|
413
445
|
# remind pwd
|
414
446
|
@orig_pwd = Dir.pwd
|
415
447
|
# Process commandline.
|
416
448
|
process_args
|
417
449
|
# Set pwd.
|
418
450
|
opts_dir = @opts[:directory]
|
419
|
-
if opts_dir
|
451
|
+
if !(opts_dir.empty? || opts_dir.nil?)
|
420
452
|
opts_dir = File.expand_path(opts_dir)
|
421
453
|
unless test(?d, opts_dir)
|
422
454
|
abort("No such directory - #{opts_dir}")
|
@@ -433,7 +465,7 @@ class Rant::RantApp
|
|
433
465
|
|
434
466
|
# Notify plugins before running tasks
|
435
467
|
@plugins.each { |plugin| plugin.rant_start }
|
436
|
-
if @opts[:
|
468
|
+
if @opts[:tasks]
|
437
469
|
show_descriptions
|
438
470
|
raise Rant::RantDoneException
|
439
471
|
end
|
@@ -444,6 +476,7 @@ class Rant::RantApp
|
|
444
476
|
rescue Rant::RantDoneException
|
445
477
|
@done = true
|
446
478
|
# Notify plugins
|
479
|
+
goto "#"
|
447
480
|
@plugins.each { |plugin| plugin.rant_done }
|
448
481
|
return 0
|
449
482
|
rescue Rant::RantfileException
|
@@ -451,7 +484,12 @@ class Rant::RantApp
|
|
451
484
|
$stderr.puts "rant aborted!"
|
452
485
|
return 1
|
453
486
|
rescue Rant::RantError
|
454
|
-
|
487
|
+
ch = get_ch_from_backtrace($!.backtrace)
|
488
|
+
if ch
|
489
|
+
err_msg(pos_text(ch[:file], ch[:ln]), $!.message)
|
490
|
+
else
|
491
|
+
err_msg $!.message, $!.backtrace[0..4]
|
492
|
+
end
|
455
493
|
$stderr.puts "rant aborted!"
|
456
494
|
return 1
|
457
495
|
rescue Rant::RantAbortException
|
@@ -528,6 +566,7 @@ class Rant::RantApp
|
|
528
566
|
unless @imports.include? arg
|
529
567
|
unless Rant::CODE_IMPORTS.include? arg
|
530
568
|
begin
|
569
|
+
msg 2, "import #{arg}"
|
531
570
|
require "rant/import/#{arg}"
|
532
571
|
rescue LoadError => e
|
533
572
|
abort(pos_text(ch[:file], ch[:ln]),
|
@@ -704,12 +743,11 @@ class Rant::RantApp
|
|
704
743
|
raise Rant::RantAbortException
|
705
744
|
end
|
706
745
|
|
707
|
-
def
|
746
|
+
def show_help
|
708
747
|
puts "rant [-f RANTFILE] [OPTIONS] tasks..."
|
709
748
|
puts
|
710
749
|
puts "Options are:"
|
711
750
|
print option_listing(OPTIONS)
|
712
|
-
raise Rant::RantDoneException
|
713
751
|
end
|
714
752
|
|
715
753
|
def show_descriptions
|
@@ -888,17 +926,22 @@ class Rant::RantApp
|
|
888
926
|
def build target, opt = {}
|
889
927
|
opt[:force] = true if @force_targets.delete(target)
|
890
928
|
matching_tasks = 0
|
929
|
+
old_subdir = @current_subdir
|
930
|
+
old_pwd = Dir.pwd
|
891
931
|
resolve(target).each { |t|
|
892
932
|
matching_tasks += 1
|
893
933
|
begin
|
894
934
|
t.invoke(opt)
|
895
935
|
rescue Rant::TaskFail => e
|
896
|
-
|
897
|
-
abort
|
936
|
+
err_task_fail(e)
|
937
|
+
abort
|
898
938
|
end
|
899
939
|
}
|
940
|
+
@current_subdir = old_subdir
|
941
|
+
Dir.chdir old_pwd
|
900
942
|
matching_tasks
|
901
943
|
end
|
944
|
+
public :build
|
902
945
|
|
903
946
|
def resolve task_name, rel_project_dir = @current_subdir
|
904
947
|
#select_tasks_by_name task_name, rel_project_dir
|
@@ -1058,15 +1101,18 @@ class Rant::RantApp
|
|
1058
1101
|
$stdout.puts "rant #{Rant::VERSION}"
|
1059
1102
|
raise Rant::RantDoneException
|
1060
1103
|
when "--help"
|
1061
|
-
|
1104
|
+
show_help
|
1105
|
+
raise Rant::RantDoneException
|
1062
1106
|
when "--directory"
|
1107
|
+
# take care: we bypass the checks of self.rootdir=
|
1108
|
+
# because @run is true
|
1063
1109
|
@opts[:directory] = value
|
1064
1110
|
when "--rantfile"
|
1065
1111
|
@arg_rantfiles << value
|
1066
1112
|
when "--force-run"
|
1067
1113
|
@force_targets << value
|
1068
1114
|
when "--tasks"
|
1069
|
-
@opts[:
|
1115
|
+
@opts[:tasks] = true
|
1070
1116
|
when "--stop-after-load"
|
1071
1117
|
@opts[:stop_after_load] = true
|
1072
1118
|
when "--trace-abort"
|
@@ -1224,6 +1270,55 @@ class Rant::RantApp
|
|
1224
1270
|
end
|
1225
1271
|
end
|
1226
1272
|
|
1273
|
+
# Returns the usual hash with :file and :ln as keys for the first
|
1274
|
+
# element in backtrace which comes from an Rantfile, or nil if no
|
1275
|
+
# Rantfile is involved.
|
1276
|
+
#
|
1277
|
+
# Note that this method is very time consuming!
|
1278
|
+
def get_ch_from_backtrace(backtrace)
|
1279
|
+
backtrace.each { |clr|
|
1280
|
+
ch = ::Rant::Lib.parse_caller_elem(clr)
|
1281
|
+
if ::Rant::Env.on_windows?
|
1282
|
+
return ch if @rantfiles.any? { |rf|
|
1283
|
+
# sigh... a bit hackish: replace any backslash
|
1284
|
+
# with a slash and remove any leading drive (e.g.
|
1285
|
+
# C:) from the path
|
1286
|
+
rf.path.tr("\\", "/").sub(/^\w\:/, '') ==
|
1287
|
+
ch[:file].tr("\\", "/").sub(/^\w\:/, '')
|
1288
|
+
}
|
1289
|
+
else
|
1290
|
+
return ch if @rantfiles.any? { |rf|
|
1291
|
+
rf.path == ch[:file]
|
1292
|
+
}
|
1293
|
+
end
|
1294
|
+
}
|
1295
|
+
nil
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
def err_task_fail(e)
|
1299
|
+
msg = []
|
1300
|
+
t_msg = ["Task `#{e.tname}' fail."]
|
1301
|
+
orig = e
|
1302
|
+
loop { orig = orig.orig; break unless Rant::TaskFail === orig }
|
1303
|
+
unless orig == e
|
1304
|
+
if Rant::RantError === orig
|
1305
|
+
ch = get_ch_from_backtrace(orig.backtrace)
|
1306
|
+
if ch
|
1307
|
+
msg << pos_text(ch[:file], ch[:ln])
|
1308
|
+
msg << orig.message
|
1309
|
+
else
|
1310
|
+
msg << orig.message << orig.backtrace[0..4]
|
1311
|
+
end
|
1312
|
+
elsif Rant::CommandError === orig
|
1313
|
+
msg << orig.message if @opts[:err_commands]
|
1314
|
+
else
|
1315
|
+
msg << orig.message unless Rant::RantAbortException
|
1316
|
+
end
|
1317
|
+
end
|
1318
|
+
err_msg msg unless msg.empty?
|
1319
|
+
err_msg t_msg
|
1320
|
+
end
|
1321
|
+
|
1227
1322
|
# Just ensure that Rant.rac holds an RantApp after loading
|
1228
1323
|
# this file. The code in initialize will register the new app with
|
1229
1324
|
# Rant.rac= if necessary.
|