rant 0.4.8 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +31 -0
- data/README +3 -1
- data/Rantfile +53 -2
- data/doc/advanced.rdoc +86 -1
- data/doc/c.rdoc +8 -0
- data/doc/homepage/index.html +2 -0
- data/doc/rant.1 +4 -0
- data/doc/rant.rdoc +38 -0
- data/doc/rant_vs_rake.rdoc +13 -0
- data/doc/rantfile.rdoc +93 -63
- data/doc/sys.rdoc +568 -0
- data/lib/rant/coregen.rb +43 -16
- data/lib/rant/import/command.rb +7 -4
- data/lib/rant/import/filelist/more.rb +57 -0
- data/lib/rant/import/metadata.rb +5 -1
- data/lib/rant/import/nodes/default.rb +3 -24
- data/lib/rant/import/signedfile.rb +1 -8
- data/lib/rant/import/sys/more.rb +2 -1
- data/lib/rant/import/var/booleans.rb +65 -0
- data/lib/rant/import/var/lists.rb +34 -0
- data/lib/rant/import/var/numbers.rb +116 -0
- data/lib/rant/import/var/strings.rb +43 -0
- data/lib/rant/import.rb +19 -3
- data/lib/rant/node.rb +39 -6
- data/lib/rant/rantlib.rb +44 -8
- data/lib/rant/rantsys.rb +22 -54
- data/lib/rant/rantvar.rb +89 -256
- data/misc/TODO +18 -0
- data/misc/devel-notes +26 -1
- data/test/action.rant +24 -0
- data/test/deprecated/test_0_5_4.rb +53 -0
- data/test/deprecated/test_0_6_0.rb +1 -1
- data/test/dryrun/Rantfile +10 -0
- data/test/dryrun/foo.c +8 -0
- data/test/dryrun/test_dryrun.rb +31 -0
- data/test/import/c/dependencies/Rantfile +1 -1
- data/test/import/command/Rantfile +1 -1
- data/test/import/sys/test_tgz.rb +22 -0
- data/test/subdirs2/root.rant +11 -1
- data/test/subdirs2/sub1/sub.rant +3 -0
- data/test/subdirs2/test_subdirs2.rb +19 -0
- data/test/test_action.rb +75 -0
- data/test/test_filelist.rb +13 -10
- data/test/test_rant_interface.rb +2 -2
- data/test/test_rule.rb +121 -3
- data/test/test_sys_methods.rb +558 -0
- data/test/test_var.rb +10 -0
- data/test/tutil.rb +81 -8
- metadata +19 -2
data/doc/sys.rdoc
ADDED
@@ -0,0 +1,568 @@
|
|
1
|
+
|
2
|
+
== sys methods
|
3
|
+
|
4
|
+
The +sys+ object, which is accessible from anywhere in an Rantfile,
|
5
|
+
provides many methods for common file system operations like deleting,
|
6
|
+
copying, moving, comparing and writing files.
|
7
|
+
|
8
|
+
Unless explicitely mentioned otherwise, the following statements apply
|
9
|
+
to all below documented methods:
|
10
|
+
|
11
|
+
1. Portable across all supported platforms.
|
12
|
+
2. Ignore the return value!
|
13
|
+
3. The messages printed to standard output may change.
|
14
|
+
4. Error conditions are reported through exceptions of class
|
15
|
+
+SystemCallError+ or subclasses of +SystemCallError+.
|
16
|
+
|
17
|
+
The following methods print messages to standard output:
|
18
|
+
|
19
|
+
* <b>cd(dir)</b>
|
20
|
+
|
21
|
+
Change the current directory to +dir+. +dir+ may be an absolute path
|
22
|
+
or a path relative to the current directory.
|
23
|
+
If a block is given, the current directory will be changed to +dir+,
|
24
|
+
then the block is executed and it is ensured, that after block
|
25
|
+
execution the old working directory is resumed (even if an exception
|
26
|
+
is thrown during block execution).
|
27
|
+
|
28
|
+
Examples:
|
29
|
+
|
30
|
+
# relative path
|
31
|
+
sys.pwd # => "/home/user"
|
32
|
+
sys.cd "tmp" # prints "cd tmp"
|
33
|
+
sys.pwd # => "/home/user/tmp"
|
34
|
+
sys.cd ".." # prints "cd .."
|
35
|
+
sys.pwd # => "/home/user"
|
36
|
+
|
37
|
+
# absolute path
|
38
|
+
sys.cd "/etc" # prints "cd /etc"
|
39
|
+
sys.pwd # => "/etc"
|
40
|
+
|
41
|
+
# relative path, with block
|
42
|
+
sys.pwd # => "/home/user"
|
43
|
+
sys.cd "tmp" do
|
44
|
+
sys.pwd # => "/home/user/tmp"
|
45
|
+
# perform some operations, may
|
46
|
+
# also call sys.cd
|
47
|
+
sys.cd "/etc"
|
48
|
+
end
|
49
|
+
sys.pwd # => "/home/user"
|
50
|
+
|
51
|
+
* <b>rm(file)</b>
|
52
|
+
|
53
|
+
Remove +file+. +file+ may be an absolute or relative path (string).
|
54
|
+
If +file+ is an array of strings or a filelist, remove all entries
|
55
|
+
of +file+.
|
56
|
+
|
57
|
+
Examples:
|
58
|
+
|
59
|
+
# remove the file "util.o" in the current directory
|
60
|
+
sys.rm "util.o" # prints "rm util.o"
|
61
|
+
|
62
|
+
# remove all files ending in ".o" in the "lib" directory
|
63
|
+
sys.rm sys["lib/*.o"]
|
64
|
+
|
65
|
+
Raises a +SystemCallError+ if +file+ doesn't exist or is a
|
66
|
+
directory.
|
67
|
+
|
68
|
+
* <b>rm_f(file)</b>
|
69
|
+
|
70
|
+
Same as <tt>rm(file)</tt>, but doesn't throw an exception if +file+
|
71
|
+
doesn't exist.
|
72
|
+
|
73
|
+
Example:
|
74
|
+
|
75
|
+
# remove "main.o" if it exists
|
76
|
+
sys.rm_f "main.o" # prints "rm -f main.o"
|
77
|
+
|
78
|
+
* <b>rmdir(dir)</b>
|
79
|
+
|
80
|
+
Remove the empty directory +dir+. +dir+ may be a list of strings, a
|
81
|
+
filelist or a string. Raises a +SystemCallError+ if +dir+ is not
|
82
|
+
empty or doesn't exist.
|
83
|
+
|
84
|
+
Examples:
|
85
|
+
|
86
|
+
# remove empty directory "/home/user/tmp"
|
87
|
+
sys.rmdir "/home/user/tmp"
|
88
|
+
|
89
|
+
# remove empty directory, relative path
|
90
|
+
sys.rmdir "tmp"
|
91
|
+
|
92
|
+
# remove empty directories "tmp" and "/usr/local/tmp"
|
93
|
+
sys.rmdir ["tmp", "/usr/local/tmp"]
|
94
|
+
|
95
|
+
# remove all (empty) directories in the current directory ending
|
96
|
+
# in ".t"
|
97
|
+
sys.rmdir sys["*.t"]
|
98
|
+
|
99
|
+
* <b>rm_r(entry)</b>
|
100
|
+
|
101
|
+
If +entry+ is a (relative or absolute) path to a file, simply
|
102
|
+
removes the file. If +entry+ is a directory, remove the directory
|
103
|
+
and all its contents (including subdirectories).
|
104
|
+
|
105
|
+
If +entry+ is an array of pathes or a filelist, remove all entries
|
106
|
+
listed in +entry+ (directories are removed, including their
|
107
|
+
contents, too).
|
108
|
+
|
109
|
+
Examples:
|
110
|
+
|
111
|
+
# remove the "tmp" directory and all its contents
|
112
|
+
sys.rm_r "tmp" # prints "rm -r tmp"
|
113
|
+
|
114
|
+
Raises a +SystemCallError+ if +entry+ doesn't exist.
|
115
|
+
|
116
|
+
* <b>rm_rf(entry)</b>
|
117
|
+
|
118
|
+
Does the same as <tt>rm_r(entry)</tt>, but doesn't raise an
|
119
|
+
exception if +entry+ doens't exist.
|
120
|
+
|
121
|
+
Example:
|
122
|
+
|
123
|
+
# remove the "tmp" directory and all its contents if it exists
|
124
|
+
sys.rm_rf "tmp" # prints "rm -rf tmp"
|
125
|
+
|
126
|
+
* <b>mkdir(dir)</b>
|
127
|
+
|
128
|
+
If +dir+ is a string, create the new directory +dir+. +dir+ may be a
|
129
|
+
relative or absolute path.
|
130
|
+
|
131
|
+
Examples:
|
132
|
+
|
133
|
+
# relative path
|
134
|
+
sys.mkdir "foo"
|
135
|
+
|
136
|
+
# absolute path
|
137
|
+
sys.mkdir "/home/user/foo"
|
138
|
+
|
139
|
+
If +dir+ is a list of strings, or a filelist, create all directories
|
140
|
+
listed in +dir+.
|
141
|
+
|
142
|
+
Example:
|
143
|
+
|
144
|
+
# with array, creates directory "foo" and directory "bar"
|
145
|
+
sys.mkdir ["foo", "bar"]
|
146
|
+
|
147
|
+
Raises a +SystemCallError+ if a file/directory with this name
|
148
|
+
already exists.
|
149
|
+
|
150
|
+
* <b>mkdir_p(dir)</b>
|
151
|
+
|
152
|
+
Creates the directory +dir+ and all its parent directories, if
|
153
|
+
necessary. Does nothing if +dir+ already exists.
|
154
|
+
|
155
|
+
If +dir+ is an array/filelist, creates all directories listed in
|
156
|
+
+dir+.
|
157
|
+
|
158
|
+
Examples:
|
159
|
+
|
160
|
+
# creates "/usr" if a directory of this name doesn't exist
|
161
|
+
# creates "/usr/local" if a directory of this name doesn't exist
|
162
|
+
# creates "/usr/local/bin" if a directory of this name doesn't exist
|
163
|
+
sys.mkdir_p "/usr/local/bin" # prints "mkdir -p /usr/local/bin"
|
164
|
+
|
165
|
+
# creates the three given pathes
|
166
|
+
sys.mkdir_p ["foo/include", "foo/src/util", "foo/src/ui"]
|
167
|
+
|
168
|
+
* <b>cp(src, dest)</b>
|
169
|
+
|
170
|
+
If +src+ is a (relative or absolute) path to a file, copy the file
|
171
|
+
+src+ to +dest+.
|
172
|
+
|
173
|
+
Example:
|
174
|
+
|
175
|
+
# copy "main.c" to "build/main.c"
|
176
|
+
sys.cp "main.c", "build/main.c" # prints "cp main.c build/main.c"
|
177
|
+
|
178
|
+
If +dest+ is a directory, copy +src+ to <tt>dest/src</tt>.
|
179
|
+
If +src+ is an array of strings or a filelist, copy all files listed
|
180
|
+
in +src+ to the directory +dest+.
|
181
|
+
|
182
|
+
Examples:
|
183
|
+
|
184
|
+
# copy "main.c" to the "build" directory
|
185
|
+
sys.cp "main.c", "build"
|
186
|
+
|
187
|
+
# copy all files ending in ".c" from the current directory to the
|
188
|
+
# "build" directory
|
189
|
+
sys.cp sys["*.c"], "build"
|
190
|
+
|
191
|
+
Raises a +SystemCallError+ if +src+ is a directory or doesn't exist.
|
192
|
+
|
193
|
+
* <b>cp_r(src, dest)</b>
|
194
|
+
|
195
|
+
Does the same as <tt>cp(src, dest)</tt>, but also accepts a
|
196
|
+
directory/directories as +src+. Directories are recursively copied
|
197
|
+
to +dest+.
|
198
|
+
|
199
|
+
Example:
|
200
|
+
|
201
|
+
# Recursively copy all files/directories in the "src" directory
|
202
|
+
# to the (existing) "/backup" directory.
|
203
|
+
sys.cp_r sys["src/*"], "/backup" # prints "cp -r <list of src/* files> /backup"
|
204
|
+
|
205
|
+
* <b>mv(src, dest)</b>
|
206
|
+
|
207
|
+
If +src+ is a path (string), move the file +src+ to +dest+.
|
208
|
+
|
209
|
+
Example:
|
210
|
+
|
211
|
+
# move "build/foo.exe" to "dist/foo.exe"
|
212
|
+
sys.mv "build/foo.exe", "dist/foo.exe" # prints "mv build/foo.exe dist/foo.exe"
|
213
|
+
|
214
|
+
If +dest+ is a directory, move +src+ do <tt>dest/src</tt>. If +src+
|
215
|
+
is an array of pathes or a filelist, move all entries of +src+ to
|
216
|
+
the directory +dest+.
|
217
|
+
|
218
|
+
Example:
|
219
|
+
|
220
|
+
# move all files ending in ".exe" from the "build" directory to
|
221
|
+
# the "dist" directory
|
222
|
+
sys.mv sys["build/*.exe"], "dist"
|
223
|
+
|
224
|
+
+src+ may also be a (empty or non-empty) directory. Of course a
|
225
|
+
mixed array/filelist of "normal" files and directories is also
|
226
|
+
allowed.
|
227
|
+
|
228
|
+
Raises a +SystemCallError+ if +src+ is an array/filelist and +dest+
|
229
|
+
is not a directory.
|
230
|
+
|
231
|
+
* <b>touch(file)</b>
|
232
|
+
|
233
|
+
+file+ may be a single path to a file, an array of pathes or a
|
234
|
+
filelist. Updates the modification time and the access time of all
|
235
|
+
files. If a file doesn't exist, creates an empty one with this name.
|
236
|
+
|
237
|
+
Examples:
|
238
|
+
|
239
|
+
# "main.c" is a file, update its modification time
|
240
|
+
sys.touch "main.c"
|
241
|
+
|
242
|
+
# "ts1" and "ts2" don't exist, create two empty files
|
243
|
+
sys.touch ["ts1", "ts2"]
|
244
|
+
|
245
|
+
* <b>safe_ln(src, dest)</b>
|
246
|
+
|
247
|
+
This creates a hard link +dest+ which points to the same file as
|
248
|
+
+src+, on platforms that support hard links. Simply copies +src+ to
|
249
|
+
+dest+ on other platforms.
|
250
|
+
|
251
|
+
Example:
|
252
|
+
|
253
|
+
# link or copy "main.c" to "package/main.c"
|
254
|
+
sys.safe_ln "main.c", "package/main.c"
|
255
|
+
# prints "ln main.c package/main.c" if a hard link is created
|
256
|
+
# prints "cp main.c package/main.c" if is main.c is copied
|
257
|
+
|
258
|
+
* <b>ln(src, dest)</b>
|
259
|
+
|
260
|
+
Creates a hard link +dest+ which points to the same file as +src+. If
|
261
|
+
+dest+ is a directory, creates the hard link <tt>dest/src</tt>.
|
262
|
+
|
263
|
+
Example:
|
264
|
+
|
265
|
+
# link "main.c" to "package/main.c"
|
266
|
+
sys.ln "main.c", "package" # prints "ln main.c package"
|
267
|
+
|
268
|
+
Raises a +SystemCallError+ if +dest+ is a file or doesn't exist.
|
269
|
+
|
270
|
+
Note:: Not all file systems and operating systems support hard
|
271
|
+
links.
|
272
|
+
On operating systems without support for hard links,
|
273
|
+
a +NotImplementedError+ exception is risen.
|
274
|
+
If the operating system supports hard links, but the file
|
275
|
+
system not, a +SystemCallError+ is risen.
|
276
|
+
|
277
|
+
* <b>ln_f(src, dest)</b>
|
278
|
+
|
279
|
+
Same as <tt>ln(src, dest)</tt>, but overwrites +dest+ if +dest+
|
280
|
+
is a file.
|
281
|
+
|
282
|
+
Example:
|
283
|
+
|
284
|
+
# link "main.c" to "package/main.c", overwriting any existing
|
285
|
+
# "package/main.c" file
|
286
|
+
sys.ln_f "main.c", "package"
|
287
|
+
|
288
|
+
# ... equivalent to
|
289
|
+
sys.ln_f "main.c", "package/main.c"
|
290
|
+
|
291
|
+
* <b>ln_s(src, dest)</b>
|
292
|
+
|
293
|
+
Creates a symbolic link +dest+ which points to +src+. If +dest+ is a
|
294
|
+
directory, creates the symbolic link <tt>dest/src</tt>.
|
295
|
+
|
296
|
+
Examples:
|
297
|
+
|
298
|
+
# Create the symbolic link "NEWS" to the existing file "ChangeLog"
|
299
|
+
sys.ln_s "ChangeLog", "NEWS" # prints "ln -s ChangeLog NEWS"
|
300
|
+
|
301
|
+
Raises a +SystemCallError+ if +dest+ is the name of an existing
|
302
|
+
file or +src+ doesn't exist.
|
303
|
+
|
304
|
+
Note:: Not all file systems and operating systems support
|
305
|
+
symbolic links.
|
306
|
+
On operating systems without support for symbolic links, a
|
307
|
+
+NotImplementedError+ exception is risen. If the
|
308
|
+
operating system supports symbolic links, but the file
|
309
|
+
system not, a +SystemCallError+ is risen.
|
310
|
+
|
311
|
+
* <b>ln_sf(src, dest)</b>
|
312
|
+
|
313
|
+
Same as <tt>ln_s(src, dest)</tt>, but overwrites +dest+ if +dest+
|
314
|
+
exists.
|
315
|
+
|
316
|
+
Example:
|
317
|
+
|
318
|
+
# Create the symbolic link "NEWS" to the existing file
|
319
|
+
# "ChangeLog", overwrite any existing "NEWS" file.
|
320
|
+
sys.ln_s "ChangeLog", "NEWS" # prints "ln -sf ChangeLog NEWS"
|
321
|
+
|
322
|
+
* <b>install(src, dest, options = {})</b>
|
323
|
+
|
324
|
+
Copy file +src+ to +dest+ if +dest+ doesn't exist or differs from
|
325
|
+
+src+. Install +src+ to <tt>dest/src</tt> if +dest+ is a directory.
|
326
|
+
If +src+ is an array/filelist, installs each entry in +src+ under
|
327
|
+
the +dest+ directory.
|
328
|
+
|
329
|
+
Options is a hash which may contain the following keys:
|
330
|
+
|
331
|
+
<tt>:mode</tt>:: If given, after copying the mode of the target
|
332
|
+
file(s) is changed to the integer given as
|
333
|
+
value.
|
334
|
+
|
335
|
+
<tt>:preserve</tt>:: Takes either +true+ or +false+. If given and
|
336
|
+
+true+, the target file(s) will have the same
|
337
|
+
access and modification times as the source
|
338
|
+
file(s).
|
339
|
+
|
340
|
+
Examples:
|
341
|
+
|
342
|
+
# copy the file "./ruby" to "/usr/local/bin/ruby19" and change the
|
343
|
+
# mode of the target file to 0755.
|
344
|
+
sys.install "ruby", "/usr/local/bin/ruby19", :mode => 0755
|
345
|
+
|
346
|
+
# install all files in the "lib" directory in "/usr/lib/foo" and
|
347
|
+
# change the access and modification times of the target files to
|
348
|
+
# match those of their source files.
|
349
|
+
sys.install sys["lib/*"], "/usr/lib/foo", :preserve => true
|
350
|
+
|
351
|
+
* <b>chmod(mode, file)</b>
|
352
|
+
|
353
|
+
+file+ may be a single file name or an array/filelist. Changes the
|
354
|
+
file permissions of all given files to the bit pattern represented
|
355
|
+
by the integer +mode+.
|
356
|
+
|
357
|
+
Examples:
|
358
|
+
|
359
|
+
# make file "/usr/local/bin/ruby" executable
|
360
|
+
sys.chmod 0755, "/usr/local/bin/ruby" # prints "chmod 0755 /usr/local/bin/ruby"
|
361
|
+
|
362
|
+
# make all files in the "bin" directory executable
|
363
|
+
sys.chmod 0755, sys["bin/*"]
|
364
|
+
|
365
|
+
Note:: Not all file systems/operating systems support the same
|
366
|
+
permission bits. This method will only set the supported
|
367
|
+
ones.
|
368
|
+
|
369
|
+
* <b>ruby(arg1, arg2, ...)</b>
|
370
|
+
|
371
|
+
Starts a new ruby interpreter with the given arguments.
|
372
|
+
|
373
|
+
Example:
|
374
|
+
|
375
|
+
sys.ruby "setup.rb", "--prefix=/usr" # prints "<absolute path to ruby> setup.rb --prefix=/usr"
|
376
|
+
|
377
|
+
IMPORTANT:: It does NOT start a subshell.
|
378
|
+
|
379
|
+
Bad Example:
|
380
|
+
|
381
|
+
# This probably does not do what was intended. Ruby will search
|
382
|
+
# for the script file with the name "setup.rb --prefix=/usr"!
|
383
|
+
sys.ruby "setup.rb --prefix=/usr"
|
384
|
+
|
385
|
+
Note:: Rant determines the absolute path to the ruby interpreter
|
386
|
+
which is running the current Rant instance. It uses this
|
387
|
+
path to start a new ruby interpreter. As a result, this
|
388
|
+
method will also work when "ruby" is not on the PATH.
|
389
|
+
|
390
|
+
* <b>write_to_file(fn, text)</b>
|
391
|
+
|
392
|
+
Requires <tt>import "sys/more"</tt>
|
393
|
+
|
394
|
+
Write the string +text+ to the file with name +fn+. If the file
|
395
|
+
already exists, it is overwritten, otherwise a new file is created.
|
396
|
+
|
397
|
+
Example:
|
398
|
+
|
399
|
+
import "sys/more"
|
400
|
+
|
401
|
+
sys.write_to_file "version", "1.2.0\n" # => prints "writing 6 bytes to file `version'"
|
402
|
+
|
403
|
+
* <b>unpack_tgz(fn, options = {})</b>
|
404
|
+
|
405
|
+
Requires <tt>import "sys/tgz"</tt>
|
406
|
+
|
407
|
+
Unpack the gzipped tar archive file with the file name +fn+ in the
|
408
|
+
current directory. If +options+ contains the key <tt>:in</tt>, its
|
409
|
+
value will be used as name of the output directory.
|
410
|
+
|
411
|
+
Example:
|
412
|
+
|
413
|
+
import "sys/tgz"
|
414
|
+
|
415
|
+
# Creates the "pkg" directory if it doesn't exist and unpacks all
|
416
|
+
# contents of "rant-0.4.6.tgz" in the "pkg" directory.
|
417
|
+
sys.unpack_tgz "rant-0.4.6.tgz", :in => "pkg"
|
418
|
+
|
419
|
+
Existing files will be overwritten.
|
420
|
+
|
421
|
+
* <b>unpack_zip(fn, options = {})</b>
|
422
|
+
|
423
|
+
Requires <tt>import "sys/zip"</tt>
|
424
|
+
|
425
|
+
Unpack the zip archive file with the file name +fn+ in the current
|
426
|
+
directory. If +options+ contains the key <tt>:in</tt>, its value
|
427
|
+
will be used as name of the output directory.
|
428
|
+
|
429
|
+
Example:
|
430
|
+
|
431
|
+
import "sys/zip"
|
432
|
+
|
433
|
+
# Creates the "pkg" directory if it doesn't exist and unpacks all
|
434
|
+
# contents of "rant-0.4.6.zip" in the "pkg" directory.
|
435
|
+
sys.unpack_zip "rant-0.4.6.zip", :in => "pkg"
|
436
|
+
|
437
|
+
Existing files will be overwritten.
|
438
|
+
|
439
|
+
The following methods are "silent", i.e. they don't print messages to
|
440
|
+
standard output:
|
441
|
+
|
442
|
+
* <b>pwd</b>
|
443
|
+
|
444
|
+
Returns the current working directory as string.
|
445
|
+
|
446
|
+
Example:
|
447
|
+
|
448
|
+
sys.pwd # => "/home/user"
|
449
|
+
|
450
|
+
* <b>compare_file(a, b)</b>
|
451
|
+
|
452
|
+
Returns true if the files +a+ and +b+ have the same contents, false
|
453
|
+
otherwise.
|
454
|
+
|
455
|
+
Example:
|
456
|
+
|
457
|
+
unless sys.compare_file("lib/main.c", "/backup/main.c")
|
458
|
+
puts "lib/main.c differs from /backup/main.c"
|
459
|
+
end
|
460
|
+
|
461
|
+
Raises a +SystemCallError+ if +a+ or +b+ is not a file.
|
462
|
+
|
463
|
+
* <b>uptodate?(new, old_list)</b>
|
464
|
+
|
465
|
+
Returns true if the file with name +new+ is newer (checked by file
|
466
|
+
modification time) than all files listed in the +old_list+
|
467
|
+
array/filelist. A non-existent file (including +new+) is considered
|
468
|
+
older than any other file.
|
469
|
+
|
470
|
+
Example:
|
471
|
+
|
472
|
+
unless sys.uptodate?("foo.exe", sys["src/*.c", "include/*.h"])
|
473
|
+
puts "(re)build of foo.exe required"
|
474
|
+
end
|
475
|
+
|
476
|
+
* <b>expand_path(path)</b>
|
477
|
+
|
478
|
+
Resolves any "." or ".." elements in +path+ and expands +path+ to an
|
479
|
+
absolute path. Replaces a leading <tt>@</tt> character with an
|
480
|
+
absolute path to the project's root directory. Returns the resulting
|
481
|
+
path string.
|
482
|
+
|
483
|
+
Examples, assuming current directory is "/home/user/project/sub"
|
484
|
+
and project root directory is "/home/user/project":
|
485
|
+
|
486
|
+
sys.expand_path("README") # => "/home/user/project/sub/README"
|
487
|
+
sys.expand_path("./README") # => "/home/user/project/sub/README"
|
488
|
+
sys.expand_path("@README") # => "/home/user/project/README"
|
489
|
+
sys.expand_path("../../README") # => "/home/user/README"
|
490
|
+
sys.expand_path("/@README") # => "/@README"
|
491
|
+
sys.expand_path("subsub/./../") # => "/home/user/project/sub"
|
492
|
+
|
493
|
+
* <b>split_all(path)</b>
|
494
|
+
|
495
|
+
Splits +path+ into all its elements and returns and array.
|
496
|
+
|
497
|
+
Examples:
|
498
|
+
|
499
|
+
sys.split_all("abc") # => ["abc"]
|
500
|
+
sys.split_all("foo/bar") # => ["foo", "bar"]
|
501
|
+
sys.split_all("foo/bar/baz") # => ["foo", "bar", "baz"]
|
502
|
+
|
503
|
+
* <b>escape(arg)</b>
|
504
|
+
|
505
|
+
Escapes all spaces in +arg+ for the shell which is used on the
|
506
|
+
current platform. Returns the escaped string.
|
507
|
+
|
508
|
+
Example:
|
509
|
+
|
510
|
+
sys.escape("foo bar")
|
511
|
+
# gives on Windows: '"foo bar"'
|
512
|
+
# other systems: 'foo\ bar'
|
513
|
+
|
514
|
+
If +arg+ is an array (or filelist) all elements are escaped and the
|
515
|
+
resulting strings joined together, seperated by spaces.
|
516
|
+
|
517
|
+
Example:
|
518
|
+
|
519
|
+
sys.escape(["foo bar", "arg 2"])
|
520
|
+
# gives on Windows: '"foo bar" "arg 2"'
|
521
|
+
# other systems: 'foo\ bar arg\ 2'
|
522
|
+
|
523
|
+
Note:: Might escape more special shell characters in the future.
|
524
|
+
|
525
|
+
* <b>sp(path)</b>
|
526
|
+
|
527
|
+
Does the same as <tt>escape(path)</tt>, but also replaces all
|
528
|
+
slashes with backslashes on windows.
|
529
|
+
|
530
|
+
Example:
|
531
|
+
|
532
|
+
libdir = "/home/user/program files/d"
|
533
|
+
sources = ["foo bar.d", "util.d"]
|
534
|
+
sys "dmd #{sys.sp sources} -offoo -I#{sys.sp libdir}"
|
535
|
+
# executes the command
|
536
|
+
# on windows: 'dmd "foo bar.d" util.d -offoo -I"/home/user/program files/d"'
|
537
|
+
# other systems: 'dmd foo\ bar.d util.d -offoo -I/home/user/program\ files/d'
|
538
|
+
|
539
|
+
* <b>glob(pattern1, pattern2, ...)</b>
|
540
|
+
|
541
|
+
<b>[pattern1, pattern2, ...]</b>
|
542
|
+
|
543
|
+
Returns a filelist including the given patterns. For a discussion of
|
544
|
+
filelists, read <em>Selecting files with filelists</em> in
|
545
|
+
doc/advanced.rdoc[link:files/doc/advanced_rdoc.html].
|
546
|
+
|
547
|
+
Examples:
|
548
|
+
|
549
|
+
# the following two are equivalent
|
550
|
+
sys.glob("*.c", "*.h")
|
551
|
+
sys["*.c", "*.h"]
|
552
|
+
|
553
|
+
Filelists created with this method, ignore entries starting with a
|
554
|
+
dot.
|
555
|
+
|
556
|
+
* <b>glob_all(pattern1, pattern2, ...)</b>
|
557
|
+
|
558
|
+
Like <tt>glob(pattern1, pattern2, ...)</tt>, but the created filelist
|
559
|
+
doesn't ignore entries starting with a dot.
|
560
|
+
|
561
|
+
== See also
|
562
|
+
|
563
|
+
Rantfile basics::
|
564
|
+
doc/rantfile.rdoc[link:files/doc/rantfile_rdoc.html]
|
565
|
+
Advanced Rantfiles::
|
566
|
+
doc/advanced.rdoc[link:files/doc/advanced_rdoc.html]
|
567
|
+
Rant Overview::
|
568
|
+
README[link:files/README.html]
|
data/lib/rant/coregen.rb
CHANGED
@@ -105,6 +105,7 @@ module Rant
|
|
105
105
|
unless args.size == 1
|
106
106
|
rac.abort_at(ch, "Rule takes only one argument.")
|
107
107
|
end
|
108
|
+
rac.abort_at(ch, "Rule: block required.") unless block
|
108
109
|
arg = args.first
|
109
110
|
target = nil
|
110
111
|
src_arg = nil
|
@@ -178,16 +179,9 @@ module Rant
|
|
178
179
|
have_src = true
|
179
180
|
src = @src_proc[target]
|
180
181
|
if src.respond_to? :to_ary
|
181
|
-
src.
|
182
|
-
if @rant.resolve(f).empty? && !test(?e, f)
|
183
|
-
have_src = false
|
184
|
-
break
|
185
|
-
end
|
186
|
-
}
|
182
|
+
have_src = src.to_ary.all? { |s| have_src?(s) }
|
187
183
|
else
|
188
|
-
|
189
|
-
have_src = false
|
190
|
-
end
|
184
|
+
have_src = have_src?(src)
|
191
185
|
end
|
192
186
|
if have_src
|
193
187
|
create_nodes(rel_project_dir, target, src)
|
@@ -196,6 +190,10 @@ module Rant
|
|
196
190
|
end
|
197
191
|
alias [] call
|
198
192
|
private
|
193
|
+
def have_src?(name)
|
194
|
+
!@rant.rec_save_resolve(name, self).empty? or
|
195
|
+
test(?e, name)
|
196
|
+
end
|
199
197
|
def create_nodes(rel_project_dir, target, deps)
|
200
198
|
case nodes = @block[target, deps]
|
201
199
|
when Array: nodes
|
@@ -210,6 +208,11 @@ module Rant
|
|
210
208
|
end
|
211
209
|
class FileHook < Hook
|
212
210
|
private
|
211
|
+
def have_src?(name)
|
212
|
+
test(?e, name) or
|
213
|
+
@rant.rec_save_resolve(name, self
|
214
|
+
).any? { |t| t.file_target? }
|
215
|
+
end
|
213
216
|
def create_nodes(rel_project_dir, target, deps)
|
214
217
|
t = @rant.file(:__caller__ => @ch,
|
215
218
|
target => deps, &@block)
|
@@ -220,14 +223,38 @@ module Rant
|
|
220
223
|
end # class Rule
|
221
224
|
class Action
|
222
225
|
def self.rant_gen(rac, ch, args, &block)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
226
|
+
case args.size
|
227
|
+
when 0:
|
228
|
+
unless (rac[:tasks] || rac[:stop_after_load])
|
229
|
+
yield
|
230
|
+
end
|
231
|
+
when 1:
|
232
|
+
rx = args.first
|
233
|
+
unless rx.kind_of? Regexp
|
234
|
+
rac.abort_at(ch, "Action: argument has " +
|
235
|
+
"to be a regular expression.")
|
236
|
+
end
|
237
|
+
rac.resolve_hooks << self.new(rac, block, rx)
|
238
|
+
nil
|
239
|
+
else
|
240
|
+
rac.abort_at(ch, "Action: too many arguments.")
|
241
|
+
end
|
230
242
|
end
|
243
|
+
def initialize(rant, block, rx)
|
244
|
+
@rant = rant
|
245
|
+
@subdir = @rant.current_subdir
|
246
|
+
@block = block
|
247
|
+
@rx = rx
|
248
|
+
end
|
249
|
+
def call(target, rel_project_dir)
|
250
|
+
if target =~ @rx
|
251
|
+
@rant.resolve_hooks.delete(self)
|
252
|
+
@rant.goto_project_dir @subdir
|
253
|
+
@block.call
|
254
|
+
@rant.resolve(target, rel_project_dir)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
alias [] call
|
231
258
|
end
|
232
259
|
end # module Generators
|
233
260
|
end # module Rant
|
data/lib/rant/import/command.rb
CHANGED
@@ -113,8 +113,8 @@ module Rant
|
|
113
113
|
def val_for_interp_var(var)
|
114
114
|
case var
|
115
115
|
when "name": self.name
|
116
|
-
when "prerequisites":
|
117
|
-
when "source":
|
116
|
+
when "prerequisites": prerequisites.map { |n| rac.resolve_root_ref(n) }
|
117
|
+
when "source": rac.resolve_root_ref(source)
|
118
118
|
else
|
119
119
|
cx = rac.cx
|
120
120
|
val = cx.var._get(var) || (
|
@@ -143,8 +143,8 @@ module Rant
|
|
143
143
|
def val_for_interp_sym(sym)
|
144
144
|
case sym
|
145
145
|
when ">": name
|
146
|
-
when "<": prerequisites
|
147
|
-
when "-": source
|
146
|
+
when "<": prerequisites.map { |n| rac.resolve_root_ref(n) }
|
147
|
+
when "-": rac.resolve_root_ref(source)
|
148
148
|
end
|
149
149
|
end
|
150
150
|
end
|
@@ -173,6 +173,9 @@ module Rant
|
|
173
173
|
end
|
174
174
|
@command_changed = @cmd_key = @new_sig = @md = nil
|
175
175
|
end
|
176
|
+
def pre_action_descs
|
177
|
+
[@command ? "SHELL\n#@command" : "SHELL"]
|
178
|
+
end
|
176
179
|
private
|
177
180
|
def res_command(node)
|
178
181
|
return if @command
|