rant 0.4.8 → 0.5.0
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 +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
|