<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Fischer dot Name &#187; distutils</title>
	<atom:link href="http://www.davidfischer.name/tag/distutils/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.davidfischer.name</link>
	<description>Some Things to Some People</description>
	<lastBuildDate>Thu, 15 Jul 2010 21:05:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Extending Distutils for Repeatable Builds</title>
		<link>http://www.davidfischer.name/2010/01/extending-distutils-for-repeatable-builds/</link>
		<comments>http://www.davidfischer.name/2010/01/extending-distutils-for-repeatable-builds/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 07:28:11 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[distutils]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[pypi]]></category>

		<guid isPermaLink="false">http://www.davidfischer.name/?p=373</guid>
		<description><![CDATA[Distutils is Python&#8217;s built-in mechanism]]></description>
			<content:encoded><![CDATA[<p><a href="http://docs.python.org/distutils/index.html">Distutils</a> is Python&#8217;s built-in mechanism for packaging and installing Python modules. It is very convenient for packaging up your source code, scripts and other files and creating a distribution to be uploaded to <a href="http://pypi.python.org/pypi">pypi</a> as I&#8217;ve mentioned <a href="http://www.davidfischer.name/2009/07/packaging-and-sharing-django-applications/">before</a>. Distutils was <a href="http://www.timecastle.net/static/1-python-distutils.pdf">discussed</a> (pdf) at PyCon last year and it looks like there are efforts <a href="http://tarekziade.wordpress.com/2010/01/07/possible-new-features-for-distutils-2-7/">afoot</a> to improve it to add some much needed features like unittesting and <a href="http://www.python.org/dev/peps/pep-0390/">metadata</a>. Add-on packages like <a href="http://pip.openplans.org/">pip</a> add additional features like uninstallation and dependency management but nothing guarantees that your users have it. Although Python&#8217;s packaging and distribution model beats PHP&#8217;s hands down, there is still a lot of room for improvement to make it seamless.</p>
<h5>Release management</h5>
<p>In essence, these issues and enhancements boil down to making release management easier. When releasing your package, you want to make sure that it contains all the appropriate files, is tested and can be installed easily. Distutils helps with the installation, pip with the dependencies and <a href="http://virtualenv.openplans.org/">virtualenv</a> (a topic for a later post) helps a lot with testing package interactions. But what about unittests? What about cleaning up after setup.py? What about generating documentation or other files?</p>
<h5>Extending distutils</h5>
<p>Until all these features get put into distutils, you have to <a href="http://docs.python.org/distutils/extending.html">extend</a> it yourself in <span style="font-family:monospace">setup.py</span>. Fortunately, this is not very complicated and can buy you some reliability in your build process. Adding a command like <span style="font-family:monospace">python setup.py test</span> is pretty trivial:</p>
<pre><code class="python">from distutils.core import setup
from unittest import TextTestRunner, TestLoader
import mymodule.tests

cmdclasses = dict()

class TestCommand(Command):
    """Runs the unit tests for mymodule"""

    user_options = []
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass
    def run(self):
        loader = TestLoader()
        t = TextTestRunner()
        t.run(loader.loadTestsFromModule(mymodule.tests))

# 'test' is the parameter as it gets added to setup.py
cmdclasses['test'] = TestCommand

setup(cmdclass = cmdclasses
#...
)</code></pre>
<p>The same sort of functionality could be used to verify any prerequisites not already checked by distutils or pip, generate documentation without external dependencies like <a href="http://code.djangoproject.com/browser/django/trunk/docs/Makefile">Make</a> (although Django supports Python 2.3 before this functionality was available) or to create a uniform way to take source control diffs and submit patches. Executing these commands from one place makes the whole process more consistent and easy to understood. Hopefully the new enhancements to distutils will make the process even better.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.davidfischer.name/2010/01/extending-distutils-for-repeatable-builds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
