blob: 940622a3217657ac646cd576ed2d4449832b0fac (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
<!DOCTYPE html>
<!--
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
https://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 lang="en">
<head>
<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
<title>Local Task</title>
</head>
<body>
<h2>Local</h2>
<p><em>Since Ant 1.8</em></p>
<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 <code>Local</code> 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.</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 class="attr">
<tr>
<th scope="col">Attribute</th>
<th scope="col">Description</th>
<th scope="col">Required</th>
</tr>
<tr>
<td>name</td>
<td>The property to declare in the current scope</td>
<td>Yes</td>
</tr>
</table>
<h3>Parameters specified as nested elements</h3>
<h4>Name</h4>
<p>As an alternative to (or in conjunction with) the <code>name</code> attribute, the nested text of
each of one or more nested <code><name></code> elements specifies a property name to declare in
the local scope. <em>Since Ant 1.10.13</em></p>
<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 class="output">
step1:
[echo] Before local: foo is foo
[echo] After local: foo is bar
step2:
[echo] In step2: foo is foo</pre>
<p>here the <code>local</code> task shadowed the global definition of <code>foo</code> for the
remainder of the target <q>step1</q>.</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 class="output">
[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 <code>macrodef</code></h4>
<p>This probably is where <code>local</code> can be applied in the most useful way. If you needed a
"temporary property" inside a <code>macrodef</code> 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 <code>parent</code> 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 named <code>parent</code> and there will be no global
property of that name at all.</p>
<h4>Use of nested name elements</h4>
This style declares and executes a single task, as compensation for requiring more lines of XML than
would individual invocations using <code>@name</code>:
<pre>
<local>
<name>foo</name>
<name>bar</name>
<name>baz</name>
</local>
</pre>
</body>
</html>
|