rant 0.4.6 → 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- data/INSTALL +44 -0
- data/NEWS +30 -0
- data/README +6 -46
- data/Rantfile +38 -7
- data/doc/c.rdoc +2 -0
- data/doc/command.rdoc +210 -0
- data/doc/examples/c_dependencies/Rantfile +1 -1
- data/doc/examples/directedrule/Rantfile +1 -1
- data/doc/homepage/index.html +12 -1
- data/doc/rant-import.rdoc +5 -0
- data/doc/rant_vs_rake.rdoc +107 -0
- data/doc/rantfile.rdoc +17 -17
- data/doc/rubyproject.rdoc +45 -45
- data/doc/subdirs.rdoc +1 -1
- data/lib/rant/coregen.rb +62 -22
- data/lib/rant/import/archive.rb +1 -0
- data/lib/rant/import/command.rb +206 -0
- data/lib/rant/import/nodes/default.rb +12 -6
- data/lib/rant/import/nodes/signed.rb +3 -3
- data/lib/rant/import/signedfile.rb +14 -15
- data/lib/rant/import/win32/rubycmdwrapper.rb +1 -0
- data/lib/rant/import.rb +52 -4
- data/lib/rant/metautils.rb +119 -0
- data/lib/rant/node.rb +11 -2
- data/lib/rant/rantenv.rb +5 -2
- data/lib/rant/rantlib.rb +30 -46
- data/lib/rant/rantsys.rb +81 -13
- data/lib/rant/rantvar.rb +1 -76
- data/lib/rant.rb +2 -2
- data/misc/TODO +21 -0
- data/test/deprecated/test_0_5_2.rb +28 -0
- data/test/deprecated/test_0_6_0.rb +24 -0
- data/test/dyn_dependencies.rf +25 -0
- data/test/import/command/Rantfile +102 -0
- data/test/import/command/test_command.rb +597 -0
- data/test/rant-import/test_rant-import.rb +23 -1
- data/test/rule.rf +2 -0
- data/test/test_dyn_dependencies.rb +45 -0
- data/test/test_env.rb +5 -4
- data/test/test_filelist.rb +60 -3
- data/test/test_rant_interface.rb +5 -0
- data/test/test_sys.rb +53 -2
- data/test/tutil.rb +14 -6
- metadata +17 -6
- data/test/deprecated/test_0_4_8.rb +0 -41
data/doc/rantfile.rdoc
CHANGED
@@ -182,10 +182,10 @@ explain it a little bit. The +sys+ command can be used in three ways:
|
|
182
182
|
|
183
183
|
When the external program returns with an exit code other than 0,
|
184
184
|
Rant will abort with an error message. Sometimes this is not
|
185
|
-
desirable. E.g. the +diff
|
186
|
-
the files are equal, 1 if have differences and
|
187
|
-
error occurs. Rant allows you to handle/ignore
|
188
|
-
program yourself. Example:
|
185
|
+
desirable. E.g. the +diff+ program, which compares two files,
|
186
|
+
returns 0 if the files are equal, 1 if they have differences and
|
187
|
+
something else if an error occurs. Rant allows you to handle/ignore
|
188
|
+
the exit code of a program yourself. Example:
|
189
189
|
|
190
190
|
task :diff do |t|
|
191
191
|
sys "diff -u a/util.c b/util.c > util.diff" do |ps|
|
@@ -310,20 +310,20 @@ last dot with the given string.
|
|
310
310
|
=== Importing additional generators
|
311
311
|
|
312
312
|
The +import+ function lets you import additional generators.
|
313
|
-
Currently the following
|
314
|
-
Clean::
|
315
|
-
AutoClean::
|
316
|
-
|
317
|
-
DirectedRule::
|
318
|
-
|
319
|
-
|
320
|
-
SubFile::
|
321
|
-
RubyTest::
|
322
|
-
RubyDoc::
|
323
|
-
RubyPackage::
|
324
|
-
|
313
|
+
Currently the following come with Rant:
|
314
|
+
Clean:: Remove selected files.
|
315
|
+
AutoClean:: Remove all files generated by any file task (including
|
316
|
+
those generated by rules).
|
317
|
+
DirectedRule:: A Rule which takes sources from one or more
|
318
|
+
directories and puts generated files into a specified
|
319
|
+
directory.
|
320
|
+
SubFile:: Create file task and necessary directory tasks.
|
321
|
+
RubyTest:: Run Test::Unit tests for your Ruby code.
|
322
|
+
RubyDoc:: Run RDoc.
|
323
|
+
RubyPackage:: Generate tar, zip and gem packages of your Ruby
|
324
|
+
application/library.
|
325
325
|
Win32::RubyCmdWrapper:: Create .cmd wrapper scripts for installation
|
326
|
-
|
326
|
+
of Ruby scripts on Windows.
|
327
327
|
|
328
328
|
Read doc/advanced.rdoc[link:files/doc/advanced_rdoc.html] and
|
329
329
|
doc/rubyproject.rdoc[link:files/doc/rubyproject_rdoc.html] for
|
data/doc/rubyproject.rdoc
CHANGED
@@ -8,11 +8,11 @@ We are assuming a project with the following directories and files:
|
|
8
8
|
Rantfile
|
9
9
|
README
|
10
10
|
bin/
|
11
|
-
|
11
|
+
wgrep
|
12
12
|
lib/
|
13
|
-
|
13
|
+
wgrep.rb
|
14
14
|
test/
|
15
|
-
|
15
|
+
tc_wgrep.rb
|
16
16
|
You can find this little project in test/project_rb1 directory of the
|
17
17
|
Rant package. You'll probably have more files in your project, but we
|
18
18
|
will try to write our Rantfile as generic as possible:
|
@@ -20,27 +20,27 @@ will try to write our Rantfile as generic as possible:
|
|
20
20
|
import %w(rubytest rubydoc rubypackage clean)
|
21
21
|
|
22
22
|
lib_files = sys["lib/**/*.rb"]
|
23
|
-
dist_files = lib_files +
|
23
|
+
dist_files = lib_files + sys["README", "rantfile.rb", "{test,bin}/*"]
|
24
24
|
|
25
25
|
desc "Run unit tests."
|
26
26
|
gen RubyTest do |t|
|
27
|
-
|
28
|
-
|
27
|
+
t.test_dir = "test"
|
28
|
+
t.pattern = "tc_*.rb"
|
29
29
|
end
|
30
30
|
|
31
31
|
desc "Generate html documentation."
|
32
32
|
gen RubyDoc do |t|
|
33
|
-
|
33
|
+
t.opts = %w(--title wgrep --main README README)
|
34
34
|
end
|
35
35
|
|
36
36
|
desc "Create packages."
|
37
37
|
gen RubyPackage, "wgrep" do |t|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
t.version = "1.0.0"
|
39
|
+
t.summary = "Simple grep program."
|
40
|
+
t.files = dist_files
|
41
|
+
t.bindir = "bin"
|
42
|
+
t.executable = "wgrep"
|
43
|
+
t.package_task
|
44
44
|
end
|
45
45
|
|
46
46
|
desc "Remove autogenerated and backup files."
|
@@ -73,8 +73,8 @@ collect the testcases and then runs the _testrb_ command.
|
|
73
73
|
To format the documentation:
|
74
74
|
% rant doc
|
75
75
|
|
76
|
-
|
77
|
-
|
76
|
+
README:
|
77
|
+
wgrep.rb: mcc....
|
78
78
|
Generating HTML...
|
79
79
|
|
80
80
|
Files: 2
|
@@ -150,9 +150,9 @@ you can set the +pkg_dir+ attribute:
|
|
150
150
|
Perhaps you want to specify explicetely what packages you want to
|
151
151
|
build. To accomplish this, each of the following methods listed takes
|
152
152
|
an optional task name as argument:
|
153
|
-
t.tar_task
|
154
|
-
t.zip_task
|
155
|
-
t.gem_task
|
153
|
+
t.tar_task # create tar.gz archive, task name defaults to "tar"
|
154
|
+
t.zip_task # create zip archive, task name defaults to "zip"
|
155
|
+
t.gem_task # create gem, task name defaults to "gem"
|
156
156
|
An example would be:
|
157
157
|
desc "Create tar.gz package."
|
158
158
|
t.tar_task :archive
|
@@ -166,28 +166,28 @@ An example would be:
|
|
166
166
|
In our example we had only a few attributes for our package. Here are
|
167
167
|
following two lists with the available attributes.
|
168
168
|
* Attributes that take a single argument:
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
169
|
+
name
|
170
|
+
date
|
171
|
+
description
|
172
|
+
email
|
173
|
+
has_rdoc
|
174
|
+
homepage
|
175
|
+
platform
|
176
|
+
required_ruby_version
|
177
|
+
rubyforge_project
|
178
|
+
summary
|
179
|
+
version
|
180
180
|
* Attributes that take one or more values (if you give a single value
|
181
181
|
it will automatically be converted to a list):
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
182
|
+
author
|
183
|
+
bindir
|
184
|
+
executable
|
185
|
+
extension
|
186
|
+
files
|
187
|
+
rdoc_options
|
188
|
+
requires
|
189
|
+
test_files
|
190
|
+
test_suite
|
191
191
|
The attributes can also be set without the assignment operator:
|
192
192
|
t.executable "mybin"
|
193
193
|
|
@@ -202,11 +202,11 @@ task name. The output directory for the html files defaults to +doc+.
|
|
202
202
|
To change this set the +dir+ attribute:
|
203
203
|
desc "Generate html documentation."
|
204
204
|
gen RubyDoc, :html do |t|
|
205
|
-
|
205
|
+
t.dir = "doc/html"
|
206
206
|
As rant invokes RDoc programmatically, no command is printed when the
|
207
207
|
task is run. If you want to see one, set the verbose attribute to
|
208
208
|
+true+:
|
209
|
-
|
209
|
+
t.verbose = true
|
210
210
|
|
211
211
|
=== Installation
|
212
212
|
|
@@ -224,14 +224,14 @@ lines to your Rantfile:
|
|
224
224
|
|
225
225
|
desc "Install wgrep."
|
226
226
|
task :install do
|
227
|
-
|
228
|
-
|
227
|
+
# Run setup.rb with the Ruby interpreter.
|
228
|
+
sys.ruby "setup.rb"
|
229
229
|
end
|
230
230
|
|
231
231
|
if Env.on_windows?
|
232
|
-
|
233
|
-
|
234
|
-
|
232
|
+
# Create .cmd files for all scripts in the bin/ directory and
|
233
|
+
# make the install task dependent on them.
|
234
|
+
enhance :install => (gen Win32::RubyCmdWrapper, sys["bin/*"])
|
235
235
|
end
|
236
236
|
|
237
237
|
== See also
|
data/doc/subdirs.rdoc
CHANGED
@@ -123,7 +123,7 @@ To run the IO related tests from the test directory we type:
|
|
123
123
|
testrb tc_reader.rb tc_writer.rb
|
124
124
|
... output of testrb ...
|
125
125
|
|
126
|
-
To run the clobber task from the
|
126
|
+
To run the clobber task from the toplevel directory:
|
127
127
|
|
128
128
|
<test> $ rant @clobber
|
129
129
|
(root is /home/stefan/Ruby/misc/rant/rbtest, in test)
|
data/lib/rant/coregen.rb
CHANGED
@@ -98,7 +98,7 @@ module Rant
|
|
98
98
|
}
|
99
99
|
end
|
100
100
|
end
|
101
|
-
class Rule
|
101
|
+
class Rule
|
102
102
|
# Generate a rule by installing an at_resolve hook for
|
103
103
|
# +rac+.
|
104
104
|
def self.rant_gen(rac, ch, args, &block)
|
@@ -136,48 +136,88 @@ module Rant
|
|
136
136
|
"to be a string or regular expression")
|
137
137
|
end
|
138
138
|
src_proc = case src_arg
|
139
|
-
when String
|
139
|
+
when String, Array
|
140
140
|
unless String === target
|
141
141
|
rac.abort(ch, "rule target has to be " +
|
142
142
|
"a string if source is a string")
|
143
143
|
end
|
144
|
-
|
144
|
+
if src_arg.kind_of? String
|
145
|
+
lambda { |name|
|
146
|
+
name.sub(/#{esc_target}$/, src_arg)
|
147
|
+
}
|
148
|
+
else
|
149
|
+
lambda { |name|
|
150
|
+
src_arg.collect { |s_src|
|
151
|
+
s_src = ".#{s_src}" if Symbol === s_src
|
152
|
+
name.sub(/#{esc_target}$/, s_src)
|
153
|
+
}
|
154
|
+
}
|
155
|
+
end
|
145
156
|
when Proc: src_arg
|
146
157
|
when nil: lambda { |name| [] }
|
147
158
|
else
|
148
|
-
rac.abort_at(ch, "rule source has to be " +
|
149
|
-
"String or Proc")
|
159
|
+
rac.abort_at(ch, "rule source has to be a " +
|
160
|
+
"String, Array or Proc")
|
150
161
|
end
|
151
|
-
|
152
|
-
|
162
|
+
rac.resolve_hooks <<
|
163
|
+
(block.arity == 2 ? Hook : FileHook).new(
|
164
|
+
rac, ch, target_rx, src_proc, block)
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
class Hook
|
168
|
+
attr_accessor :target_rx
|
169
|
+
def initialize(rant, ch, target_rx, src_proc, block)
|
170
|
+
@rant = rant
|
171
|
+
@ch = ch
|
172
|
+
@target_rx = target_rx
|
173
|
+
@src_proc = src_proc
|
174
|
+
@block = block
|
175
|
+
end
|
176
|
+
def call(target, rel_project_dir)
|
177
|
+
if @target_rx =~ target
|
153
178
|
have_src = true
|
154
|
-
src = src_proc[
|
179
|
+
src = @src_proc[target]
|
155
180
|
if src.respond_to? :to_ary
|
156
181
|
src.each { |f|
|
157
|
-
if
|
182
|
+
if @rant.resolve(f).empty? && !test(?e, f)
|
158
183
|
have_src = false
|
159
184
|
break
|
160
185
|
end
|
161
186
|
}
|
162
187
|
else
|
163
|
-
if
|
188
|
+
if @rant.resolve(src).empty? && !test(?e, src)
|
164
189
|
have_src = false
|
165
190
|
end
|
166
191
|
end
|
167
192
|
if have_src
|
168
|
-
|
169
|
-
task_name => src_proc[task_name], &block)
|
170
|
-
t.project_subdir = rac.current_subdir
|
171
|
-
[t]
|
193
|
+
create_nodes(rel_project_dir, target, src)
|
172
194
|
end
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
195
|
+
end
|
196
|
+
end
|
197
|
+
alias [] call
|
198
|
+
private
|
199
|
+
def create_nodes(rel_project_dir, target, deps)
|
200
|
+
case nodes = @block[target, deps]
|
201
|
+
when Array: nodes
|
202
|
+
when Node: [nodes]
|
203
|
+
else
|
204
|
+
@rant.abort_at(@ch, "Block has to " +
|
205
|
+
"return Node or array of Nodes.")
|
206
|
+
end.each { |node|
|
207
|
+
node.project_subdir = @rant.current_subdir
|
208
|
+
}
|
209
|
+
end
|
210
|
+
end
|
211
|
+
class FileHook < Hook
|
212
|
+
private
|
213
|
+
def create_nodes(rel_project_dir, target, deps)
|
214
|
+
t = @rant.file(:__caller__ => @ch,
|
215
|
+
target => deps, &@block)
|
216
|
+
t.project_subdir = @rant.current_subdir
|
217
|
+
[t]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end # class Rule
|
181
221
|
class Action
|
182
222
|
def self.rant_gen(rac, ch, args, &block)
|
183
223
|
unless args.empty?
|
data/lib/rant/import/archive.rb
CHANGED
@@ -0,0 +1,206 @@
|
|
1
|
+
|
2
|
+
# command.rb - File tasks with command change recognition.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at>
|
5
|
+
|
6
|
+
#require 'rant/import/metadata' #rant-import:uncomment
|
7
|
+
#require 'rant/import/signature/md5' #rant-import:uncomment
|
8
|
+
|
9
|
+
module Rant
|
10
|
+
def self.init_import_command(rant, *rest)
|
11
|
+
rant.import "metadata" unless rant.var._get("__metadata__")
|
12
|
+
rant.import "signature/md5" unless rant.var._get("__signature__")
|
13
|
+
end
|
14
|
+
module Generators
|
15
|
+
class Command
|
16
|
+
def self.rant_gen(rant, ch, args, &block)
|
17
|
+
if args.size == 1 && block
|
18
|
+
return \
|
19
|
+
rant.prepare_task(args.first, nil, ch) { |n,pre,_|
|
20
|
+
t = rant.node_factory.new_file(rant, n, pre, nil)
|
21
|
+
t.receiver = CommandManager.new(nil, block)
|
22
|
+
t
|
23
|
+
}
|
24
|
+
elsif args.size < 2
|
25
|
+
rant.abort_at(ch, "Command: At least two " +
|
26
|
+
"arguments required: task name and command.")
|
27
|
+
elsif args.size > 3
|
28
|
+
rant.abort_at(ch, "Command: Too many arguments.")
|
29
|
+
end
|
30
|
+
# determine task name
|
31
|
+
name = args.shift
|
32
|
+
if name.respond_to? :to_str
|
33
|
+
name = name.to_str
|
34
|
+
else
|
35
|
+
rant.abort_at(ch, "Command: task name (string) " +
|
36
|
+
"as first argument required")
|
37
|
+
end
|
38
|
+
if args.size == 1 && args.first.respond_to?(:to_hash)
|
39
|
+
parse_keyword_syntax(rant, ch,
|
40
|
+
name, block, args[0].to_hash)
|
41
|
+
else
|
42
|
+
parse_plain_syntax(rant, ch,
|
43
|
+
name, block, args[0], args[1])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
def self.parse_plain_syntax(rant, ch, name, block, pre, cmd)
|
47
|
+
# determine prerequisites
|
48
|
+
pre ||= []
|
49
|
+
# determine command
|
50
|
+
(cmd = pre; pre = []) unless cmd
|
51
|
+
if cmd.respond_to? :to_str
|
52
|
+
cmd = cmd.to_str
|
53
|
+
else
|
54
|
+
rant.abort_at(ch, "Command: command argument has " +
|
55
|
+
"to be a string.")
|
56
|
+
end
|
57
|
+
rant.prepare_task({name => pre}, nil, ch) { |n,pre,_|
|
58
|
+
t = rant.node_factory.new_file(rant, n, pre, nil)
|
59
|
+
t.receiver = CommandManager.new(cmd, block)
|
60
|
+
t
|
61
|
+
}
|
62
|
+
end
|
63
|
+
def self.parse_keyword_syntax(rant, ch, name, block, hash)
|
64
|
+
# TODO
|
65
|
+
rant.abort_at(ch, "Command: syntax error")
|
66
|
+
end
|
67
|
+
end # class Command
|
68
|
+
end # module Generators
|
69
|
+
module Node
|
70
|
+
def interp_vars!(str)
|
71
|
+
str.gsub!(/\$\((\w+)\)/) { |_|
|
72
|
+
val = val_for_interp_var($1)
|
73
|
+
unless val.respond_to?(:to_ary)
|
74
|
+
val = val.to_s
|
75
|
+
interp_vars!(val)
|
76
|
+
end
|
77
|
+
Sys.sp(val)
|
78
|
+
}
|
79
|
+
str.gsub!(/\$\{(\w+)\}/) { |_|
|
80
|
+
val = val_for_interp_var($1)
|
81
|
+
unless val.respond_to?(:to_ary)
|
82
|
+
val = val.to_s
|
83
|
+
interp_vars!(val)
|
84
|
+
end
|
85
|
+
Sys.escape(val)
|
86
|
+
}
|
87
|
+
str.gsub!(/\$\[(\w+)\]/) { |_|
|
88
|
+
val = val_for_interp_var($1)
|
89
|
+
if val.respond_to?(:to_ary)
|
90
|
+
val.to_ary.join(' ')
|
91
|
+
else
|
92
|
+
val = val.to_s
|
93
|
+
interp_vars!(val)
|
94
|
+
end
|
95
|
+
val
|
96
|
+
}
|
97
|
+
str
|
98
|
+
end
|
99
|
+
def interp_symbolic_vars!(str)
|
100
|
+
str.gsub!(/\$\((-|<|>)\)/) { |_|
|
101
|
+
Sys.sp(val_for_interp_sym($1))
|
102
|
+
}
|
103
|
+
str.gsub!(/\$\{(-|<|>)\}/) { |_|
|
104
|
+
Sys.escape(val_for_interp_sym($1))
|
105
|
+
}
|
106
|
+
str.gsub!(/\$\[(-|<|>)\]/) { |_|
|
107
|
+
val = val_for_interp_sym($1)
|
108
|
+
val.respond_to?(:to_ary) ? val.to_ary.join(' ') : val.to_s
|
109
|
+
}
|
110
|
+
str
|
111
|
+
end
|
112
|
+
private
|
113
|
+
def val_for_interp_var(var)
|
114
|
+
case var
|
115
|
+
when "name": self.name
|
116
|
+
when "prerequisites": self.prerequisites
|
117
|
+
when "source": self.source
|
118
|
+
else
|
119
|
+
cx = rac.cx
|
120
|
+
val = cx.var._get(var) || (
|
121
|
+
if cx.instance_eval("defined? @#{var}")
|
122
|
+
cx.instance_variable_get "@#{var}"
|
123
|
+
else
|
124
|
+
rac.warn_msg(rac.pos_text(
|
125
|
+
rantfile.path, line_number),
|
126
|
+
"Command: undefined variable `#{var}'")
|
127
|
+
""
|
128
|
+
end
|
129
|
+
)
|
130
|
+
if val.respond_to?(:call) && val.respond_to?(:arity)
|
131
|
+
val.arity == 0 ? val.call : val.call(self)
|
132
|
+
elsif val.respond_to?(:to_hash)
|
133
|
+
rac.warn_msg(
|
134
|
+
"`#{var}' -- Avoid interpolation of hashes.\n" +
|
135
|
+
"Behaviour is undecided.")
|
136
|
+
""
|
137
|
+
#val.to_hash[full_name]
|
138
|
+
else
|
139
|
+
val
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
def val_for_interp_sym(sym)
|
144
|
+
case sym
|
145
|
+
when ">": name
|
146
|
+
when "<": prerequisites
|
147
|
+
when "-": source
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
class CommandManager
|
152
|
+
def initialize(cmd_str, cmd_block)
|
153
|
+
@cmd_str = cmd_str
|
154
|
+
@cmd_block = cmd_block
|
155
|
+
@command = nil
|
156
|
+
end
|
157
|
+
def update?(node)
|
158
|
+
res_command(node)
|
159
|
+
@command_changed
|
160
|
+
end
|
161
|
+
def has_pre_action?
|
162
|
+
true
|
163
|
+
end
|
164
|
+
def pre_run(node)
|
165
|
+
dir = File.dirname(node.name)
|
166
|
+
unless dir == "." || dir == "/"
|
167
|
+
node.rac.build dir, :type => :file
|
168
|
+
end
|
169
|
+
@command.split(/\n/).each { |cmd| node.rac.sys cmd }
|
170
|
+
if @command_changed
|
171
|
+
node.goto_task_home
|
172
|
+
@md.path_set(@cmd_key, @new_sig, node.name)
|
173
|
+
end
|
174
|
+
@command_changed = @cmd_key = @new_sig = @md = nil
|
175
|
+
end
|
176
|
+
private
|
177
|
+
def res_command(node)
|
178
|
+
return if @command
|
179
|
+
@command =
|
180
|
+
if @cmd_block
|
181
|
+
cmd = (@cmd_block.arity == 0 ?
|
182
|
+
@cmd_block.call :
|
183
|
+
@cmd_block[node])
|
184
|
+
if cmd.respond_to? :to_str
|
185
|
+
cmd.to_str.dup
|
186
|
+
else
|
187
|
+
node.rac.abort_at(node.ch,
|
188
|
+
"Command: block has to return command string.")
|
189
|
+
end
|
190
|
+
else
|
191
|
+
node.interp_vars!(@cmd_str.to_str.dup)
|
192
|
+
end
|
193
|
+
var = node.rac.var
|
194
|
+
@md = var._get "__metadata__"
|
195
|
+
sigs = var._get "__signature__"
|
196
|
+
@cmd_key = "command_sig_#{sigs.name}"
|
197
|
+
old_sig = @md.path_fetch(@cmd_key, node.name)
|
198
|
+
sig_str = @command.gsub(/( |\t)+/, ' ')
|
199
|
+
sig_str.gsub!(/\[#.*?#\]/, '')
|
200
|
+
@command.gsub!(/\[#(.*?)#\]/) { |_| $1 }
|
201
|
+
node.interp_symbolic_vars!(@command)
|
202
|
+
@new_sig = sigs.signature_for_string(sig_str)
|
203
|
+
@command_changed = old_sig != @new_sig
|
204
|
+
end
|
205
|
+
end # class CommandManager
|
206
|
+
end # module Rant
|
@@ -33,6 +33,8 @@ module Rant
|
|
33
33
|
class Task
|
34
34
|
include Node
|
35
35
|
|
36
|
+
attr_accessor :receiver
|
37
|
+
|
36
38
|
def initialize(rac, name, prerequisites = [], &block)
|
37
39
|
super()
|
38
40
|
@rac = rac or raise ArgumentError, "rac not given"
|
@@ -46,6 +48,7 @@ module Rant
|
|
46
48
|
# false invoked, but fail
|
47
49
|
# true invoked and run successfully
|
48
50
|
@success = nil
|
51
|
+
@receiver = nil
|
49
52
|
end
|
50
53
|
|
51
54
|
# Get a list of the *names* of all prerequisites. The
|
@@ -64,7 +67,7 @@ module Rant
|
|
64
67
|
# True if this task has at least one action (block to be
|
65
68
|
# executed) associated.
|
66
69
|
def has_actions?
|
67
|
-
|
70
|
+
@block or @receiver && @receiver.has_pre_action?
|
68
71
|
end
|
69
72
|
|
70
73
|
# Add a prerequisite.
|
@@ -141,9 +144,13 @@ module Rant
|
|
141
144
|
dep
|
142
145
|
end
|
143
146
|
}
|
147
|
+
if @receiver
|
148
|
+
goto_task_home
|
149
|
+
update = true if @receiver.update?(self)
|
150
|
+
end
|
144
151
|
# Never run a task block for a "needed?" query.
|
145
152
|
return update if opt[:needed?]
|
146
|
-
|
153
|
+
run if update
|
147
154
|
@success = true
|
148
155
|
# IMPORTANT: return update flag
|
149
156
|
update
|
@@ -501,8 +508,7 @@ module Rant
|
|
501
508
|
if File.exist?(@name)
|
502
509
|
@ts = File.mtime @name
|
503
510
|
else
|
504
|
-
rac.
|
505
|
-
"SourceNode: no such file -- #@name")
|
511
|
+
rac.abort_at(ch, "SourceNode: no such file -- #@name")
|
506
512
|
end
|
507
513
|
sd = project_subdir
|
508
514
|
@pre.each { |f|
|
@@ -512,7 +518,7 @@ module Rant
|
|
512
518
|
mtime = File.mtime f
|
513
519
|
@ts = mtime if mtime > @ts
|
514
520
|
else
|
515
|
-
rac.
|
521
|
+
rac.abort_at(ch,
|
516
522
|
"SourceNode: no such file -- #{f}")
|
517
523
|
end
|
518
524
|
else
|
@@ -523,7 +529,7 @@ module Rant
|
|
523
529
|
goto_task_home
|
524
530
|
@ts = node_ts if node_ts > @ts
|
525
531
|
else
|
526
|
-
rac.
|
532
|
+
rac.abort_at(ch,
|
527
533
|
"SourceNode can't depend on #{node.name}")
|
528
534
|
end
|
529
535
|
}
|
@@ -42,7 +42,7 @@ module Rant
|
|
42
42
|
if test(?f, @name)
|
43
43
|
@signature = sig.signature_for_file(@name)
|
44
44
|
else
|
45
|
-
@rac.
|
45
|
+
@rac.abort_at(ch,
|
46
46
|
"SourceNode: no such file -- #@name")
|
47
47
|
end
|
48
48
|
sd = project_subdir
|
@@ -55,7 +55,7 @@ module Rant
|
|
55
55
|
if test(?f, f)
|
56
56
|
sig_list << sig.signature_for_file(f)
|
57
57
|
else
|
58
|
-
rac.
|
58
|
+
rac.abort_at(ch,
|
59
59
|
"SourceNode: no such file -- #{f}")
|
60
60
|
end
|
61
61
|
else
|
@@ -66,7 +66,7 @@ module Rant
|
|
66
66
|
sig_list << node.signature
|
67
67
|
goto_task_home
|
68
68
|
else
|
69
|
-
rac.
|
69
|
+
rac.abort_at(ch,
|
70
70
|
"SourceNode can't depend on #{node.name}")
|
71
71
|
end
|
72
72
|
}
|