github.com/sercand/please@v13.4.0+incompatible/docs/language.html (about)

     1  
     2      <h1>The BUILD language</h1>
     3  
     4      <p>Please's BUILD files typically contain a series of build rule declarations. These are
     5        invocations of builtins like <code>java_binary</code> which create new BUILD targets.</p>
     6  
     7      <p>However, you can do much more with it; the syntax is actually a restricted Python subset
     8        so it's possible to script the creation of build targets in elaborate ways. See
     9        <a href="#grammar">below</a> for a formal description of the grammar.</p>
    10  
    11      <p>You can do most things that one might consider "simple" Python; <code>for</code> and
    12        <code>if</code> statements, define functions, create lists and dicts, etc. Conventionally
    13        we keep complex logic in build_defs files but at present there is no difference in accepted
    14        syntax between the two.</p>
    15  
    16      <p>Since it is not possible to <code>import</code> things, one obviously requires a different
    17        method of sharing code; in Please that is <a href="lexicon.html#subinclude">subinclude</a>.
    18        This function takes the output of a build rule elsewhere in the repo and makes it available
    19        in the context of the currently executing file - for example, if it has defined a function,
    20        that function is now available in your BUILD file at the top level.</p>
    21  
    22      <p>See <a href="lexicon.html">here</a> for a full description of available builtin rules.</p>
    23  
    24      <h2>Types</h2>
    25  
    26      <p>The set of builtin types are again a subset of Python's:
    27        <ul>
    28  	<li>Integers (all integers are 64-bit signed integers)</li>
    29  	<li>Strings</li>
    30  	<li>Lists</li>
    31  	<li>Dictionaries</li>
    32  	<li>Functions</li>
    33  	<li><code>True</code>, <code>False</code> and <code>None</code> are singletons which are
    34  	  instantiated by name.</li>
    35        </ul>
    36      </p>
    37  
    38      <p>Specifically there are no classes, sets, floats or bytes. Tuples don't exist as a standalone
    39        type, in various cases lists are generated as a replacement. In some cases the runtime may
    40        prohibit modification of a list or dict when they can be shared between multiple BUILD files
    41        in order to prevent one from seeing another's modifications.</p>
    42  
    43      <p>Dictionaries are somewhat restricted in function; they may only be keyed by strings and cannot
    44        be iterated directly - i.e. one must use <code>keys()</code>, <code>values()</code> or
    45        <code>items()</code>. The results of all these functions are always consistently ordered.</p>
    46  
    47      <h2>Functions</h2>
    48  
    49      <p>The following functions are available as builtins; unless otherwise noted they mimic Python's
    50        builtins in most cases (although this is not guaranteed to every possible nuance).
    51        <ul>
    52  	<li><code>len</code></li>
    53  	<li><code>enumerate</code></li>
    54  	<li><code>zip</code></li>
    55  	<li><code>isinstance</code></li>
    56  	<li><code>range</code></li>
    57  	<li><code>any</code></li>
    58  	<li><code>all</code></li>
    59  	<li><code>sorted</code></li>
    60        </ul>
    61      </p>
    62  
    63      <p>Several additional builtin functions are also available:
    64        <ul>
    65  	<li><code>package_name</code> - returns the package being currently parsed.</li>
    66  	<li><code>join_path</code> - like <code>os.path.join</code></li>
    67  	<li><code>split_path</code> - like <code>os.path.split</code></li>
    68  	<li><code>splitext</code> - like <code>os.path.splitext</code></li>
    69  	<li><code>basename</code> - like <code>os.path.basename</code></li>
    70  	<li><code>dirname</code> - like <code>os.path.dirname</code></li>
    71  	<li><code>exec</code> - like <code>subprocess.Popen</code></li>
    72        </ul>
    73      </p>
    74  
    75      <p>The following are available as member functions of strings:
    76        <ul>
    77  	<li><code>join</code></li>
    78  	<li><code>split</code></li>
    79  	<li><code>replace</code></li>
    80  	<li><code>partition</code></li>
    81  	<li><code>rpartition</code></li>
    82  	<li><code>startswith</code></li>
    83  	<li><code>endswith</code></li>
    84  	<li><code>format</code> - although this lacks some functionality, <code>%</code> is generally preferred</li>
    85  	<li><code>lstrip</code></li>
    86  	<li><code>rstrip</code></li>
    87  	<li><code>strip</code></li>
    88  	<li><code>find</code></li>
    89  	<li><code>rfind</code></li>
    90  	<li><code>count</code></li>
    91  	<li><code>upper</code></li>
    92  	<li><code>lower</code></li>
    93        </ul>
    94      </p>
    95  
    96      <p>The following are available as member functions of dictionaries:
    97        <ul>
    98  	<li><code>keys</code></li>
    99  	<li><code>values</code></li>
   100  	<li><code>items</code></li>
   101  	<li><code>copy</code></li>
   102        </ul>
   103      </p>
   104  
   105      <p>Finally, messages can be logged to Please's usual logging mechanism. These
   106        may or may not be displayed depending on the <code>-v</code> flag; by default only
   107        <code>warning</code> and above are visible.
   108        <ul>
   109  	<li><code>log.debug</code></li>
   110  	<li><code>log.info</code></li>
   111  	<li><code>log.notice</code></li>
   112  	<li><code>log.warning</code></li>
   113  	<li><code>log.error</code></li>
   114  	<li><code>log.fatal</code> - this will cause the process to exit immediately and unsuccessfully.</li>
   115        </ul>
   116      </p>
   117  
   118      <h2>Style</h2>
   119  
   120      <p>We normally write BUILD files in an idiom which doesn't quite match standard Python styles.
   121        The justification is that these are mostly just inherited from working on Blaze, but a
   122        brief explanation follows after an example:</p>
   123  
   124      <pre><code>
   125        # Taken from //src/core/BUILD in the Please repo
   126        go_library(
   127            name = 'core',
   128            srcs = glob(['*.go'], exclude=['*_test.go', 'version.go']) + [':version'],
   129            visibility = ['PUBLIC'],
   130            deps = [
   131                '//third_party/go:gcfg',
   132                '//third_party/go:logging',
   133                '//third_party/go:queue',
   134            ]
   135        )
   136      </code></pre>
   137  
   138      <p><b>All arguments to build rules are passed as keywords.</b> This is pretty important
   139        since (1) nobody will be able to read your BUILD file otherwise and (2) while we don't
   140        normally change the order of function arguments, we might sometimes insert earlier ones
   141        which will break code using positional arguments.</p>
   142  
   143      <p>Arguments to functions like <code>glob()</code> and <code>subinclude()</code> are not
   144        necessarily passed as keywords.</p>
   145  
   146      <p>We put spaces around the <code>=</code> for each argument to the build rule.</p>
   147  
   148      <p>Either single or double quotes work, as usual, but don't mix both in one file.</p>
   149  
   150      <p>Lists either go all on one line:
   151        <pre><code>['*_test.go', 'version.go']</code></pre>
   152        or are broken across multiple lines like so:
   153        <pre><code>          [
   154                '//third_party/go:gcfg',
   155                '//third_party/go:logging',
   156                '//third_party/go:queue',
   157            ]</code></pre>
   158      </p>
   159  
   160      <p>Indentation is normally four spaces.</p>
   161  
   162      <p>We generally try to order lists lexicographically but don't always get this 100%.</p>
   163  
   164      <p>If you'd like an autoformatter for BUILD files, Google's
   165        <a href="https://github.com/bazelbuild/buildifier">Buildifier</a> is very good & fast.
   166        We use a slightly modified version of it internally & on the Please repo.</p>
   167  
   168      <h2><a name="grammar">Grammar</a></h2>
   169  
   170      <p>The grammar is defined as (more or less) the following, where <code>Ident</code>,
   171        <code>String</code>, <code>Int</code> and <code>EOL</code> are token types emitted by the lexer.</p>
   172  
   173      <pre><code>{{ .Grammar }}</code></pre>
   174  
   175      <p>As mentioned above, this is similar to Python but lacks the <code>import</code>, <code>try</code>,
   176        <code>except</code>, <code>finally</code>, <code>class</code>, <code>global</code>,
   177        <code>nonlocal</code>, <code>while</code> and <code>async</code> keywords. The implementation
   178        may happen to permit using these as identifiers although it's discouraged (some tools might
   179        attempt to operate on the file using Python's <code>ast</code> module for convenience, which would not
   180        be possible if those keywords are used).<br/>
   181        As a result, while <code>raise</code> and <code>assert</code> <b>are</b> supported, it's
   182        not possible to catch and handle the resulting exceptions. These hence function only to
   183        signal an error condition which results in immediate termination.</p>
   184  
   185      <p>A more limited set of operators than in Python are available. The provided set are
   186        considered sufficient for use in BUILD files.</p>
   187  
   188      <p>Function annotations similar to <a href="https://www.python.org/dev/peps/pep-3107">PEP-3107</a>
   189        / <a href="https://www.python.org/dev/peps/pep-0484">PEP-484</a> are available, although
   190        they have first-class meaning as type hints. The arguments are annotated with the expected
   191        type or types (separated by <code>|</code>) and when called the type of the argument will
   192        be verified to match. This makes it easier to give useful feedback to users if they
   193        make mistakes in their BUILD files (e.g. passing a string where a list is required).</p>
   194  
   195      <p>Varargs and kwargs functions are not supported.</p>
   196  
   197      <p><a href="https://www.python.org/dev/peps/pep-0498">PEP-498</a> style string interpolation
   198        is available, but it is much more limited than in Python; it can only interpolate variable
   199        names rather than arbitrary expressions.</p>