rant 0.4.6 → 0.4.8
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/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
|
}
|