blob: 35b1a1e156183478313c2c2d4242366c645e9924 [file] [log] [blame]
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed 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.
*/
{namespace buck.visibility}
/***/
{template .soyweb}
{call buck.page}
{param title: 'Visibility' /}
{param navid: 'concept_visibility' /}
{param prettify: true /}
{param description}
Determines whether a build rule can include a build target in its list
of dependencies.
{/param}
{param content}
<p>
Visibility determines whether a build rule can include a build target in its
list of <code>deps</code>. In a large project, you may want to prevent
developers from "reaching across" the project and pulling in additional code.
Reducing the visibility of build rules can help prevent that type of behavior.
</p>
<p>
There are two types of visibility attributes available, each of which takes a
list of {sp}<a href="{ROOT}concept/build_target_pattern.html">build target
patterns</a>: <code>visibility</code>, which determines what other targets can
depend on a target, and <code>within_view</code>, which determines what other
targets a target can depend on.
</p>
<p>
Both attributes act as whitelists, with some exceptions. In general, if a target
is not listed, there may be no dependency relationship. If
the <code>within_view</code> list is empty or unset, however, its check is
bypassed. Similarly, targets defined in the same build file always act as if
they were members of their siblings' <code>visibility</code> lists.
</p>
<p>
There is also a special value, <code>'PUBLIC'</code>, which makes a build rule
visible to all other rules. <code>'PUBLIC'</code> is valid
in <code>visibility</code> but not <code>within_view</code>.
</p>
<p>
In case of logically-conflicting lists, <code>within_view</code> takes
precedence over <code>visibility</code>.
If <code>//foo:bar</code> defines <code>//hello:world</code> in
its <code>visibility</code> list, but <code>//hello:world</code> does not
define <code>//foo:bar</code> in its <code>within_view</code> list,
then <code>//hello:world</code> may not depend on <code>//foo:bar</code>.
</p>
<h2>Examples</h2>
<p>
A common library like Guava should be able to be included by any build rule:
</p>
{literal}<pre class="prettyprint lang-py">
prebuilt_jar(
name = 'guava',
binary_jar = 'guava-14.0.1.jar',
visibility = [
'PUBLIC',
],
)
</pre>{/literal}
<p>
It is common to restrict the visibility of Android resources to the Java code
that uses it:
</p>
{literal}<pre class="prettyprint lang-py">
android_resource(
name = 'ui_res',
res = 'res',
package = 'com.example',
visibility = [
'//java/com/example/ui:ui',
],
)
</pre>{/literal}
<p>
Or it may be simpler to make it visible to the entire directory in case
additional build rules are added to <code>java/com/example/ui/BUCK</code>:
</p>
{literal}<pre class="prettyprint lang-py">
android_resource(
name = 'ui_res',
res = 'res',
package = 'com.example',
visibility = [
'//java/com/example/ui:',
],
)
</pre>{/literal}
<p>
Also, it is common to limit code for testing to be visible only to tests.
If you define all of your Java unit tests in a folder named
{sp}<code>javatests/</code> in the root of your project, then you could
define the following rule to ensure that only allow build rules
under <code>javatests/</code> can depend on JUnit:
</p>
{literal}<pre class="prettyprint lang-py">
prebuilt_jar(
name = 'junit',
binary_jar = 'junit-4.11.jar',
visibility = [
'//javatests/...',
],
)
</pre>{/literal}
<p>
Finally, restricting the view of a target can be useful for preventing
dependency creep:
</p>
{literal}<pre class="prettyprint lang-py">
java_library(
name = 'example',
visibility = [
'PUBLIC',
],
within_view = [
'//foo:bar',
'//hello:world',
],
)
</pre>{/literal}
{/param}
{/call}
{/template}