Pants plugins that are expected to be widely useful, but not shipped with core pants belong here.
Having plugin code live in the main pants repo allows plugin authors to have their plugin tested and refactored alongside pants code while allowing pants core contributors a better grasp of how plugin APIs are used.
Most new plugins should get their own top-level contrib/
subdirectory although it may make sense
to house the source code for related plugins under one top-level contrib/
subdirectory. The
contrib/scrooge
directory is an example of this and houses two plugin tasks that both use the same
underlying Scrooge tool.
Contrib plugins should generally follow 3 basic setup steps:
-
Create a contrib source tree for the new plugin and register source roots A typical pure python layout would be:
contrib/example/ src/python/pants/contrib/example/... tests/python/pants_test/contrib/example/...
Source roots for this layout would be added to contrib/example/BUILD:
source_root('src/python', page, python_library, resources) source_root('tests/python', page, python_library, python_tests, resources)
NB: python code should be in the pants/contrib and pants_test/contrib namespaces and the
__init__.py
files for these shared root namespaces should contain a namespace declaration like so:__import__('pkg_resources').declare_namespace(__name__)
-
Make the local pants aware of your plugin This involves 3 edits to
pants.ini
. You'll need to add one entry in each of thepythonpath
,backend_packages
andbootstrap_buildfiles
lists:[DEFAULT] # Enable our own custom loose-source plugins as well as contribs. pythonpath: [ "%(buildroot)s/pants-plugins/src/python", ... "%(buildroot)s/contrib/example/src/python", # 1 ... ] backend_packages: [ "internal_backend.optional", "internal_backend.repositories", "internal_backend.sitegen", "internal_backend.utilities", ... "pants.contrib.example", # 2 ... ] ... [goals] bootstrap_buildfiles: [ "%(buildroot)s/BUILD", ... "%(buildroot)s/contrib/example/BUILD", # 3 ... "%(buildroot)s/examples/BUILD", "%(buildroot)s/testprojects/BUILD", ]
-
When you're ready for your plugin to be distributed, add a
provides
contrib_setup_py
descriptor to your main plugin BUILD target and register the plugin with the release script. Theprovides
descriptor just requires a name and description for your plugin suitable for pypi:python_library( name='plugin', sources=['register.py'], provides=contrib_setup_py( name='pantsbuild.pants.contrib.example', description='An example pants contrib plugin.' ) )
To register with the release script, add an entry to
contrib/release_packages.sh
:PKG_EXAMPLE=( "pantsbuild.pants.example" "//contrib/example/src/python/pants/contrib/example:plugin" "pkg_example_install_test" ) function pkg_example_install_test() { PIP_ARGS="$@" pip install ${PIP_ARGS} pantsbuild.pants.example==$(local_version) && \ execute_packaged_pants_with_internal_backends \ "extra_backend_packages='pants.contrib.example'" \ goals | grep "example-goal" &> /dev/null } # Once an individual (new) package is declared above, insert it into the array below) CONTRIB_PACKAGES=( PKG_SCROOGE PKG_EXAMPLE )
NB: The act of releasing your contrib distribution is part of of the normal
pantsbuild.pants
release process. You may need to request a release from the owners if you have a change that should be fast-tracked before the nextpantsbuild.pants
release. You can always test that your contrib distribution works though by doing a release dry run:./build-support/bin/release.sh -n