Lably
Skip to content

Rake (software)

  • 6 min read
  • 1 chapter

Related on Lably

Through Make (software)

Examples

The tasks that should be executed need to be defined in a configuration file called Rakefile. A Rakefile has no special syntax and contains executable Ruby code.

Tasks

The basic unit in Rake is the task. A task has a name and an action block, that defines its functionality. The following code defines a task called greet that will output the text "Hello, Rake!" to the console.

<span id="mwHw"></span><span class="n" id="mwIA">task</span><span class="w" id="mwIQ"> </span><span class="ss" id="mwIg">:greet</span><span class="w" id="mwIw"> </span><span class="k" id="mwJA">do</span> <span class="w" id="mwJQ"> </span><span class="nb" id="mwJg">puts</span><span class="w" id="mwJw"> </span><span class="s2" id="mwKA">"Hello, Rake!"</span> <span class="k" id="mwKQ">end</span>

When defining a task, you can optionally add dependencies, that is one task can depend on the successful completion of another task. Calling the "seed" task from the following example will first execute the "migrate" task and only then proceed with the execution of the "seed" task.

<span id="mwLw"></span><span class="n" id="mwMA">task</span><span class="w" id="mwMQ"> </span><span class="ss" id="mwMg">:seed</span><span class="w" id="mwMw"> </span><span class="o" id="mwNA">=></span><span class="w" id="mwNQ"> </span><span class="ss" id="mwNg">:migrate</span><span class="w" id="mwNw"> </span><span class="k" id="mwOA">do</span> <span class="w" id="mwOQ"> </span><span class="c1" id="mwOg"># This task will run after the :migrate task</span> <span class="k" id="mwOw">end</span>

Tasks can also be made more versatile by accepting arguments. For example, the "generate_report" task will take a date as argument. If no argument is supplied the current date is used.

<span id="mwQQ"></span><span class="n" id="mwQg">task</span><span class="w" id="mwQw"> </span><span class="ss" id="mwRA">:generate_report</span><span class="p" id="mwRQ">,</span><span class="w" id="mwRg"> </span><span class="o" id="mwRw">[</span><span class="ss" id="mwSA">:date</span><span class="o" id="mwSQ">]</span><span class="w" id="mwSg"> </span><span class="k" id="mwSw">do</span><span class="w" id="mwTA"> </span><span class="o" id="mwTQ">|</span><span class="n" id="mwTg">t</span><span class="p" id="mwTw">,</span><span class="w" id="mwUA"> </span><span class="n" id="mwUQ">args</span><span class="o" id="mwUg">|</span> <span class="w" id="mwUw"> </span><span class="n" id="mwVA">report_date</span><span class="w" id="mwVQ"> </span><span class="o" id="mwVg">=</span><span class="w" id="mwVw"> </span><span class="n" id="mwWA">args</span><span class="o" id="mwWQ">[</span><span class="ss" id="mwWg">:date</span><span class="o" id="mwWw">]</span><span class="w" id="mwXA"> </span><span class="o" id="mwXQ">||</span><span class="w" id="mwXg"> </span><span class="no" id="mwXw">Date</span><span class="o" id="mwYA">.</span><span class="n" id="mwYQ">today</span> <span class="w" id="mwYg"> </span><span class="c1" id="mwYw"># Generate the report based on the specified date</span> <span class="k" id="mwZA">end</span>

A special type of task is the file task, which can be used to specify file creation tasks. The following task, for example, is given two object files, i.e. "a.o" and "b.o", to create an executable program.

<span id="mwag"></span><span class="n" id="mwaw">file</span><span class="w" id="mwbA"> </span><span class="s2" id="mwbQ">"prog"</span><span class="w" id="mwbg"> </span><span class="o" id="mwbw">=></span><span class="w" id="mwcA"> </span><span class="o" id="mwcQ">[</span><span class="s2" id="mwcg">"a.o"</span><span class="p" id="mwcw">,</span><span class="w" id="mwdA"> </span><span class="s2" id="mwdQ">"b.o"</span><span class="o" id="mwdg">]</span><span class="w" id="mwdw"> </span><span class="k" id="mweA">do</span><span class="w" id="mweQ"> </span><span class="o" id="mweg">|</span><span class="n" id="mwew">t</span><span class="o" id="mwfA">|</span> <span class="w" id="mwfQ"> </span><span class="n" id="mwfg">sh</span><span class="w" id="mwfw"> </span><span class="s2" id="mwgA">"cc -o </span><span class="si" id="mwgQ">#{</span><span class="n" id="mwgg">t</span><span class="o" id="mwgw">.</span><span class="n" id="mwhA">name</span><span class="si" id="mwhQ">}</span><span class="s2" id="mwhg"> </span><span class="si" id="mwhw">#{</span><span class="n" id="mwiA">t</span><span class="o" id="mwiQ">.</span><span class="n" id="mwig">prerequisites</span><span class="o" id="mwiw">.</span><span class="n" id="mwjA">join</span><span class="p" id="mwjQ">(</span><span class="s1" id="mwjg">' '</span><span class="p" id="mwjw">)</span><span class="si" id="mwkA">}</span><span class="s2" id="mwkQ">"</span> <span class="k" id="mwkg">end</span>

Another useful tool is the directory convenience method, that can be used to create directories upon demand.

<span id="mwmA"></span><span class="n" id="mwmQ">directory</span><span class="w" id="mwmg"> </span><span class="s2" id="mwmw">"testdata/examples/doc"</span>

Rules

When a file is named as a prerequisite but it does not have a file task defined for it, Rake will attempt to synthesize a task by looking at a list of rules supplied in the Rakefile. For example, suppose we were trying to invoke task "mycode.o" with no tasks defined for it. If the Rakefile has a rule that looks like this:

<span id="mwoA"></span><span class="n" id="mwoQ">rule</span><span class="w" id="mwog"> </span><span class="s1" id="mwow">'.o'</span><span class="w" id="mwpA"> </span><span class="o" id="mwpQ">=></span><span class="w" id="mwpg"> </span><span class="s1" id="mwpw">'.c'</span><span class="w" id="mwqA"> </span><span class="k" id="mwqQ">do</span><span class="w" id="mwqg"> </span><span class="o" id="mwqw">|</span><span class="n" id="mwrA">t</span><span class="o" id="mwrQ">|</span> <span class="w" id="mwrg"> </span><span class="n" id="mwrw">sh</span><span class="w" id="mwsA"> </span><span class="s2" id="mwsQ">"cc </span><span class="si" id="mwsg">#{</span><span class="n" id="mwsw">t</span><span class="o" id="mwtA">.</span><span class="n" id="mwtQ">source</span><span class="si" id="mwtg">}</span><span class="s2" id="mwtw"> -c -o </span><span class="si" id="mwuA">#{</span><span class="n" id="mwuQ">t</span><span class="o" id="mwug">.</span><span class="n" id="mwuw">name</span><span class="si" id="mwvA">}</span><span class="s2" id="mwvQ">"</span> <span class="k" id="mwvg">end</span>

This rule will synthesize any task that ends in ".o". It has as a prerequisite that a source file with an extension of ".c" must exist. If Rake is able to find a file named "mycode.c", it will automatically create a task that builds "mycode.o" from "mycode.c". If the file "mycode.c" does not exist, Rake will attempt to recursively synthesize a rule for it.

When a task is synthesized from a rule, the source attribute of the task is set to the matching source file. This allows users to write rules with actions that reference the source file.

Advanced rules

Any regular expression may be used as the rule pattern. Additionally, a proc may be used to calculate the name of the source file. This allows for complex patterns and sources.

The following rule is equivalent to the example above:

<span id="mwyA"></span><span class="n" id="mwyQ">rule</span><span class="p" id="mwyg">(</span><span class="sr" id="mwyw">/\.o$/</span><span class="w" id="mwzA"> </span><span class="o" id="mwzQ">=></span> <span class="w" id="mwzg"> </span><span class="o" id="mwzw">-></span><span class="p" id="mw0A">(</span><span class="n" id="mw0Q">t_name</span><span class="p" id="mw0g">){</span><span class="w" id="mw0w"> </span><span class="n" id="mw1A">t_name</span><span class="o" id="mw1Q">.</span><span class="n" id="mw1g">sub</span><span class="w" id="mw1w"> </span><span class="sr" id="mw2A">/\.o$/</span><span class="p" id="mw2Q">,</span><span class="w" id="mw2g"> </span><span class="s1" id="mw2w">'.c'</span><span class="w" id="mw3A"> </span><span class="p" id="mw3Q">})</span><span class="w" id="mw3g"> </span><span class="k" id="mw3w">do</span><span class="w" id="mw4A"> </span><span class="o" id="mw4Q">|</span><span class="n" id="mw4g">t</span><span class="o" id="mw4w">|</span> <span class="w" id="mw5A"> </span><span class="n" id="mw5Q">sh</span><span class="w" id="mw5g"> </span><span class="s2" id="mw5w">"cc </span><span class="si" id="mw6A">#{</span><span class="n" id="mw6Q">t</span><span class="o" id="mw6g">.</span><span class="n" id="mw6w">source</span><span class="si" id="mw7A">}</span><span class="s2" id="mw7Q"> -c -o </span><span class="si" id="mw7g">#{</span><span class="n" id="mw7w">t</span><span class="o" id="mw8A">.</span><span class="n" id="mw8Q">name</span><span class="si" id="mw8g">}</span><span class="s2" id="mw8w">"</span> <span class="k" id="mw9A">end</span>

NOTE: Because of a quirk in Ruby syntax, parentheses are required around a rule when the first argument is a regular expression.

The following rule might be used for Java files:

<span id="mw-w"></span><span class="n" id="mw_A">rule</span><span class="w" id="mw_Q"> </span><span class="s1" id="mw_g">'.class'</span><span class="w" id="mw_w"> </span><span class="o" id="mwAQA">=></span><span class="w" id="mwAQE"> </span><span class="o" id="mwAQI">-></span><span class="p" id="mwAQM">(</span><span class="n" id="mwAQQ">t_name</span><span class="p" id="mwAQU">){</span><span class="w" id="mwAQY"> </span><span class="n" id="mwAQc">t_name</span> <span class="w" id="mwAQg"> </span><span class="o" id="mwAQk">.</span><span class="n" id="mwAQo">sub</span><span class="p" id="mwAQs">(</span><span class="sr" id="mwAQw">/\.class$/</span><span class="p" id="mwAQ0">,</span><span class="w" id="mwAQ4"> </span><span class="s1" id="mwAQ8">'.java'</span><span class="p" id="mwARA">)</span> <span class="w" id="mwARE"> </span><span class="o" id="mwARI">.</span><span class="n" id="mwARM">sub</span><span class="p" id="mwARQ">(</span><span class="sr" id="mwARU">/^classes\//</span><span class="p" id="mwARY">,</span><span class="w" id="mwARc"> </span><span class="s1" id="mwARg">'src/'</span><span class="p" id="mwARk">)</span><span class="w" id="mwARo"> </span><span class="p" id="mwARs">}</span><span class="w" id="mwARw"> </span><span class="k" id="mwAR0">do</span><span class="w" id="mwAR4"> </span><span class="o" id="mwAR8">|</span><span class="n" id="mwASA">t</span><span class="o" id="mwASE">|</span> <span class="w" id="mwASI"> </span><span class="n" id="mwASM">java_compile</span><span class="p" id="mwASQ">(</span><span class="n" id="mwASU">t</span><span class="o" id="mwASY">.</span><span class="n" id="mwASc">source</span><span class="p" id="mwASg">,</span><span class="w" id="mwASk"> </span><span class="n" id="mwASo">t</span><span class="o" id="mwASs">.</span><span class="n" id="mwASw">name</span><span class="p" id="mwAS0">)</span> <span class="k" id="mwAS4">end</span>

Namespaces

To better organize big Rakefiles, tasks can be grouped into namespaces. Below is an example of a simple Rake recipe:

<span id="mwATU"></span><span class="n" id="mwATY">namespace</span><span class="w" id="mwATc"> </span><span class="ss" id="mwATg">:cake</span><span class="w" id="mwATk"> </span><span class="k" id="mwATo">do</span> <span class="w" id="mwATs"> </span><span class="n" id="mwATw">desc</span><span class="w" id="mwAT0"> </span><span class="s1" id="mwAT4">'make pancakes'</span> <span class="w" id="mwAT8"> </span><span class="n" id="mwAUA">task</span><span class="w" id="mwAUE"> </span><span class="ss" id="mwAUI">:pancake</span><span class="w" id="mwAUM"> </span><span class="o" id="mwAUQ">=></span><span class="w" id="mwAUU"> </span><span class="o" id="mwAUY">[</span><span class="ss" id="mwAUc">:flour</span><span class="p" id="mwAUg">,</span><span class="ss" id="mwAUk">:milk</span><span class="p" id="mwAUo">,</span><span class="ss" id="mwAUs">:egg</span><span class="p" id="mwAUw">,</span><span class="ss" id="mwAU0">:baking_powder</span><span class="o" id="mwAU4">]</span><span class="w" id="mwAU8"> </span><span class="k" id="mwAVA">do</span> <span class="w" id="mwAVE"> </span><span class="nb" id="mwAVI">puts</span><span class="w" id="mwAVM"> </span><span class="s2" id="mwAVQ">"sizzle"</span> <span class="w" id="mwAVU"> </span><span class="k" id="mwAVY">end</span> <span class="w" id="mwAVc"> </span><span class="n" id="mwAVg">task</span><span class="w" id="mwAVk"> </span><span class="ss" id="mwAVo">:butter</span><span class="w" id="mwAVs"> </span><span class="k" id="mwAVw">do</span> <span class="w" id="mwAV0"> </span><span class="nb" id="mwAV4">puts</span><span class="w" id="mwAV8"> </span><span class="s2" id="mwAWA">"cut 3 tablespoons of butter into tiny squares"</span> <span class="w" id="mwAWE"> </span><span class="k" id="mwAWI">end</span> <span class="w" id="mwAWM"> </span><span class="n" id="mwAWQ">task</span><span class="w" id="mwAWU"> </span><span class="ss" id="mwAWY">:flour</span><span class="w" id="mwAWc"> </span><span class="o" id="mwAWg">=></span><span class="w" id="mwAWk"> </span><span class="ss" id="mwAWo">:butter</span><span class="w" id="mwAWs"> </span><span class="k" id="mwAWw">do</span> <span class="w" id="mwAW0"> </span><span class="nb" id="mwAW4">puts</span><span class="w" id="mwAW8"> </span><span class="s2" id="mwAXA">"use hands to knead butter squares into 1 1/2 cup flour"</span> <span class="w" id="mwAXE"> </span><span class="k" id="mwAXI">end</span> <span class="w" id="mwAXM"> </span><span class="n" id="mwAXQ">task</span><span class="w" id="mwAXU"> </span><span class="ss" id="mwAXY">:milk</span><span class="w" id="mwAXc"> </span><span class="k" id="mwAXg">do</span> <span class="w" id="mwAXk"> </span><span class="nb" id="mwAXo">puts</span><span class="w" id="mwAXs"> </span><span class="s2" id="mwAXw">"add 1 1/4 cup milk"</span> <span class="w" id="mwAX0"> </span><span class="k" id="mwAX4">end</span> <span class="w" id="mwAX8"> </span><span class="n" id="mwAYA">task</span><span class="w" id="mwAYE"> </span><span class="ss" id="mwAYI">:egg</span><span class="w" id="mwAYM"> </span><span class="k" id="mwAYQ">do</span> <span class="w" id="mwAYU"> </span><span class="nb" id="mwAYY">puts</span><span class="w" id="mwAYc"> </span><span class="s2" id="mwAYg">"add 1 egg"</span> <span class="w" id="mwAYk"> </span><span class="k" id="mwAYo">end</span> <span class="w" id="mwAYs"> </span><span class="n" id="mwAYw">task</span><span class="w" id="mwAY0"> </span><span class="ss" id="mwAY4">:baking_powder</span><span class="w" id="mwAY8"> </span><span class="k" id="mwAZA">do</span> <span class="w" id="mwAZE"> </span><span class="nb" id="mwAZI">puts</span><span class="w" id="mwAZM"> </span><span class="s2" id="mwAZQ">"add 3 1/2 teaspoons baking powder"</span> <span class="w" id="mwAZU"> </span><span class="k" id="mwAZY">end</span> <span class="k" id="mwAZc">end</span>

More in Computing and communication