Contribute Media
A thank you to everyone who makes this possible: Read More

Practical PyBuilder

Summary

PyBuilder is a software build tool written in pure python which mainly targets pure python applications. It provides glue between existing build frameworks, thus empowering you to focus on the big picture of the build process.

It will be shown through demonstrations and samples how a simple, human-readable and declarative configuration can lead to an astonishingly well-integrated build process which will make maintainers, developers and newcomers happy.

Description

Why another build tool

Starting up a simple python project with best practices still takes a lot of boilerplate and glueing (e.G. chaining unit tests and integration tests in the build process, adding a linter, measuring coverage, ...). It often results in extremely ugly homebrew scripts and edge-case solutions that are not reusable. There are even programs out there (e.G. cookiecutter) that encourage boilerplate code generation!

Build orchestration

PyBuilder borrows from the maven idea of phases (packaging, verifying, publishing, ...) to set up a fully declarative and automated build that can be run locally and remotely (build servers) in the very same way. Rather than reinventing the wheel, it provides glue between existing solutions (like unittest, coverage, flake8, ...) through a simple but powerful plugin mechanism.

The talk

After a more theoretical talk with a colleague at PyConDE 2013, I want to show how it's actually like to work with PyBuilder. This includes

  • starting up a project
  • running builds
  • using plugins
  • writing a plugin

The demo code will be made available on GitHub and I'll probably have recordings prepped in case something goes wrong.

Reviewer FAQ

How does PyBuilder compare to other existing solutions like zc.buildout?

As opposed to solutions like zc.buildout which focus on the building of complex projects (many parts, complex dependencies) PyBuilder emphasizes the full build process for very simple projects. Undoubtedly, buildout is more powerful for building in that regard and there is no reason to switch to PyBuilder.

However, for simple projects (a few packages, pure python) we believe that PyBuilder is better, especially if you're starting out with Python. The plugin architecture (as opposed to recipes) makes it easier to reason about what is going on. We are able to model dependencies between build phases (like "coverage" needing "unit tests" and "packaging" needing "integration tests") where recipes are not. It also seems (after looking through the recipes available for buildout) that we have more focus on QA as part of the build process (lint code, differentiate between unit/integration tests, code analysis, ...).

There is also a special focus on having the build descriptor written in Python (with fluent interfaces where possible) so that it is possible to understand what the configuration is by reading plain english, as opposed to zc.buildout (where the configuration is an ini file, or SCons which is very make-oriented).

In the end, a big difference between most build tools and PyBuilder is that PyBuilder is more about orchestration. We didn't reinvent packaging or linting, we simply use what is already there (setuptools, flake8, pymetrics, ...). This allows users to use the tools they want without having to do the integration themselves, and still get a nice, unified build process out of it.

A simple example :

In buildout, code analysis can be done with

[buildout]
parts += code-analysis

[code-analysis]
recipe = plone.recipe.codeanalysis
directory = ${buildout:directory}/src

This is not readable IMHO. In PyBuilder it can look like this :

use_plugin('python.flake8')
project.set_property('flake8_include_test_sources', True)
project.set_property('flake8_ignore', 'E501')
project.set_property('flake8_break_build', True)
"It provides glue between existing build frameworks" - which ones ? Could you name (some at least) ?

Currently there is only a plugin for building with distutils/setuptools. Should that change (e.G. new contender) it would be easy to switch using PyBuilder.

Examples where glue is needed :

  • Glue setuptools + unittest, so that no distribution can be shipped if tests fail
  • Glue setuptools + coverage + unittest, so that no distribution can be shipped if the statement coverage is too low (configurable ofc)
  • Glue setuptools + pip so that cloned projects can be built with their dependencies without needing to pip install manually

Details

Improve this page