rant 0.4.0 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +16 -0
- data/README +3 -2
- data/Rantfile +3 -4
- data/doc/advanced.rdoc +18 -13
- data/doc/examples/c_cpp_examples/Rantfile +37 -0
- data/doc/examples/c_cpp_examples/c/problem_1_1/another_test.c +6 -0
- data/doc/examples/c_cpp_examples/c/problem_1_1/another_test.h +7 -0
- data/doc/examples/c_cpp_examples/c/problem_1_1/main.c +12 -0
- data/doc/examples/c_cpp_examples/c/problem_1_1/test.c +6 -0
- data/doc/examples/c_cpp_examples/c/problem_1_1/test.h +7 -0
- data/doc/examples/c_cpp_examples/c/template.rf +21 -0
- data/doc/examples/c_cpp_examples/c++/problem_1_1/another_test.cpp +6 -0
- data/doc/examples/c_cpp_examples/c++/problem_1_1/another_test.h +5 -0
- data/doc/examples/c_cpp_examples/c++/problem_1_1/main.cpp +12 -0
- data/doc/examples/c_cpp_examples/c++/problem_1_1/test.cpp +6 -0
- data/doc/examples/c_cpp_examples/c++/problem_1_1/test.h +5 -0
- data/doc/examples/c_cpp_examples/c++/template.rf +21 -0
- data/doc/examples/c_cpp_examples/rule.rf +7 -0
- data/doc/rantfile.rdoc +1 -0
- data/lib/rant/archive/rubyzip/tempfile_bugfixed.rb +10 -8
- data/lib/rant/archive/rubyzip.rb +3 -8
- data/lib/rant/import/archive.rb +8 -4
- data/lib/rant/import/rubydoc.rb +1 -1
- data/lib/rant/import/rubytest.rb +12 -17
- data/lib/rant/import.rb +3 -2
- data/lib/rant/rantenv.rb +7 -4
- data/lib/rant/rantfile.rb +41 -21
- data/lib/rant/rantlib.rb +166 -113
- data/lib/rant/rantsys.rb +32 -17
- data/lib/rant/rantvar.rb +15 -15
- data/lib/rant/tempfile.rb +12 -0
- data/test/Rantfile +33 -0
- data/test/import/directedrule/test_directedrule.rb +29 -0
- data/test/import/package/Rantfile +2 -0
- data/test/import/package/test_package.rb +10 -0
- data/test/import/subfile/test_subfile.rb +21 -0
- data/test/project1/test_project.rb +10 -30
- data/test/project2/test_project.rb +1 -1
- data/test/project_rb1/test_project_rb1.rb +2 -1
- data/test/rant-import/test_rant-import.rb +35 -1
- data/test/subdirs/test_subdirs.rb +1 -2
- data/test/test_dirtask.rb +42 -0
- data/test/test_examples.rb +67 -0
- data/test/test_filelist.rb +52 -0
- data/test/test_rantfile_api.rb +59 -0
- data/test/ts_all.rb +1 -0
- metadata +25 -3
data/lib/rant/rantlib.rb
CHANGED
@@ -23,6 +23,38 @@ require 'rant/rantsys'
|
|
23
23
|
# this object.
|
24
24
|
Rant::MAIN_OBJECT = self
|
25
25
|
|
26
|
+
unless Process::Status.method_defined?(:success?)
|
27
|
+
class Process::Status
|
28
|
+
def success?; exitstatus == 0; end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
if RUBY_VERSION < "1.8.2"
|
32
|
+
class Array
|
33
|
+
def flatten
|
34
|
+
cp = self.dup
|
35
|
+
cp.flatten!
|
36
|
+
cp
|
37
|
+
end
|
38
|
+
def flatten!
|
39
|
+
res = []
|
40
|
+
flattened = false
|
41
|
+
self.each { |e|
|
42
|
+
if e.respond_to? :to_ary
|
43
|
+
res.concat(e.to_ary)
|
44
|
+
flattened = true
|
45
|
+
else
|
46
|
+
res << e
|
47
|
+
end
|
48
|
+
}
|
49
|
+
if flattened
|
50
|
+
replace(res)
|
51
|
+
flatten!
|
52
|
+
self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
26
58
|
class Array
|
27
59
|
|
28
60
|
# Concatenates all elements like #join(' ') but also puts quotes
|
@@ -63,6 +95,9 @@ class String
|
|
63
95
|
self.sub(/(\.[^.]*$)|$/, ".#{ext}")
|
64
96
|
end
|
65
97
|
end
|
98
|
+
def to_rant_target
|
99
|
+
self
|
100
|
+
end
|
66
101
|
end
|
67
102
|
|
68
103
|
module Rant::Lib
|
@@ -76,7 +111,7 @@ module Rant::Lib
|
|
76
111
|
#
|
77
112
|
# Note: This method splits on the pattern <tt>:(\d+)(:|$)</tt>,
|
78
113
|
# assuming anything before is the filename.
|
79
|
-
def parse_caller_elem
|
114
|
+
def parse_caller_elem(elem)
|
80
115
|
return { :file => "", :ln => 0 } if elem.nil?
|
81
116
|
if elem =~ /^(.+):(\d+)(:|$)/
|
82
117
|
{ :file => $1, :ln => $2.to_i }
|
@@ -102,17 +137,17 @@ module RantContext
|
|
102
137
|
FileList = Rant::FileList
|
103
138
|
|
104
139
|
# Define a basic task.
|
105
|
-
def task
|
140
|
+
def task(targ, &block)
|
106
141
|
rac.task(targ, &block)
|
107
142
|
end
|
108
143
|
|
109
144
|
# Define a file task.
|
110
|
-
def file
|
145
|
+
def file(targ, &block)
|
111
146
|
rac.file(targ, &block)
|
112
147
|
end
|
113
148
|
|
114
149
|
# Add code and/or prerequisites to existing task.
|
115
|
-
def enhance
|
150
|
+
def enhance(targ, &block)
|
116
151
|
rac.enhance(targ, &block)
|
117
152
|
end
|
118
153
|
|
@@ -134,7 +169,7 @@ module RantContext
|
|
134
169
|
|
135
170
|
# Look in the subdirectories, given by args,
|
136
171
|
# for rantfiles.
|
137
|
-
def subdirs
|
172
|
+
def subdirs(*args)
|
138
173
|
rac.subdirs(*args)
|
139
174
|
end
|
140
175
|
|
@@ -149,6 +184,10 @@ module RantContext
|
|
149
184
|
def var(*args, &block)
|
150
185
|
rac.var(*args, &block)
|
151
186
|
end
|
187
|
+
|
188
|
+
def make(*args, &block)
|
189
|
+
rac.make(*args, &block)
|
190
|
+
end
|
152
191
|
end # module RantContext
|
153
192
|
|
154
193
|
class RantAppContext
|
@@ -225,12 +264,6 @@ module Rant
|
|
225
264
|
def rac=(app)
|
226
265
|
@@rac = app
|
227
266
|
end
|
228
|
-
|
229
|
-
# "Clear" the current Rant application. After this call,
|
230
|
-
# Rant has the same state as immediately after startup.
|
231
|
-
def reset
|
232
|
-
@@rac = nil
|
233
|
-
end
|
234
267
|
end
|
235
268
|
|
236
269
|
end # module Rant
|
@@ -255,7 +288,7 @@ class Rant::RantApp
|
|
255
288
|
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT,
|
256
289
|
"Print more messages to stderr." ],
|
257
290
|
[ "--quiet", "-q", GetoptLong::NO_ARGUMENT,
|
258
|
-
"Don't print commands."
|
291
|
+
"Don't print commands." ],
|
259
292
|
[ "--err-commands", GetoptLong::NO_ARGUMENT,
|
260
293
|
"Print failed commands and their exit status." ],
|
261
294
|
[ "--directory","-C", GetoptLong::REQUIRED_ARGUMENT,
|
@@ -264,7 +297,7 @@ class Rant::RantApp
|
|
264
297
|
"Process RANTFILE instead of standard rantfiles.\n" +
|
265
298
|
"Multiple files may be specified with this option" ],
|
266
299
|
[ "--force-run","-a", GetoptLong::REQUIRED_ARGUMENT,
|
267
|
-
"Force
|
300
|
+
"Force rebuild of TARGET and all dependencies." ],
|
268
301
|
[ "--tasks", "-T", GetoptLong::NO_ARGUMENT,
|
269
302
|
"Show a list of all described tasks and exit." ],
|
270
303
|
|
@@ -314,7 +347,7 @@ class Rant::RantApp
|
|
314
347
|
# Note: Might change before 1.0
|
315
348
|
attr_reader :resolve_hooks
|
316
349
|
|
317
|
-
def initialize
|
350
|
+
def initialize(*args)
|
318
351
|
unless args.empty?
|
319
352
|
STDERR.puts caller[0]
|
320
353
|
STDERR.puts "Warning: Giving arguments Rant::RantApp.new " +
|
@@ -444,7 +477,7 @@ class Rant::RantApp
|
|
444
477
|
end
|
445
478
|
|
446
479
|
# Returns 0 on success and 1 on failure.
|
447
|
-
def run
|
480
|
+
def run(*args)
|
448
481
|
@run = true
|
449
482
|
@args.concat(args.flatten)
|
450
483
|
# remind pwd
|
@@ -484,20 +517,16 @@ class Rant::RantApp
|
|
484
517
|
goto "#"
|
485
518
|
@plugins.each { |plugin| plugin.rant_done }
|
486
519
|
return 0
|
487
|
-
rescue Rant::RantError
|
488
|
-
ch = get_ch_from_backtrace($!.backtrace)
|
489
|
-
if ch
|
490
|
-
err_msg(pos_text(ch[:file], ch[:ln]), $!.message)
|
491
|
-
else
|
492
|
-
err_msg $!.message, $!.backtrace[0..4]
|
493
|
-
end
|
494
|
-
$stderr.puts "rant aborted!"
|
495
|
-
return 1
|
496
520
|
rescue Rant::RantAbortException
|
497
521
|
$stderr.puts "rant aborted!"
|
498
522
|
return 1
|
499
|
-
rescue
|
500
|
-
|
523
|
+
rescue Exception => e
|
524
|
+
ch = get_ch_from_backtrace(e.backtrace)
|
525
|
+
if ch && !@opts[:trace_abort]
|
526
|
+
err_msg(pos_text(ch[:file], ch[:ln]), e.message)
|
527
|
+
else
|
528
|
+
err_msg e.message, e.backtrace[0..4]
|
529
|
+
end
|
501
530
|
$stderr.puts "rant aborted!"
|
502
531
|
return 1
|
503
532
|
ensure
|
@@ -511,7 +540,7 @@ class Rant::RantApp
|
|
511
540
|
|
512
541
|
###### methods accessible through RantContext ####################
|
513
542
|
|
514
|
-
def desc
|
543
|
+
def desc(*args)
|
515
544
|
if args.empty? || (args.size == 1 && args.first.nil?)
|
516
545
|
@task_desc = nil
|
517
546
|
else
|
@@ -519,13 +548,13 @@ class Rant::RantApp
|
|
519
548
|
end
|
520
549
|
end
|
521
550
|
|
522
|
-
def task
|
551
|
+
def task(targ, &block)
|
523
552
|
prepare_task(targ, block) { |name,pre,blk|
|
524
553
|
Rant::Task.new(self, name, pre, &blk)
|
525
554
|
}
|
526
555
|
end
|
527
556
|
|
528
|
-
def file
|
557
|
+
def file(targ, &block)
|
529
558
|
prepare_task(targ, block) { |name,pre,blk|
|
530
559
|
Rant::FileTask.new(self, name, pre, &blk)
|
531
560
|
}
|
@@ -533,15 +562,12 @@ class Rant::RantApp
|
|
533
562
|
|
534
563
|
def gen(*args, &block)
|
535
564
|
# retrieve caller info
|
536
|
-
|
537
|
-
ch = Rant::Lib::parse_caller_elem(clr)
|
538
|
-
name = nil
|
539
|
-
pre = []
|
565
|
+
ch = Rant::Lib::parse_caller_elem(caller[1])
|
540
566
|
# validate args
|
541
567
|
generator = args.shift
|
542
568
|
unless generator.respond_to? :rant_gen
|
543
569
|
abort_at(ch,
|
544
|
-
"First argument to
|
570
|
+
"gen: First argument to has to be a task-generator.")
|
545
571
|
end
|
546
572
|
# ask generator to produce a task for this application
|
547
573
|
generator.rant_gen(self, ch, args, &block)
|
@@ -556,8 +582,7 @@ class Rant::RantApp
|
|
556
582
|
end
|
557
583
|
args.flatten.each { |arg|
|
558
584
|
unless String === arg
|
559
|
-
|
560
|
-
"import: only strings allowed as arguments")
|
585
|
+
abort_at(ch, "import: only strings allowed as arguments")
|
561
586
|
end
|
562
587
|
unless @imports.include? arg
|
563
588
|
unless Rant::CODE_IMPORTS.include? arg
|
@@ -565,8 +590,7 @@ class Rant::RantApp
|
|
565
590
|
msg 2, "import #{arg}"
|
566
591
|
require "rant/import/#{arg}"
|
567
592
|
rescue LoadError => e
|
568
|
-
|
569
|
-
"No such import - #{arg}")
|
593
|
+
abort_at(ch, "No such import - #{arg}")
|
570
594
|
end
|
571
595
|
Rant::CODE_IMPORTS << arg.dup
|
572
596
|
end
|
@@ -623,7 +647,7 @@ class Rant::RantApp
|
|
623
647
|
# name given as only key in targ.
|
624
648
|
# If there is no task with the given name, generate a warning
|
625
649
|
# and a new file task.
|
626
|
-
def enhance
|
650
|
+
def enhance(targ, &block)
|
627
651
|
prepare_task(targ, block) { |name,pre,blk|
|
628
652
|
t = resolve(name).last
|
629
653
|
if t
|
@@ -659,17 +683,14 @@ class Rant::RantApp
|
|
659
683
|
end
|
660
684
|
|
661
685
|
# Search the given directories for Rantfiles.
|
662
|
-
def subdirs
|
686
|
+
def subdirs(*args)
|
663
687
|
args.flatten!
|
664
|
-
|
665
|
-
ln = cinf[:ln] || 0
|
666
|
-
file = cinf[:file]
|
688
|
+
ch = Rant::Lib::parse_caller_elem(caller[1])
|
667
689
|
args.each { |arg|
|
668
690
|
if arg.respond_to? :to_str
|
669
691
|
arg = arg.to_str
|
670
692
|
else
|
671
|
-
|
672
|
-
"subdirs: arguments must be strings")
|
693
|
+
abort_at(ch, "subdirs: arguments must be strings")
|
673
694
|
end
|
674
695
|
loaded = false
|
675
696
|
prev_subdir = @current_subdir
|
@@ -690,12 +711,12 @@ class Rant::RantApp
|
|
690
711
|
goto_project_dir prev_subdir
|
691
712
|
end
|
692
713
|
unless loaded || @opts[:no_warn_subdir]
|
693
|
-
warn_msg(pos_text(file, ln),
|
714
|
+
warn_msg(pos_text(ch[:file], ch[:ln]),
|
694
715
|
"subdirs: No Rantfile in subdir `#{arg}'.")
|
695
716
|
end
|
696
717
|
}
|
697
718
|
rescue SystemCallError => e
|
698
|
-
|
719
|
+
abort_at(ch, "subdirs: " + e.message)
|
699
720
|
end
|
700
721
|
|
701
722
|
def sys(*args, &block)
|
@@ -717,8 +738,8 @@ class Rant::RantApp
|
|
717
738
|
td
|
718
739
|
end
|
719
740
|
|
720
|
-
# Prints msg as error message and raises
|
721
|
-
def abort
|
741
|
+
# Prints msg as error message and raises an RantAbortException.
|
742
|
+
def abort(*msg)
|
722
743
|
err_msg(msg) unless msg.empty?
|
723
744
|
$stderr.puts caller if @opts[:trace_abort]
|
724
745
|
raise Rant::RantAbortException
|
@@ -731,7 +752,7 @@ class Rant::RantApp
|
|
731
752
|
end
|
732
753
|
|
733
754
|
def show_help
|
734
|
-
puts "rant [-f
|
755
|
+
puts "rant [-f Rantfile] [Options] [targets]"
|
735
756
|
puts
|
736
757
|
puts "Options are:"
|
737
758
|
print option_listing(OPTIONS)
|
@@ -766,7 +787,7 @@ class Rant::RantApp
|
|
766
787
|
tlist.each { |t|
|
767
788
|
print(prefix + t.full_name.ljust(name_length) + infix)
|
768
789
|
dt = t.description.sub(/\s+$/, "")
|
769
|
-
puts dt.sub(
|
790
|
+
puts dt.sub(/\n/, "\n" + ' ' * cmd_length + infix + " ")
|
770
791
|
}
|
771
792
|
true
|
772
793
|
end
|
@@ -799,15 +820,13 @@ class Rant::RantApp
|
|
799
820
|
@opts[:quiet]
|
800
821
|
end
|
801
822
|
|
802
|
-
def pos_text
|
823
|
+
def pos_text(file, ln)
|
803
824
|
t = "in file `#{file}'"
|
804
|
-
|
805
|
-
|
806
|
-
end
|
807
|
-
t + ": "
|
825
|
+
t << ", line #{ln}" if ln && ln > 0
|
826
|
+
t << ": "
|
808
827
|
end
|
809
828
|
|
810
|
-
def msg
|
829
|
+
def msg(*args)
|
811
830
|
verbose_level = args[0]
|
812
831
|
if verbose_level.is_a? Integer
|
813
832
|
super(args[1..-1]) if verbose_level <= verbose
|
@@ -818,7 +837,7 @@ class Rant::RantApp
|
|
818
837
|
|
819
838
|
# Print a command message as would be done from a call to a
|
820
839
|
# Sys method.
|
821
|
-
def cmd_msg
|
840
|
+
def cmd_msg(cmd)
|
822
841
|
puts cmd unless quiet?
|
823
842
|
end
|
824
843
|
|
@@ -853,7 +872,7 @@ class Rant::RantApp
|
|
853
872
|
|
854
873
|
private
|
855
874
|
def have_any_task?
|
856
|
-
|
875
|
+
!@tasks.empty?
|
857
876
|
end
|
858
877
|
|
859
878
|
def target_list
|
@@ -890,15 +909,60 @@ class Rant::RantApp
|
|
890
909
|
matching_tasks = 0
|
891
910
|
target_list.each do |target|
|
892
911
|
goto "#"
|
893
|
-
if
|
912
|
+
if build(target) == 0
|
894
913
|
abort("Don't know how to make `#{target}'.")
|
895
914
|
end
|
896
915
|
end
|
897
916
|
end
|
898
917
|
|
918
|
+
def make(target, *args, &block)
|
919
|
+
ch = nil
|
920
|
+
if target.respond_to? :to_hash
|
921
|
+
targ = target.to_hash
|
922
|
+
ch = Rant::Lib.parse_caller_elem(caller[1])
|
923
|
+
abort_at(ch, "make: too many arguments") unless args.empty?
|
924
|
+
tn = nil
|
925
|
+
prepare_task(targ, block, ch) { |name,pre,blk|
|
926
|
+
tn = name
|
927
|
+
Rant::FileTask.new(self, name, pre, &blk)
|
928
|
+
}
|
929
|
+
build(tn)
|
930
|
+
elsif target.respond_to? :to_rant_target
|
931
|
+
rt = target.to_rant_target
|
932
|
+
opt = args.shift
|
933
|
+
unless args.empty?
|
934
|
+
ch ||= Rant::Lib.parse_caller_elem(caller[1])
|
935
|
+
abort_at(ch, "make: too many arguments")
|
936
|
+
end
|
937
|
+
if block
|
938
|
+
# create a file task
|
939
|
+
ch ||= Rant::Lib.parse_caller_elem(caller[1])
|
940
|
+
prepare_task(rt, block, ch) { |name,pre,blk|
|
941
|
+
Rant::FileTask.new(self, name, pre, &blk)
|
942
|
+
}
|
943
|
+
build(rt)
|
944
|
+
else
|
945
|
+
build(rt, opt||{})
|
946
|
+
end
|
947
|
+
elsif target.respond_to? :rant_gen
|
948
|
+
ch = Rant::Lib.parse_caller_elem(caller[1])
|
949
|
+
rv = target.rant_gen(self, ch, args, &block)
|
950
|
+
unless rv.respond_to? :to_rant_target
|
951
|
+
abort_at(ch, "make: invalid generator return value")
|
952
|
+
end
|
953
|
+
build(rv.to_rant_target)
|
954
|
+
rv
|
955
|
+
else
|
956
|
+
ch = Rant::Lib.parse_caller_elem(caller[1])
|
957
|
+
abort_at(ch,
|
958
|
+
"make: generator or target as first argument required.")
|
959
|
+
end
|
960
|
+
end
|
961
|
+
public :make
|
962
|
+
|
899
963
|
# Invoke all tasks necessary to build +target+. Returns the number
|
900
964
|
# of tasks invoked.
|
901
|
-
def
|
965
|
+
def build(target, opt = {})
|
902
966
|
opt[:force] = true if @force_targets.delete(target)
|
903
967
|
matching_tasks = 0
|
904
968
|
old_subdir = @current_subdir
|
@@ -916,18 +980,24 @@ class Rant::RantApp
|
|
916
980
|
Dir.chdir old_pwd
|
917
981
|
matching_tasks
|
918
982
|
end
|
919
|
-
public :
|
920
|
-
alias build make
|
983
|
+
public :build
|
921
984
|
|
922
|
-
# Currently always returns an array (which might actually be
|
923
|
-
#
|
924
|
-
def resolve
|
985
|
+
# Currently always returns an array (which might actually be an
|
986
|
+
# empty array, but never nil).
|
987
|
+
def resolve(task_name, rel_project_dir = @current_subdir)
|
925
988
|
s = @tasks[expand_path(rel_project_dir, task_name)]
|
926
989
|
case s
|
927
990
|
when nil
|
928
991
|
@resolve_hooks.each { |s|
|
929
992
|
# Note: will probably change to get more params
|
930
993
|
s = s[task_name]
|
994
|
+
#if s
|
995
|
+
# puts s.size
|
996
|
+
# t = s.first
|
997
|
+
# puts t.full_name
|
998
|
+
# puts t.name
|
999
|
+
# puts t.deps
|
1000
|
+
#end
|
931
1001
|
return s if s
|
932
1002
|
}
|
933
1003
|
[]
|
@@ -942,7 +1012,7 @@ class Rant::RantApp
|
|
942
1012
|
# target. It may create one or more tasks for the target, which is
|
943
1013
|
# given as argument, on the fly and return an array of the created
|
944
1014
|
# tasks or nil.
|
945
|
-
def at_resolve
|
1015
|
+
def at_resolve(&block)
|
946
1016
|
@resolve_hooks << block if block
|
947
1017
|
end
|
948
1018
|
public :at_resolve
|
@@ -994,7 +1064,7 @@ class Rant::RantApp
|
|
994
1064
|
|
995
1065
|
# Returns the value of the last expression executed in +rantfile+.
|
996
1066
|
# +rantfile+ has to be an Rant::Rantfile instance.
|
997
|
-
def load_file
|
1067
|
+
def load_file(rantfile)
|
998
1068
|
msg 1, "source #{rantfile}"
|
999
1069
|
rv = nil
|
1000
1070
|
begin
|
@@ -1021,7 +1091,7 @@ class Rant::RantApp
|
|
1021
1091
|
# If dir is nil, look in current directory.
|
1022
1092
|
# Returns always an array with the pathes (not only the filenames)
|
1023
1093
|
# to the rantfiles.
|
1024
|
-
def rantfiles_in_dir
|
1094
|
+
def rantfiles_in_dir(dir=nil)
|
1025
1095
|
files = []
|
1026
1096
|
::Rant::RANTFILES.each { |rfn|
|
1027
1097
|
path = dir ? File.join(dir, rfn) : rfn
|
@@ -1038,7 +1108,7 @@ class Rant::RantApp
|
|
1038
1108
|
def process_args
|
1039
1109
|
# WARNING: we currently have to fool getoptlong,
|
1040
1110
|
# by temporory changing ARGV!
|
1041
|
-
# This could cause problems.
|
1111
|
+
# This could cause problems (e.g. multithreading).
|
1042
1112
|
old_argv = ARGV.dup
|
1043
1113
|
ARGV.replace(@args.dup)
|
1044
1114
|
cmd_opts = GetoptLong.new(*OPTIONS.collect { |lst| lst[0..-2] })
|
@@ -1089,14 +1159,15 @@ class Rant::RantApp
|
|
1089
1159
|
if targ.is_a? Hash
|
1090
1160
|
targ.reject! { |k, v| clr = v if k == :__caller__ }
|
1091
1161
|
end
|
1092
|
-
|
1162
|
+
ch = Hash === clr ? clr : Rant::Lib::parse_caller_elem(clr)
|
1093
1163
|
|
1094
|
-
name, pre
|
1164
|
+
name, pre = normalize_task_arg(targ, ch)
|
1095
1165
|
|
1096
|
-
file, is_new = rantfile_for_path(file)
|
1166
|
+
file, is_new = rantfile_for_path(ch[:file])
|
1097
1167
|
nt = yield(name, pre, block)
|
1098
1168
|
nt.rantfile = file
|
1099
|
-
|
1169
|
+
nt.project_subdir = file.project_subdir
|
1170
|
+
nt.line_number = ch[:ln]
|
1100
1171
|
nt.description = @task_desc
|
1101
1172
|
@task_desc = nil
|
1102
1173
|
file.tasks << nt
|
@@ -1105,7 +1176,7 @@ class Rant::RantApp
|
|
1105
1176
|
end
|
1106
1177
|
public :prepare_task
|
1107
1178
|
|
1108
|
-
def hash_task
|
1179
|
+
def hash_task(task)
|
1109
1180
|
n = task.full_name
|
1110
1181
|
#STDERR.puts "hash_task: `#{n}'"
|
1111
1182
|
et = @tasks[n]
|
@@ -1122,69 +1193,58 @@ class Rant::RantApp
|
|
1122
1193
|
|
1123
1194
|
# Tries to extract task name and prerequisites from the typical
|
1124
1195
|
# argument to the +task+ command. +targ+ should be one of String,
|
1125
|
-
# Symbol or Hash.
|
1126
|
-
# reporting and debugging.
|
1196
|
+
# Symbol or Hash. ch is the caller (hash with the elements :file
|
1197
|
+
# and :ln) and is used for error reporting and debugging.
|
1127
1198
|
#
|
1128
|
-
# Returns
|
1199
|
+
# Returns two values, the first is a string which is the task name
|
1129
1200
|
# and the second is an array with the prerequisites.
|
1130
|
-
# The third is the file name of +clr+, the fourth is the line number
|
1131
|
-
# of +clr+.
|
1132
1201
|
def normalize_task_arg(targ, ch)
|
1133
|
-
# pre 0.3.7: ch in parameter list was clr
|
1134
|
-
# TODO: check the code calling this method so that we can
|
1135
|
-
# assume clr is already a hash
|
1136
|
-
#ch = Hash === clr ? clr : Rant::Lib::parse_caller_elem(clr)
|
1137
|
-
|
1138
1202
|
name = nil
|
1139
1203
|
pre = []
|
1140
|
-
ln, file = ch[:ln], ch[:file]
|
1141
1204
|
|
1142
1205
|
# process and validate targ
|
1143
1206
|
if targ.is_a? Hash
|
1144
1207
|
if targ.empty?
|
1145
|
-
|
1146
|
-
"Empty hash as task argument, " +
|
1208
|
+
abort_at(ch, "Empty hash as task argument, " +
|
1147
1209
|
"task name required.")
|
1148
1210
|
end
|
1149
1211
|
if targ.size > 1
|
1150
|
-
|
1151
|
-
"Too many hash elements, " +
|
1212
|
+
abort_at(ch, "Too many hash elements, " +
|
1152
1213
|
"should only be one.")
|
1153
1214
|
end
|
1154
1215
|
targ.each_pair { |k,v|
|
1155
|
-
name = normalize_task_name(k,
|
1216
|
+
name = normalize_task_name(k, ch)
|
1156
1217
|
pre = v
|
1157
1218
|
}
|
1158
1219
|
unless ::Rant::FileList === pre
|
1159
1220
|
if pre.respond_to? :to_ary
|
1160
1221
|
pre = pre.to_ary.dup
|
1161
1222
|
pre.map! { |elem|
|
1162
|
-
normalize_task_name(elem,
|
1223
|
+
normalize_task_name(elem, ch)
|
1163
1224
|
}
|
1164
1225
|
else
|
1165
|
-
pre = [normalize_task_name(pre,
|
1226
|
+
pre = [normalize_task_name(pre, ch)]
|
1166
1227
|
end
|
1167
1228
|
end
|
1168
1229
|
else
|
1169
|
-
name = normalize_task_name(targ,
|
1230
|
+
name = normalize_task_name(targ, ch)
|
1170
1231
|
end
|
1171
1232
|
|
1172
|
-
[name, pre
|
1233
|
+
[name, pre]
|
1173
1234
|
end
|
1174
1235
|
public :normalize_task_arg
|
1175
1236
|
|
1176
1237
|
# Tries to make a task name out of arg and returns
|
1177
1238
|
# the valid task name. If not possible, calls abort
|
1178
1239
|
# with an appropriate error message using file and ln.
|
1179
|
-
def normalize_task_name(arg,
|
1240
|
+
def normalize_task_name(arg, ch)
|
1180
1241
|
return arg if arg.is_a? String
|
1181
1242
|
if Symbol === arg
|
1182
1243
|
arg.to_s
|
1183
1244
|
elsif arg.respond_to? :to_str
|
1184
1245
|
arg.to_str
|
1185
1246
|
else
|
1186
|
-
|
1187
|
-
"Task name has to be a string or symbol.")
|
1247
|
+
abort_at(ch, "Task name has to be a string or symbol.")
|
1188
1248
|
end
|
1189
1249
|
end
|
1190
1250
|
|
@@ -1192,7 +1252,7 @@ class Rant::RantApp
|
|
1192
1252
|
# and a boolean value as second. If the second is true,
|
1193
1253
|
# the rantfile was created and added, otherwise the rantfile
|
1194
1254
|
# already existed.
|
1195
|
-
def rantfile_for_path
|
1255
|
+
def rantfile_for_path(path)
|
1196
1256
|
# all rantfiles have an absolute path as path attribute
|
1197
1257
|
abs_path = File.expand_path(path)
|
1198
1258
|
if @rantfiles.any? { |rf| rf.path == abs_path }
|
@@ -1237,20 +1297,13 @@ class Rant::RantApp
|
|
1237
1297
|
t_msg = ["Task `#{e.tname}' fail."]
|
1238
1298
|
orig = e
|
1239
1299
|
loop { orig = orig.orig; break unless Rant::TaskFail === orig }
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
msg << orig.message << orig.backtrace[0..4]
|
1248
|
-
end
|
1249
|
-
elsif Rant::CommandError === orig
|
1250
|
-
msg << orig.message if @opts[:err_commands]
|
1251
|
-
elsif orig && !(Rant::RantAbortException === orig)
|
1252
|
-
msg << orig.message << orig.backtrace[0..4]
|
1253
|
-
end
|
1300
|
+
if orig && orig != e && !(Rant::RantAbortException === orig)
|
1301
|
+
ch = get_ch_from_backtrace(orig.backtrace)
|
1302
|
+
msg << pos_text(ch[:file], ch[:ln]) if ch
|
1303
|
+
unless Rant::CommandError === orig && !@opts[:err_commands]
|
1304
|
+
msg << orig.message
|
1305
|
+
msg << orig.backtrace[0..4] unless ch
|
1306
|
+
end
|
1254
1307
|
end
|
1255
1308
|
err_msg msg unless msg.empty?
|
1256
1309
|
err_msg t_msg
|