@menu
* Builder Configuration::
* Merging Build Requests::
* Prioritizing Builds::
@end menu

@node Builder Configuration
@subsection Builder Configuration

@bcindex c['builders']

The @code{c['builders']} key is a list of objects giving configuration for the
Builders.  For more information, @xref{Builder}.  The class definition for the
builder configuration is in @code{buildbot.config}.  In the configuration file,
its use looks like:

@example
from buildbot.config import BuilderConfig
c['builders'] = [
    BuilderConfig(name='quick', slavenames=['bot1', 'bot2'], factory=f_quick),
    BuilderConfig(name='thorough', slavename='bot1', factory=f_thorough),
]
@end example

The constructor takes the following keyword arguments:

@table @code
@item name
This specifies the Builder's name, which is used in status
reports.

@item slavename
@item slavenames
These arguments specify the buildslave or buildslaves that will be used by this
Builder.  All slaves names must appear in the @code{c['slaves']} list. Each
buildslave can accomodate multiple Builders.  The @code{slavenames} parameter
can be a list of names, while @code{slavename} can specify only one slave.

@item factory
This is a @code{buildbot.process.factory.BuildFactory} instance which
controls how the build is performed. Full details appear in their own
section, @xref{Build Factories}. Parameters like the location of the CVS
repository and the compile-time options used for the build are
generally provided as arguments to the factory's constructor.

@end table

Other optional keys may be set on each Builder:

@table @code

@item builddir
Specifies the name of a subdirectory (under the base directory) in which
everything related to this builder will be placed on the buildmaster.
This holds build status information. If not set, defaults to @code{name}
with some characters escaped. Each builder must have a unique build
directory.

@item slavebuilddir
Specifies the name of a subdirectory (under the base directory) in which
everything related to this builder will be placed on the buildslave.
This is where checkouts, compiles, and tests are run. If not set,
defaults to @code{builddir}. If a slave is connected to multiple builders
that share the same @code{slavebuilddir}, make sure the slave is set to
run one build at a time or ensure this is fine to run multiple builds from
the same directory simultaneously.

@item category
If provided, this is a string that identifies a category for the
builder to be a part of. Status clients can limit themselves to a
subset of the available categories. A common use for this is to add
new builders to your setup (for a new module, or for a new buildslave)
that do not work correctly yet and allow you to integrate them with
the active builders. You can put these new builders in a test
category, make your main status clients ignore them, and have only
private status clients pick them up. As soon as they work, you can
move them over to the active category.

@item nextSlave
If provided, this is a function that controls which slave will be assigned
future jobs. The function is passed two arguments, the @code{Builder}
object which is assigning a new job, and a list of @code{SlaveBuilder}
objects. The function should return one of the @code{SlaveBuilder}
objects, or @code{None} if none of the available slaves should be
used.  This function can optionally return a Deferred which should
fire with the same results.

@item nextBuild
If provided, this is a function that controls which build request will be
handled next. The function is passed two arguments, the @code{Builder} object
which is assigning a new job, and a list of @code{BuildRequest} objects
representing pending build requests, sorted by increasing submission time.  .
The function should return one of the @code{BuildRequest} objects, or
@code{None} if none of the pending builds should be started.  This function can
optionally return a Deferred which should fire with the same results.

@item locks
This argument specifies a list of locks that apply to this builder; @xref{Interlocks}.

@item env
A Builder may be given a dictionary of environment variables in this parameter.
The variables are used in @pxref{ShellCommand} steps in builds created by this
builder. The environment variables will override anything in the buildslave's
environment. Variables passed directly to a @code{ShellCommand} will override
variables of the same name passed to the Builder.

For example, if you have a pool of identical slaves, it is often easier to
manage variables like PATH from Buildbot, rather than manually editing it inside
of the slaves' environment.

@example
f = factory.BuildFactory
f.addStep(ShellCommand(
              command=['bash', './configure']))
f.addStep(Compile())

c['builders'] = [
  BuilderConfig(name='test', factory=f,
        slavenames=['slave1', 'slave2', 'slave3', 'slave4'],
        env=@{'PATH': '/opt/local/bin:/opt/app/bin:/usr/local/bin:/usr/bin'@}),
]
@end example

@item mergeRequests
Specifies how build requests for this builder should be merged, overriding the
global option (@pxref{Merging Build Requests (global option)}).  See
@ref{Merging Build Requests} for details.

@item properties
A builder may be given a dictionary of @ref{Build Properties}
specific for this builder in this parameter. Those values can be used
later on like other properties. @pxref{WithProperties}.

@end table

@node Merging Build Requests
@subsection Merging Build Requests

When more than one build request is available for a builder, Buildbot can
"merge" the requests into a single build.  This is desirable when build
requests arrive more quickly than the available slaves can satisfy them, but
has the drawback that separate results for each build are not available.

This behavior can be controlled globally, using the @code{c['mergeRequests']}
parameter, and on a per-builder basis, using the @code{mergeRequests} argument
to the builder configuration.  If @code{mergeRequests} is given, it completely
overrides the global configuration.

For either configuration parameter, a value of @code{True} (the default) causes
buildbot to merge BuildRequests that have "compatible" source stamps.  Source
stamps are compatible if:

@itemize
@item their branch, project, and repository attributes match exactly;
@item neither source stamp has a patch (e.g., from a try scheduler); and
@item either both source stamps are associated with changes, or neither ar
associated with changes but they have matching revisions.
@end itemize

This algorithm is implemented by the SourceStamp method @code{canBeMergedWith}.

A configuration value of @code{False} indicates that requests should never be
merged.

If the configuration value is a callable, that callable will be invoked with
three positional arguments: a @code{Builder} object and two @code{BuildRequest}
objects. It should return true if the requests can be merged, and False
otherwise. For example:

@example
def mergeRequests(builder, req1, req2):
    "any requests with the same branch can be merged"
    return req1.branch == req2.branch
c['mergeRequests'] = mergeRequests
@end example

In many cases, the details of the SourceStamps and BuildRequests are important.
In this example, only BuildRequests with the same "reason" are merged; thus
developers forcing builds for different reasons will see distinct builds.  Note
the use of the @code{canBeMergedWith} method to access the source stamp
compatibility algorithm.

@example
def mergeRequests(builder, req1, req2):
    if req1.source.canBeMergedWith(req2.source) and  req1.reason == req2.reason:
       return True
    return False
c['mergeRequests'] = mergeRequests
@end example

If it's necessary to perform some blocking operation to determine whether two
requests can be merged, then the @code{mergeRequests} callable may return its
result via Deferred.  Note, however, that the number of invocations of the
callable is proportional to the square of the request queue length, so a
long-running callable may cause undesirable delays when the queue length grows.

@node Prioritizing Builds
@subsection Prioritizing Builds

The @code{BuilderConfig} parameter @code{nextBuild} can be use to prioritize
build requests within a builder. Note that this is orthogonal to
@pxref{Prioritizing Builders}, which controls the order in which builders are
called on to start their builds.

@example
def nextBuild(bldr, requests):
    for r in requests:
        if r.source.branch == 'release':
            return r
    return requests[0]
    
c['builders'] = [
  BuilderConfig(name='test', factory=f,
        nextBuild=nextBuild,
        slavenames=['slave1', 'slave2', 'slave3', 'slave4']),
]
@end example
