<commit_before>####################################
Using Pants with Thrift Dependencies
####################################

`Apache Thrift <http://thrift.apache.org/>`_ is a popular framework for working with
data types and service interfaces. It uses an Interface Definition Language (IDL) to
define these types and interfaces. There are tools to generate code in "real" programming
languages from Thrift IDL files. Two programs, perhaps in different in different
programming languages, should be able to communicate over Thrift interfaces by using
this generated code.

Pants knows Thrift. For each Thrift file you use, your codebase has some ``BUILD`` targets
that represent generating "real" code from IDL code. You can write code in your favorite
language that imports the generated code. To make the import work, your code's
``BUILD`` target depends on the appropriate Thrift ``BUILD`` target. The details of
that Thrift target depend on whether the IDL file "lives" in your source tree or
somewhere else.

There are two ways to use thrift:

* **Same-repo** Use this in the source tree where the Thrift files "live".
  This approach also lets you publish an IDL jar which other source trees
  can use...
* **Consuming Thrift from Elsewhere** Use this in other source trees
  to consume thrift published from the Thrift file's "home" repo.

*********
Same-repo
*********

If the Thrift IDL files live in your source tree, you can define Java and/or Python
library targets by setting up *lang*\_thrift_library targets. Other targets can depend
on a *lang*\_thrift_library; the associated code can then import the generated code.

For a Java example::

    # Target defined in src/thrift/com/twitter/mybird/BUILD:
    java_thrift_library(name='mybird',
      # Specify dependencies for thrift IDL file includes.
      dependencies=[
        pants('src/thrift/com/twitter/otherbird'),
      ],
      sources=globs('*.thrift')
    )

Pants knows that before it compiles such a target, it must first generate Java
code from the Thrift IDL files. Users can
depend on this target like any other internal target. In this case, users would
add a dependency on ``pants('src/thrift/com/twitter/mybird')``.

To make this thrift available to other source trees, you might publish it.

.. TODO when we have a doc about publishing it, link to it

*******************************
Consuming Thrift from Elsewhere
*******************************

Not all Thrift IDL files live in your repo. Pants supports cross-repo IDL
sharing
through IDL-only jars. An IDL-only jar is simply a Java ``jar``
containing raw thrift IDL files. This allows users to depend on a versioned
artifact to generate and compile the IDL themselves.

For example, you could consume the ``mybird`` artifact published above
in a different repo.

As with other code from elsewhere, you want to use :doc:`3rdparty`.
For Thrift, there are targets to use to pull in published IDL jars
and generate code from them, e.g., :ref:`bdict_idl_jar_thrift_library`
for Java and Scala::

  idl_jar_thrift_library(name='servo-exception-thrift-scala',
    thrift_jar=thrift_jar('org.archimedes', 'mybird-thrift-scala-only', '2.7.0'),
    language='scala',
    rpc_style='finagle',
  )

  idl_jar_thrift_library(name='servo-exception-thrift-java',
    thrift_jar=thrift_jar('org.archimedes', 'mybird-thrift-java-only', '2.7.0'),
    language='java',
  )

(So far, there is no Python or Ruby way to consume IDL jars. If all Ruby 
thrift lives in the same repo, you can publish the
:ref:`bdict_ruby_thrift_library` targets.)

******************************
Thrift Client & Server Example
******************************

Enough theoretical mumbo jumbo - let's build a thrift client & server with
pants! While the example is written in Java these same concepts apply to
other languages.

Thrift IDL
==========

Since we're writing a thrift service, let's start by defining the service
interface. As pants is our build tool we'll also define a ``BUILD`` file
with a target owning the sources. We define our thrift service in
``src/thrift/com/twitter/common/examples/pingpong/pingpong.thrift``.

.. include:: ../../../../../src/thrift/com/twitter/common/examples/pingpong/pingpong.thrift
  :code:

And a target owning the sources in
``src/thrift/com/twitter/common/examples/pingpong/BUILD``.

.. include:: ../../../../../src/thrift/com/twitter/common/examples/pingpong/BUILD
  :code:

Notice the target type is :ref:`bdict_java_thrift_library`, and this target<commit_msg>[PATCH 11/27] Pants-thrift docs: the consume-side part of the publishing tangled tale<commit_after>####################################
Using Pants with Thrift Dependencies
####################################

`Apache Thrift <http://thrift.apache.org/>`_ is a popular framework for working with
data types and service interfaces. It uses an Interface Definition Language (IDL) to
define these types and interfaces. There are tools to generate code in "real" programming
languages from Thrift IDL files. Two programs, perhaps in different in different
programming languages, should be able to communicate over Thrift interfaces by using
this generated code.

Pants knows Thrift. For each Thrift file you use, your codebase has some ``BUILD`` targets
that represent generating "real" code from IDL code. You can write code in your favorite
language that imports the generated code. To make the import work, your code's
``BUILD`` target depends on the appropriate Thrift ``BUILD`` target. The details of
that Thrift target depend on whether the IDL file "lives" in your source tree or
somewhere else.

There are two ways to use thrift:

* **Same-repo** Use this in the source tree where the Thrift files "live".
  This approach also lets you publish an IDL jar which other source trees
  can use...
* **Consuming Thrift from Elsewhere** Use this in other source trees
  to consume thrift published from the Thrift file's "home" repo.

*********
Same-repo
*********

If the Thrift IDL files live in your source tree, you can define Java and/or Python
library targets by setting up *lang*\_thrift_library targets. Other targets can depend
on a *lang*\_thrift_library; the associated code can then import the generated code.

For a Java example::

    # Target defined in src/thrift/com/twitter/mybird/BUILD:
    java_thrift_library(name='mybird',
      # Specify dependencies for thrift IDL file includes.
      dependencies=[
        pants('src/thrift/com/twitter/otherbird'),
      ],
      sources=globs('*.thrift')
    )

Pants knows that before it compiles such a target, it must first generate Java
code from the Thrift IDL files. Users can
depend on this target like any other internal target. In this case, users would
add a dependency on ``pants('src/thrift/com/twitter/mybird')``.

To make this thrift available to other source trees, you might
:doc:`publish it <publish>`.

*******************************
Consuming Thrift from Elsewhere
*******************************

Not all Thrift IDL files live in your repo. Pants supports cross-repo IDL
sharing
through IDL-only jars. An IDL-only jar is simply a Java ``jar``
containing raw thrift IDL files. This allows users to depend on a versioned
artifact to generate and compile the IDL themselves.

For example, you could consume the ``mybird`` artifact published above
in a different repo.

As with other code from elsewhere, you want to use :doc:`3rdparty`.
For Thrift, there are targets to use to pull in published IDL jars
and generate code from them, e.g., :ref:`bdict_idl_jar_thrift_library`
for Java and Scala::

  idl_jar_thrift_library(name='mybird-thrift-scala',
    thrift_jar=thrift_jar('org.archimedes', 'mybird-thrift-scala-only', '2.7.0'),
    language='scala',
    rpc_style='finagle',
  )

  idl_jar_thrift_library(name='mybird-thrift-java',
    thrift_jar=thrift_jar('org.archimedes', 'mybird-thrift-java-only', '2.7.0'),
    language='java',
  )

Notice something subtle here: these two ``idl_jar_thrift_library`` targets
use different ``thrift_jar`` values, one for Scala and one for Java. That
might seem strange: They consume Thrift IDL code, which is language agnostic.
Why have different ``thrift_jar``\s?

When you _publish_ an artifact that depends on an ``idl_jar_thrift_library``,
Pants needs an artifact with the JVM classes generated from the IDL.
It expects those to have been published by the IDL's "home" repo, the place
it was published from.
Pants uses the ``idl_jar_thrift_library``\'s ``thrift_jar``
parameter to figure out
the Jar with the generated code. (This works if Pants published those artifacts,
since it can assume the "-only" suffix naming convention; if the artifacts
were published some other way, you can specify the generated-code artifact
address via the ``idl_jar_thrift_library``\'s ``provided_by`` parameter.)

(So far, there is no Python or Ruby way to consume IDL jars. If all Ruby 
thrift lives in the same repo, you can publish the
:ref:`bdict_ruby_thrift_library` targets.)

******************************
Thrift Client & Server Example
******************************

Enough theoretical mumbo jumbo - let's build a thrift client & server with
pants! While the example is written in Java these same concepts apply to
other languages.

Thrift IDL
==========

Since we're writing a thrift service, let's start by defining the service
interface. As pants is our build tool we'll also define a ``BUILD`` file
with a target owning the sources. We define our thrift service in
``src/thrift/com/twitter/common/examples/pingpong/pingpong.thrift``.

.. include:: ../../../../../src/thrift/com/twitter/common/examples/pingpong/pingpong.thrift
  :code:

And a target owning the sources in
``src/thrift/com/twitter/common/examples/pingpong/BUILD``.

.. include:: ../../../../../src/thrift/com/twitter/common/examples/pingpong/BUILD
  :code:

Notice the target type is :ref:`bdict_java_thrift_library`, and this target
{'fraction_non_alphanumeric': 0.12275931520644512, 'fraction_numerical': 0.0018126888217522659, 'mean_word_length': 4.523359288097886, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7650060', 'n_tokens_mistral': 2765, 'n_tokens_neox': 2726, 'n_words': 1230}