| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| <html> |
| |
| <head> |
| <meta http-equiv="Content-Language" content="en-us"> |
| <link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> |
| <title>Local Task</title> |
| </head> |
| |
| <body> |
| |
| <h2>Local</h2> |
| <h3>Description</h3> |
| <p>Adds a local property to the current scope. Property scopes exist at Apache Ant's |
| various "block" levels. These include targets as well as the |
| <a href="parallel.html">Parallel</a> and <a href="sequential.html">Sequential</a> |
| task containers (including <a href="macrodef.html">Macrodef</a> bodies). A local |
| property at a given scope "shadows" properties of the same name at higher scopes, |
| including the global scope. Note that using the Local task at the global |
| level effectively makes the property local to the "anonymous target" in which |
| top-level operations are carried out; it will not be defined for other targets |
| in the buildfile. <b>Since Ant 1.8</b></p> |
| |
| <p>A property is made local if the <code><local></code> task |
| precedes its definition. See the examples section.</p> |
| |
| <h3>Parameters</h3> |
| <table border="1" cellpadding="2" cellspacing="0"> |
| <tr> |
| <td valign="top"><b>Attribute</b></td> |
| <td valign="top"><b>Description</b></td> |
| <td align="center" valign="top"><b>Required</b></td> |
| </tr> |
| <tr> |
| <td valign="top">name</td> |
| <td valign="top">The property to declare in the current scope</td> |
| <td valign="top" align="center">Yes</td> |
| </tr> |
| </table> |
| |
| <h3>Examples</h3> |
| |
| <h4>Temporarily shadow a global property's value</h4> |
| |
| <pre> |
| <property name="foo" value="foo"/> |
| |
| <target name="step1"> |
| <echo>Before local: foo is ${foo}</echo> |
| <local name="foo"/> |
| <property name="foo" value="bar"/> |
| <echo>After local: foo is ${foo}</echo> |
| </target> |
| |
| <target name="step2" depends="step1"> |
| <echo>In step2: foo is ${foo}</echo> |
| </target> |
| </pre> |
| |
| <p>outputs</p> |
| |
| <pre> |
| step1: |
| [echo] Before local: foo is foo |
| [echo] After local: foo is bar |
| |
| step2: |
| [echo] In step2: foo is foo |
| </pre> |
| |
| <p>here the local-task shadowed the global definition |
| of <code>foo</code> for the remainder of the target step1.</p> |
| |
| <h4>Creating thread local properties</h4> |
| |
| <pre> |
| <property name="foo" value="foo"/> |
| |
| <parallel> |
| <echo>global 1: foo is ${foo}</echo> |
| <sequential> |
| <local name="foo"/> |
| <property name="foo" value="bar.1"/> |
| <echo>First sequential: foo is ${foo}</echo> |
| </sequential> |
| <sequential> |
| <sleep seconds="1"/> |
| <echo>global 2: foo is ${foo}</echo> |
| </sequential> |
| <sequential> |
| <local name="foo"/> |
| <property name="foo" value="bar.2"/> |
| <echo>Second sequential: foo is ${foo}</echo> |
| </sequential> |
| <echo>global 3: foo is ${foo}</echo> |
| </parallel> |
| </pre> |
| |
| <p>outputs something similar to</p> |
| |
| <pre> |
| [echo] global 3: foo is foo |
| [echo] global 1: foo is foo |
| [echo] First sequential: foo is bar.1 |
| [echo] Second sequential: foo is bar.2 |
| [echo] global 2: foo is foo |
| </pre> |
| |
| <h4>Use inside macrodef</h4> |
| |
| <p>This probably is where local can be applied in the most useful |
| way. If you needed a "temporary property" inside a macrodef in Ant |
| prior to Ant 1.8.0 you had to try to come up with a property name |
| that would be unique across macro invocations.</p> |
| |
| <p>Say you wanted to write a macro that created the parent directory |
| of a given file. A naive approach would be:</p> |
| |
| <pre> |
| <macrodef name="makeparentdir"> |
| <attribute name="file"/> |
| <sequential> |
| <dirname property="parent" file="@{file}"/> |
| <mkdir dir="${parent}"/> |
| </sequential> |
| </macrodef> |
| <makeparentdir file="some-dir/some-file"/> |
| </pre> |
| |
| <p>but this would create a global property "parent" on the first |
| invocation - and since properties are not mutable, any subsequent |
| invocation will see the same value and try to create the same |
| directory as the first invocation.</p> |
| |
| <p>The recommendation prior to Ant 1.8.0 was to use a property name |
| based on one of the macro's attributes, like</p> |
| |
| <pre> |
| <macrodef name="makeparentdir"> |
| <attribute name="file"/> |
| <sequential> |
| <dirname property="parent.@{file}" file="@{file}"/> |
| <mkdir dir="${parent.@{file}}"/> |
| </sequential> |
| </macrodef> |
| </pre> |
| |
| <p>Now invocations for different files will set different properties |
| and the directories will get created. Unfortunately this "pollutes" |
| the global properties space. In addition it may be hard to come up |
| with unique names in some cases.</p> |
| |
| <p>Enter <code><local></code>:</p> |
| |
| <pre> |
| <macrodef name="makeparentdir"> |
| <attribute name="file"/> |
| <sequential> |
| <local name="parent"/> |
| <dirname property="parent" file="@{file}"/> |
| <mkdir dir="${parent}"/> |
| </sequential> |
| </macrodef> |
| </pre> |
| |
| <p>Each invocation gets its own property name "parent" and there will |
| be no global property of that name at all.</p> |
| |
| </body> |
| </html> |
| |