Require / Provide

This is a generalised mechanism for rules to provide specialised dependencies to other rules. The most obvious example is proto_library, which generates code for multiple languages, usually only one of which is actually needed by each dependency

We could break it up into multiple parts explicitly, but ideally we want to maintain the illusion that there's one rule by the name given in the BUILD file and have all other rules depend only on that. However it's pretty suboptimal to have your python_library have to wait for the C++ and Java generated code to compile.

This is solved by the proto_library rule declaring the following property:


    provides = {
        "py": ":python_dependency",
        "java": ":java_dependency",
        "cc": ":cc_dependency",
    }
    
And then the python_library rule is annotated with

    requires = ["py"],
    
Individually neither has any effect, but when a rule with a particular require depends on another with a matching provide, its dependency is matched directly to the one specified by the providing rule. This means that it can skip other dependencies that it doesn't care about and be matched only to the ones it does.

The consequence of this - skipping the actual declared dependency - can be a bit nonobvious so should be invoked sparingly. Typically the rule declaring provides should be a no-op collecting rule such as filegroup and the various provided rules shouldn't normally be needed together. Different languages are the most common example here (and indeed this feature was nearly named language at one point).

The requires stanza is also responsible for colouring the interactive build output. Currently the available colours are hardcoded but one of these days they might become configurable.