doc/rantfile.rdoc in rant-0.4.8 vs doc/rantfile.rdoc in rant-0.5.0
- old
+ new
@@ -40,36 +40,36 @@
task name may be a string or symbol:
task :taskname
That's it, your first task. Not very useful, because it doesn't do
anything. To associate an action with the task, add a block:
task :mytask do
- puts "Hello, mytask running."
+ puts "Hello, mytask running."
end
Put these 3 lines of code into a file called +Rantfile+ and run rant:
% rant mytask
Hello, mytask running.
Note: you could have omited the mytask argument to rant because it is
the only task in the Rantfile.
You can add a block parameter which will be a reference to the created
task:
task :mytask do |t|
- puts t.name
+ puts t.name
end
Running rant now:
% rant
mytask
Add prerequisites to create relations between tasks:
task :first => [:t1, :t2] do |t|
- puts t.name
+ puts t.name
end
task :t1 do |t|
- puts t.name
+ puts t.name
end
task :t2 do |t|
- puts t.name
+ puts t.name
end
In the definition of the "first" task we told Rant that it _depends_
on task "t1" and task "t2". "t1" and "t2" are called prerequisites for
"first". Try it out:
% rant first
@@ -92,11 +92,11 @@
In this example we use the <tt>sys.touch</tt> method to test our file
task. (This method works the same as the Unix touch command: Update
the modification time of a file or create an empty file):
file "testfile" do |t|
- sys.touch t.name
+ sys.touch t.name
end
Now run rant:
% rant
touch testfile
This would have been the same with a normal task. But now run rant a
@@ -105,11 +105,11 @@
This time rant doesn't run the action, because "testfile" is up to
date. Of course you can add prerequisites the same way as for a normal
task. Additionally you can add filenames as prerequisites. Assuming
the files "a.o" and "b.o" are in the same directory as the Rantfile:
file "myprog" => %w(a.o b.o) do |t|
- sys %w(cc -o), t.name, t.prerequisites
+ sys %w(cc -o), t.name, t.prerequisites
end
Running rant:
% rant
cc -o myprog a.o b.o
Running a second time:
@@ -124,62 +124,62 @@
The +desc+ function lets you describe your tasks. A small example
Rantfile:
# Generate C source file ls.c with the xgen command.
file "ls.c" => %w(ls1.x ls2.x) do |t|
- sys %w(xgen -o), t.name, t.prerequisites
+ sys %w(xgen -o), t.name, t.prerequisites
end
desc "Build ls program."
file "ls" => "ls.c" do
- sys "cc -o ls ls.c"
+ sys "cc -o ls ls.c"
end
desc "Remove autogenerated files."
task :clean do
- sys.rm_f %w(ls.c ls)
+ sys.rm_f %w(ls.c ls)
end
(Note that xgen is a hypothetical command ;)
The <tt>--tasks</tt> (or the short form, <tt>-T</tt>) option of rant
shows this descriptions:
% rant -T
- rant ls # Build ls program.
- rant clean # Remove autogenerated files.
+ rant ls # Build ls program.
+ rant clean # Remove autogenerated files.
Only the tasks which have a description are listed.
-=== The +sys+ command
+=== The +sys+ method
-After using the +sys+ command quite often in the examples, I should
-explain it a little bit. The +sys+ command can be used in three ways:
+After using the +sys+ method quite often in the examples, I should
+explain it a little bit. It can be used in three ways:
1. <b>File system operations</b>
The first form is with no arguments. It returns an object on which
- you can invoke the methods of the +FileUtils+ module that comes
- with ruby.
+ you can invoke methods for common file system operations:
+
Examples are:
- sys.rm "file1", "file2", ... # remove files
- sys.cp "src", "dest" # copy from "src" do "dest"
- sys.mkdir "dir" # create directory "dir"
- For a list of all available methods invoke ri:
- % ri FileUtils
- which will also show documentation for them.
- Additionally you have the following methos which are not in the
- FileUtils module:
- sys.ruby "arg1", "arg2", ... # invoke the ruby interpreter
- sys.safe_ln "src", "dest" # create a hardlink or fall back to
- # copying
+ sys.rm ["file1", "file2"] # remove files
+ sys.cp "src", "dest" # copy from "src" do "dest"
+ sys.mkdir "dir" # create directory "dir"
+
+ For a list of all available methods read
+ doc/sys.rdoc[link:files/doc/sys_rdoc.html].
+
2. <b>Running external commands</b>
- Invoke the +sys+ command with a string as argument to run a shell:
- sys "echo *.c"
+ Invoke the +sys+ method with a string as argument to run a shell:
+
+ sys "echo *.c"
+
will print a list of C files to stdout.
When given multiple arguments, +sys+ invokes the program named with
the first argument giving it the remaining arguments as arguments:
- sys "echo", "*.c"
+
+ sys "echo", "*.c"
+
will print "*.c" to stdout.
When the external program returns with an exit code other than 0,
Rant will abort with an error message. Sometimes this is not
desirable. E.g. the +diff+ program, which compares two files,
@@ -204,101 +204,123 @@
3. <b>Selecting files</b>
To select files with the help of glob patterns use +sys+ with the
<tt>[]</tt> operator:
- file "program" => sys["*.o"]
+
+ file "program" => sys["*.o"]
+
The task "program" depends on all files ending in ".o". Rant uses
the Dir::glob method internally to resolve patterns, so you can
read the ri docs to get an overview:
- ri Dir::glob
+ ri Dir::glob
+
From now on we'll call <tt>sys[...]</tt> the <em>glob
operator</em>.
You can give more patterns:
- c_files = sys["**/*.h", "**/*.c"]
+
+ c_files = sys["**/*.h", "**/*.c"]
+
gives a list of all files ending in ".h" or ".c" in the current
directory and all subdirectories.
- The object returned by the glob operator _behaves_ like a list of
+ The object returned by the glob operator _behaves_ like an array of
strings, so it is possible to pass it to methods expecting an array.
If you're getting errors or experience strange behaviour convert
the list explicetely to an array:
- sys.touch c_files.to_a
+ # method foo_bar is hardcoded to check for an object of class
+ # Array
+ foo_bar(c_files.to_a)
+
=== Generators
The *gen* function takes a generator which usually creates one or more
tasks for you. The following list of generators is immediately
available:
-+Directory+:: Create directories.
-+Task+:: Define custom task.
-+Rule+:: Define a rule (a rule produces tasks on the fly).
-+Action+:: Run a block of code immediately.
- The Action generator is discussed in
- doc/advanced.rdoc[link:files/doc/advanced_rdoc.html].
++Directory+:: Create directories.
++Task+:: Define custom task.
++Rule+:: Define a rule (a rule produces tasks on the fly).
++Action+:: Run a block of code immediately.
+ The Action generator is discussed in
+ doc/advanced.rdoc[link:files/doc/advanced_rdoc.html].
+
=== The +Directory+ generator
An example usage of the +Directory+ generator would be the backup
example shown in the README file:
+
file "misc/backup/data" => %w(misc/backup data) do |t|
- sys.cp "data", t.name
+ sys.cp "data", t.name
end
gen Directory, "misc/backup"
+
Now rant will create the directories "misc" and "backup" on demand.
Assuming "misc/backup" doesn't exist:
+
% rant
mkdir misc
mkdir misc/backup
cp data misc/backup/data
=== The +Task+ generator
The +Task+ generator allows you to determine by hand when your task
action needs to be run:
+
desc "Install with setup.rb"
gen Task, :install do |t|
- t.needed { !File.exist? "InstalledFiles" }
- t.act do
- sys.ruby "setup.rb"
- end
+ t.needed { !File.exist? "InstalledFiles" }
+ t.act do
+ sys.ruby "setup.rb"
+ end
end
+
The +act+ block of the "install" task will only be run if
"InstalledFiles" doesn't exist. Of course you can add prerequisites
like with any other task.
=== Rules
A Rule allows you to tell Rant how it should build files matching a
common pattern, e.g. how to build files ending in ".o". A standard
rule usage is to create C object files:
+
gen Rule, '.o' => '.c' do |t|
- sys "cc -c -o #{t.name} #{t.source}"
+ sys "cc -c -o #{t.name} #{t.source}"
end
+
Assuming that we have the C source file util.c in the current
directory:
+
% rant util.o
cc -c -o util.o util.c
+
Because Rant didn't find a task for util.o, it looked for a matching
rule and created a task for util.o.
The first line above could also be written as:
+
gen Rule, :o => :c do |t|
The +source+ method of the task object gives us the first dependency.
So the following line has the same effect:
- sys "cc -c -o #{t.name} #{t.prerequisites.first}"
+ sys "cc -c -o #{t.name} #{t.prerequisites.first}"
+
You can also refine the rule pattern by using a regular expression. To
refine dependency selection give a block as source argument:
+
src = lambda { |target| [target.sub_ext("c"), target.sub_ext("h")] }
gen Rule, /^my_[^.]+\.o$/ => src do |t|
- sys "cc -c -o #{t.name} #{t.source}"
+ sys "cc -c -o #{t.name} #{t.source}"
end
+
This rule generates a task for files beginning with "my_" and ending
in ".o" (like "my_program.o"). The task has a file ending in ".c" and
one ending in ".h" as dependencies (like "my_program.c" and
"my_program.h") . Since <tt>t.source</tt> gives us the *first*
dependency, the ".c" file will appear as argument to cc, but not the
@@ -309,21 +331,29 @@
=== Importing additional generators
The +import+ function lets you import additional generators.
Currently the following come with Rant:
+
Clean:: Remove selected files.
AutoClean:: Remove all files generated by any file task (including
those generated by rules).
DirectedRule:: A Rule which takes sources from one or more
directories and puts generated files into a specified
directory.
SubFile:: Create file task and necessary directory tasks.
+Command:: Tasks with command change recognition.
RubyTest:: Run Test::Unit tests for your Ruby code.
RubyDoc:: Run RDoc.
RubyPackage:: Generate tar, zip and gem packages of your Ruby
application/library.
+Archive::Tgz:: Create gzipped tar archives.
+Archive::Zip:: Create zip archives.
+Package::Tgz:: Create gzipped tar packages.
+Package::Zip:: Create zip packages.
+C::Dependencies:: Determine dependencies between C/C++ source/header
+ files caused by #include statements.
Win32::RubyCmdWrapper:: Create .cmd wrapper scripts for installation
of Ruby scripts on Windows.
Read doc/advanced.rdoc[link:files/doc/advanced_rdoc.html] and
doc/rubyproject.rdoc[link:files/doc/rubyproject_rdoc.html] for
@@ -336,45 +366,45 @@
Rantfiles. The tasks defined in those subdirectories can be referenced
from your main Rantfile and vice versa.
A small example: We are assuming the following files:
myprog/
- Rantfile # the main Rantfile
- README
- src/
- Rantfile
- main.c
- lib.c
- lib.h
+ Rantfile # the main Rantfile
+ README
+ src/
+ Rantfile
+ main.c
+ lib.c
+ lib.h
Then the main Rantfile could look like:
desc "Build myprog."
file "myprog" => "src/myprog" do
- sys.cp "src/myprog", "myprog"
+ sys.cp "src/myprog", "myprog"
end
desc "Remove compiler products."
task :clean => "src/clean" do
- sys.rm_f "myprog"
+ sys.rm_f "myprog"
end
# Tell Rant to look in src for an Rantfile,
# we could list more directories here.
subdirs "src"
And src/Rantfile:
file "lib.o" => %w(lib.c lib.h) do
- sys "cc -c -o lib.o lib.c"
+ sys "cc -c -o lib.o lib.c"
end
file "main.o" => "main.c" do
- sys "cc -c -o main.o main.c"
+ sys "cc -c -o main.o main.c"
end
file "myprog" => %w(lib.o main.o) do
- sys "cc -o myprog main.o lib.o"
+ sys "cc -o myprog main.o lib.o"
end
task :clean do
- sys.rm_f Dir["*.o"] + %w(myprog)
+ sys.rm_f Dir["*.o"] + %w(myprog)
end
Note that we refer to the task in subdirectory simply by prepending
the directory name and a slash to the task name.
file "myprog" => "src/myprog" do
This tells Rant that the "myprog" task depends on the "myprog" task