rant 0.4.0 → 0.4.2
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/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
|