<?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>( f o o b a r . l u )</title>
	<atom:link href="http://foobar.lu/wp/feed/" rel="self" type="application/rss+xml" />
	<link>http://foobar.lu/wp</link>
	<description>coding should be fun</description>
	<lastBuildDate>Sat, 19 May 2012 10:06:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Update to the python packaging guide.</title>
		<link>http://foobar.lu/wp/2012/05/19/update-to-the-python-packaging-guide/</link>
		<comments>http://foobar.lu/wp/2012/05/19/update-to-the-python-packaging-guide/#comments</comments>
		<pubDate>Sat, 19 May 2012 10:06:16 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=319</guid>
		<description><![CDATA[Following some of the comments, the previous article about python packaging has been updated. Added a note about pip install -e as an alternative to python setup.py develop Added a note about testpypi.python.org Fixed the section about the manifest (I forgot to add include_package_data to the setup script)]]></description>
			<content:encoded><![CDATA[<p>Following some of the comments, the <a href="http://foobar.lu/wp/2012/05/13/a-comprehensive-step-through-python-packaging-a-k-a-setup-scripts/">previous article about python packaging</a> has been updated.</p>
<ul>
<li>Added a note about <tt>pip install -e</tt> as an alternative to <tt>python setup.py develop</tt></li>
<li>Added a note about testpypi.python.org</li>
<li>Fixed the section about the manifest (I forgot to add <tt>include_package_data</tt> to the setup script)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/05/19/update-to-the-python-packaging-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A comprehensive guide through Python packaging (a.k.a. setup scripts)</title>
		<link>http://foobar.lu/wp/2012/05/13/a-comprehensive-step-through-python-packaging-a-k-a-setup-scripts/</link>
		<comments>http://foobar.lu/wp/2012/05/13/a-comprehensive-step-through-python-packaging-a-k-a-setup-scripts/#comments</comments>
		<pubDate>Sun, 13 May 2012 13:03:39 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=270</guid>
		<description><![CDATA[One of the really useful things in python are the setup scripts. When doing &#8220;serious&#8221; business, you really should look into them. Setup scripts are amazingly powerful. But they don&#8217;t necessarily need to be complex. But because of this flexibility, the documentation around them seems like a lot to read. Additionally, the state of packaging [...]]]></description>
			<content:encoded><![CDATA[<p>One of the really useful things in python are the setup scripts. When doing &#8220;serious&#8221; business, you <em>really</em> should look into them. Setup scripts are amazingly powerful. But they don&#8217;t necessarily need to be complex. But because of this flexibility, the documentation around them seems like a lot to read. Additionally, the state of packaging has changed quite a bit over the years. So you now have a couple of packages (distutils, setuptools, distribute) which all seem to try to solve the same problem. See <a title="The Current State of Packaging in Python" href="http://guide.python-distribute.org/introduction.html#current-state-of-packaging">the current state of packaging</a> for more details on this.</p>
<p>This post attempts to summarize the important bits using a &#8220;Hello World&#8221; project and steeping through the process of creating the <tt>setup.py</tt> file:</p>
<ul>
<li>Creating a package distribution</li>
<li>Automatic generation of executables</li>
<li>Version numbers</li>
<li>Dependency management</li>
<li>Publishing your package (thus also making it available for automatic dependency resolution)</li>
<li>Some more food for thought.</li>
</ul>
<div class="note admonition">
<strong>NOTE:</strong> The <tt>setup.py</tt> script we will construct in this post, will use two bits of code which may not work in all cases:</p>
<ul>
<li>importing the package itself (to centralize the version number)</li>
<li>Reading the long_description content from a text-file</li>
</ul>
<p>Both methodologies have their issues. Importing the package only works if you <em>can</em> import it cleanly (i.e. without dependencies) from standard python. Reading the text file only works if the <tt>setup.py</tt> is called from the proper location.</p>
<p>This is <em>mostly</em> true. There are corner-cases however where this is not possible. If that is the case, you will need to live without these helpful shortcuts. See the comments on this article for more on this.
</div>
<p><span id="more-270"></span></p>
<h2>Our Hello World project</h2>
<p>Our project will provide the following:</p>
<ul>
<li>a package called <tt>helloworld</tt></li>
<li>a method returning the string &#8220;Hello World!&#8221;</li>
<li>an executable printing &#8220;Hello World!&#8221; to the standard output.</li>
</ul>
<h2>Creating a package distribution</h2>
<p>Before you can do any of the aforementioned points, you need to be able to create a package file. In most cases, this would be a tarball (a source distribution). First, you need to think about your file layout:</p>
<p>In python, every package lives in its own folder. Unless you have a one-file module. For the sake of this post, I will assume you have a folder, and leave the one-file module as an exercise to the reader. After all, the differences are not all that great. Let&#8217;s also assume, for the sake of simplicity, we have only one module in our package folder.</p>
<h2>Let&#8217;s create the package</h2>
<p>First, the file laout:</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">the-helloworld-project<br />
└── helloworld<br />
&nbsp; &nbsp; ├── __init__.py<br />
&nbsp; &nbsp; └── core.py</div></div>
<p class="admonition note"><strong>NOTE:</strong> This is just an <em>example</em> project, and it could have been implemented as a one-file module (using <tt>core.py</tt>), or the application logic could have been stuffed into <tt>__int__.py</tt>. But I assume that multi-file packages are far more common, so I will use an appropriate layout for that. Also, I personally like to <em>always </em>create my projects like this. On the one hand for consistency, and on the other hand it makes it easier to &#8220;grow&#8221; the project later on. It&#8217;s up to you to decide for yourself.</p>
<p>In this case, I named the project root &#8220;the-helloworld-project&#8221;. But (again, personally), I just give the root folder the same name as the package name. The difference between the root (&#8220;the-helloworld-project&#8221;) and the package (&#8220;helloworld&#8221;) is that  the package folder contains the actual package code, and the root folder contains packaging metadata and possibly some other development related stuff (unit-tests, fabric files, a readme, the license file, &#8230;)</p>
<p>Next, let&#8217;s create our business logic. For our target features, we need both a method generating our &#8220;Hello World!&#8221; message, and one to print it to stdout. Let&#8217;s put this into <tt>helloworld/core.py</tt>:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> get_message<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;Hello World!&quot;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> print_message<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> get_message<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>So far so good. We have our business logic. Yay \o/.</p>
<h2>Creating a skeleton setup.py file</h2>
<p>Next up, we will create a <em>very</em> simple <tt>setup.py</tt> file. Let&#8217;s also add a <tt>README.txt</tt> file for good measure (it should be formatted in <a href="http://docutils.sourceforge.net/rst.html">ReST</a>!):</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Description<br />
===========<br />
<br />
An example Hello World project.</div></div>
<p>Next, let&#8217;s create a very simple setup script, and put it into the root folder:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'helloworld'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'1.0'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></div>
<p>Note that we don&#8217;t use <tt>distutils</tt>, but <tt>setuptools</tt>. You will be better off with <tt>setuptools</tt> until <tt>distutils2</tt> is available.</p>
<p class="admonition warning"><strong>IMPORTANT:</strong><br />
The package <tt>setuptools</tt> is actually made available by a package named <tt>distribute</tt>. You should <em>not</em> install the old <tt>setuptools</tt> any more!
</p>
<h3>WARNING</h3>
<p>As Ionel Maries Cristian pointed out in the comments, the line <tt>long_description=open('README.txt').read()</tt> could cause problems. Let&#8217;s make it safer&#8230;</p>
<p>We know that the README file sits in the same folder as the setup script. So we can use <tt>os.path.dirname</tt> on <tt>__file__</tt> to construct a filename we can reach:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span> <span style="color: #ff7700;font-weight:bold;">import</span> join<span style="color: #66cc66;">,</span> dirname<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'helloworld'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'1.0'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>dirname<span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: black;">&#41;</span></div></div>
<p>Now we can test to create a source distribution by running:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">python setup.py sdist</div></div>
<p>There will be some warnings as we did fill in neither an author email nor a package URL. For this example we consider this okay!</p>
<p>This will give you a file called <tt>sdist/helloworld-1.0.tar.gz</tt>. You can inspect it if you want using <tt>tar tzvf sdist/helloworld-1.0.tar.gz</tt>.</p>
<p>With this done, we already have two points of our targets done:</p>
<ul>
<li><del datetime="2012-05-13T09:50:57+00:00">a package called <tt>helloworld</tt></del></li>
<li><del datetime="2012-05-13T09:50:57+00:00">a method returning the string &#8220;Hello World!&#8221;</del></li>
<li>an executable printing &#8220;Hello World!&#8221; to the standard output.</li>
</ul>
<h2>Testing inside a virtual environment</h2>
<p>The details about virtual environments are out of the scope of this document (see <a href="http://pypi.python.org/pypi/virtualenv/">the package documentation</a> for more). But because it is <em>highly</em> recommended to use them, we will do so right now. This gives us the ability to test the package installation without polluting our system packages.</p>
<p>So let&#8217;s create one:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">virtualenv env</div></div>
<p>This will create an environment called <tt>env</tt> in our current working folder and install <tt>pip</tt> and <tt>distribute</tt> into it. With this in place, we can already test the package installation:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./env/bin/python setup.py install<br />
running install<br />
running bdist_egg<br />
running egg_info<br />
[...]<br />
Processing dependencies for helloworld==1.0<br />
Finished processing dependencies for helloworld==1.0</div></div>
<p>Now we can test our package within the virtual environment:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./env/bin/python<br />
&gt;&gt;&gt; import helloworld.core as hw<br />
&gt;&gt;&gt; hw.get_message()<br />
'Hello World!'<br />
&gt;&gt;&gt; hw.print_message()<br />
Hello World!</div></div>
<p>Perfekt!</p>
<p>But we still want our executable&#8230;</p>
<h2>Creating an executable</h2>
<p>Following <a href="http://docs.python.org/distutils/setupscript.html#installing-scripts">the official <tt>distutils</tt> documentation</a>, we should specify the <tt>scripts</tt> keyword argument on the <tt>setup</tt> method. On the other hand, <tt>distribute</tt> gives us <a href="http://guide.python-distribute.org/creation.html#entry-points">entry points</a>. Personally, I prefer entry points. So let&#8217;s get this done. Modify the <tt>setup.py</tt> file and add the following:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: black;">entry_points</span><span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'console_scripts'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #483d8b;">'helloworld = helloworld.core:print_message'</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span></div></div>
<p>The complete setup.py file should now look like this:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span> <span style="color: #ff7700;font-weight:bold;">import</span> join<span style="color: #66cc66;">,</span> dirname<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'helloworld'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'1.0'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>dirname<span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; entry_points<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'console_scripts'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #483d8b;">'helloworld = helloworld.core:print_message'</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span></div></div>
<p>What does this mean?</p>
<ul>
<li><tt>helloworld = ...</tt><br />
        Create an executable with the name <tt>helloworld</tt> (on windows it will be a .exe file)</li>
<li><tt>... = helloworld.core:...</tt><br />
        The method is found in this package</li>
<li><tt>... :print_message</tt><br />
        Call this method on execution</li>
</ul>
<p>Let&#8217;s re-install our package:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./env/bin/python setup.py install<br />
...<br />
Installing helloworld script to /path/to/the-helloworld-project/env/bin<br />
...<br />
$</div></div>
<p>As you can see in the output, the setup script installed an executable into our local <tt>bin</tt> folder. If you execute it, your method from your package will be executed.</p>
<p>Awesome!  We can cross the last item off our basic tasks:</p>
<ul>
<li><del datetime="2012-05-13T09:50:57+00:00">a package called <tt>helloworld</tt></del></li>
<li><del datetime="2012-05-13T09:50:57+00:00">a method returning the string &#8220;Hello World!&#8221;</del></li>
<li><del datetime="2012-05-13T09:50:57+00:00">an executable printing &#8220;Hello World!&#8221; to the standard output.</del></li>
</ul>
<div class="admonition note">
When running the setup script, you can also use the <tt>develop</tt> command instead of the <tt>install</tt> command. This will link the installed package with your source files. In this way, you don&#8217;t need to re-install the package when you change the source code. However, when you change something in your <tt>setup.py</tt> file, you need to re-run it of course!</p>
<p>Additionally, with <tt>pip</tt> you can instead use <tt>pip install -e .</tt> to achieve the same as with <tt>python setup.py develop</tt> with the advantage that <tt>pip</tt> also has an <tt>uninstall</tt> command.
</div>
<h2>Version Numbers</h2>
<p>Version numbers are a very important part of your project! You should manage them as soon as possible. They are primarily important in two situation:</p>
<ul>
<li>Installation of the package if an older version exists already (upgrading)</li>
<li>Dependency management</li>
</ul>
<p class="warning admonition">
If you ever publish a package, it should always stay available! People using your package have the option to &#8220;pin&#8221; a version in their dependencies. Because of this, you will never know how long a specific version is going to be used. Again: Once published it should <em><strong>never</strong></em> disappear!
</p>
<p>In the above example, we &#8220;hard-coded&#8221; the version number as <tt>1.0</tt>. There is a better solution however! It would be nice to give your package users the ability to check the version number. To do that, we will move the version number into our top-level <tt>__init__.py</tt> file. By convention, the variable should be named <tt>__version__</tt>. In our package, this will be the only line in the file:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">__version__ = '1.0'</div></div>
<p>This will allow users to do the following:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&gt;&gt;&gt; import helloworld<br />
&gt;&gt;&gt; print helloworld.__version__<br />
'1.0'</div></div>
<p>This is a <em>very</em> convenient information to have!</p>
<p>But now there is one annoyance&#8230; We have to edit the version number in two locations. In our setup script, and the </tt>__init__.py</tt> file. But there's a simple solution for that. In your setup script, simply import your project and get the version number from there.</p>
<p class="warning admonition">
<strong>WARNING:</strong><br />
As <a href="http://www.reddit.com/r/Python/comments/tkwtt/a_comprehensive_guide_through_python_packaging/c4nljj6">bboe over on reddit pointed out</a>, when doing this, you must be aware that this could fail if the project tries to import one of it's dependencies when importing <tt>helloworld</tt>. As the dependency cannot be available yet when running the script, it will raise an <tt>ImportError</tt>. So, either you don't import the version variable, or you must not trigger an import of any dependency when importing the package.<br />&nbsp;<br />Other alternatives are possible. Such as storing your version number in a separate <tt>.py</tt> file and importing that one. Or, if all else fails, running a regex on you <tt>__init__.py</tt> file. You can see implementations of these solutions in the <a href="http://www.reddit.com/r/Python/comments/tkwtt/a_comprehensive_guide_through_python_packaging/c4nljj6">reddit link</a> mentioned before.
</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> helloworld<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: black;">version</span><span style="color: #66cc66;">=</span>helloworld.__version__<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; ...</div></div>
<p>which will give you this result:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span> <span style="color: #ff7700;font-weight:bold;">import</span> join<span style="color: #66cc66;">,</span> dirname<br />
<span style="color: #ff7700;font-weight:bold;">import</span> helloworld<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'helloworld'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span>helloworld.__version__<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>dirname<span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; entry_points<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'console_scripts'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #483d8b;">'helloworld = helloworld.core:print_message'</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span></div></div>
<p>It is recommended that the version numbers follow a well-known scheme. There are a few:</p>
<ul>
<li><a href="http://www.python.org/dev/peps/pep-0386/">from PEP 386</a></li>
<li><a href="http://docs.python.org/distutils/setupscript.html#additional-meta-data">from The official documentation</a></li>
<li><a href="http://guide.python-distribute.org/specification.html#how-to-version-your-python-projects">from The Hitchhiker's Guide</a></li>
</ul>
<p>I suggest following the "strict" numbers stated in PEP386 for <tt>distutils</tt>. An example from the PEP document (ordered by version number):</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; 0.4 &nbsp; &nbsp; &nbsp; 0.4.0 &nbsp;(these two are equivalent)<br />
&nbsp; &nbsp; 0.4.1<br />
&nbsp; &nbsp; 0.5a1<br />
&nbsp; &nbsp; 0.5b3<br />
&nbsp; &nbsp; 0.5<br />
&nbsp; &nbsp; 0.9.6<br />
&nbsp; &nbsp; 1.0<br />
&nbsp; &nbsp; 1.0.4a3<br />
&nbsp; &nbsp; 1.0.4b1<br />
&nbsp; &nbsp; 1.0.4</div></div>
<h2>Dependency Management</h2>
<p>As stated above, with setup scripts, you can specify dependencies. So let's make a small hello-world web application using Flask. A web-app will also contain "data" files (templates, ...), which will give us the opportunity to talk about the manifest later on. But for now, let's simply add <tt>Flask</tt> into our dependencies. To do that, add the following to your setup script:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: black;">install_requires</span><span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'Flask'</span><br />
&nbsp; &nbsp; <span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; ...</div></div>
<p>So the complete setup script now reads:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span> <span style="color: #ff7700;font-weight:bold;">import</span> join<span style="color: #66cc66;">,</span> dirname<br />
<span style="color: #ff7700;font-weight:bold;">import</span> helloworld<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'helloworld'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span>helloworld.__version__<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>dirname<span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; entry_points<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'console_scripts'</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#91;</span><span style="color: #483d8b;">'helloworld = helloworld.core:print_message'</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; install_requires<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'Flask'</span><br />
&nbsp; &nbsp; <span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span></div></div>
<p>Let's run the script again. But let's use <tt>pip</tt> now:<tt>./env/bin/pip install -e .</tt>. Alternatively we could have used <tt>./env/bin/python setup.py install</tt> or <tt>./env/bin/python setup.py develop</tt>, but <tt>pip</tt> gives us the option of uninstalling. Not that this would matter in our development environment. But it's good to know it exists. On the output, we will see that this will now automagically pull in everything required. Python will automatically query <a href="http://pypi.python.org/pypi">pypi</a> to find the latest version of <tt>Flask</tt> and follow it's dependencies.</p>
<p>Okay. So now we got the latest <tt>Flask</tt> version, and we will start to develop against that version. Because of this, we want to pin the version, so that we (and our users) will not be surprised if the API of Flask will change in the future. To determine the version of Flask, we can run the following:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./env/bin/pip freeze<br />
...<br />
Flask==0.8<br />
...</div></div>
<p>This will list all packages, including the version number installed in the environment from which <tt>pip</tt> was run.</p>
<p class="note admonition">
This output can also be used as a "requirements file" for <tt>pip</tt> installations. I won't cover that topic yet. It's still new to me <img src='http://foobar.lu/wp/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
</p>
<p>So now we know we got version 0.8. We can now change our setup script to pin our version:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: black;">install_requires</span><span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'Flask==0.8'</span><br />
&nbsp; &nbsp; <span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; ...</div></div>
<p>You are strongly encouraged to do this as it puts <em>you</em> in control about when and where you will upgrade to newer versions!</p>
<p>Now, as a small interlude, let's create a one-page web application, basing ourselves on the integrated server. This will also give us the opportunity to revisit the creation of executables. In a production environment, you should not do this, but rather deploy a WSGI application. But this post is not about web application. We just want some "data" files!</p>
<p>Create a folder for our templates (which incidentally contains our only data file):</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ mkdir helloworld/templates</div></div>
<p>... and put the following file into it, called <tt>index.html</tt>:</p>
<div class="codecolorer-container html4strict twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #00bbdd;">&lt;!DOCTYPE HTML&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span> <span style="color: #000066;">lang</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;en&quot;</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">charset</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;UTF-8&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
&nbsp; &nbsp; {{message}}<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></div></div>
<p>Next, create the Flask entry point inside <tt>helloworld/web.py</tt></p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> flask <span style="color: #ff7700;font-weight:bold;">import</span> Flask<span style="color: #66cc66;">,</span> render_template<br />
<span style="color: #ff7700;font-weight:bold;">from</span> helloworld.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> get_message<br />
app <span style="color: #66cc66;">=</span> Flask<span style="color: black;">&#40;</span>__name__<span style="color: black;">&#41;</span><br />
<br />
<br />
<span style="color: #66cc66;">@</span>app.<span style="color: black;">route</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;/&quot;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> hello<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> render_template<span style="color: black;">&#40;</span><span style="color: #483d8b;">'index.html'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; message<span style="color: #66cc66;">=</span>get_message<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> run_server<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; app.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>... and add the entry-point to setup.py:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span> <span style="color: #ff7700;font-weight:bold;">import</span> join<span style="color: #66cc66;">,</span> dirname<br />
<span style="color: #ff7700;font-weight:bold;">import</span> helloworld<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'helloworld'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span>helloworld.__version__<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>dirname<span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; entry_points<span style="color: #66cc66;">=</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'console_scripts'</span>: <span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'helloworld = helloworld.core:print_message'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'serve = helloworld.web:run_server'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; install_requires<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'Flask==0.8'</span><br />
&nbsp; &nbsp; <span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span></div></div>
<p>Execute the setup script again (to make the new executable available):</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./env/bin/python setup.py develop</div></div>
<p>... and test the server:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ./env/bin/serve<br />
&nbsp;* Running on http://127.0.0.1:5000/</div></div>
<p>Good! We have everything in place to talk about the manifest.</p>
<h2>The MANIFEST</h2>
<p>There is still one problem with our project. By default the package only contains python files. If you need to add additional data, for example template of image files in a web-application, you need to specify these. The above example contains a template. So let's see what this means for us. Let's create a new source distribution:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ python setup.py sdist</div></div>
<p>Now, inspect the contents of the tarball:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ tar tzvf dist/helloworld-1.0.tar.gz<br />
drwxrwxr-x exhuma/exhuma &nbsp; &nbsp; 0 2012-05-13 15:02 helloworld-1.0/<br />
-rw-rw-r-- exhuma/exhuma &nbsp; 443 2012-05-13 14:55 helloworld-1.0/setup.py<br />
drwxrwxr-x exhuma/exhuma &nbsp; &nbsp; 0 2012-05-13 15:02 helloworld-1.0/helloworld/<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;91 2012-05-13 12:46 helloworld-1.0/helloworld/core.py<br />
-rw-rw-r-- exhuma/exhuma &nbsp; 249 2012-05-13 14:57 helloworld-1.0/helloworld/web.py<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;20 2012-05-13 14:34 helloworld-1.0/helloworld/__init__.py<br />
-rw-rw-r-- exhuma/exhuma &nbsp; 264 2012-05-13 15:02 helloworld-1.0/PKG-INFO<br />
drwxrwxr-x exhuma/exhuma &nbsp; &nbsp; 0 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;10 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/requires.txt<br />
-rw-rw-r-- exhuma/exhuma &nbsp; 264 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/PKG-INFO<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;96 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/entry_points.txt<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;11 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/top_level.txt<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp; 1 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/dependency_links.txt<br />
-rw-rw-r-- exhuma/exhuma &nbsp; 285 2012-05-13 15:02 helloworld-1.0/helloworld.egg-info/SOURCES.txt<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;59 2012-05-13 15:02 helloworld-1.0/setup.cfg<br />
-rw-rw-r-- exhuma/exhuma &nbsp; &nbsp;57 2012-05-13 12:50 helloworld-1.0/README.txt</div></div>
<p>As you can see, the templates are not included! So our package <strong>will not work</strong> if we distribute like this! To do this, we need to tell python that we want other non-source files to be added. We can do this easily with a file called <tt>MANIFEST.in</tt>. In our case, it will look like this:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">recursive-include helloworld/templates *.html</div></div>
<p>Finally, we need to add the following line to the setup script:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: black;">include_package_data</span><span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; ...<br />
&nbsp; &nbsp; <span style="color: black;">&#41;</span></div></div>
<p>There are other ways to address the issue of data files. Most notably, as of Python 2.7, the setup procedure will automatically create a manifest based on <tt>package_data</tt> and <tt>data_files</tt>. The advantage of this is that your setup specs are no longer split into multiple files. As it is fairly new, and as Python 2.7 is only now gaining traction, I have not yet worked with this. I leave this as an exercise to the reader.</p>
<p>If we now re-create the sdist, we see that the files are included in the tarball. We need to do this for all non-source files which we want to include in our project! You can find more detailed information on <a href="http://docs.python.org/distutils/sourcedist.html#specifying-the-files-to-distribute">this in the official documentation</a>.</p>
<h3>Accessing packaged files</h3>
<p>When you need to access these packaged data files you cannot simply use <tt>open(filename)</tt>. You don't know the filename! It could even be stored inside a <tt>.egg</tt>. This all depends on how the end-user will install the package. You don't have control over this! For this reason, <tt>distribute</tt> provides <a href="http://packages.python.org/distribute/pkg_resources.html#basic-resource-access">a couple of methods</a> to access these files. The most likely candidates are:</p>
<ul>
<li><tt>resource_stream</tt> which returns a file-like object,</li>
<li><tt>resource_string</tt> which returns a string and</li>
<li><tt>resource_filename</tt></li>
</ul>
<p>Note that when using <tt>resource_filename</tt> the resource may be (in the case of a zipped installation) extracted to a cache folder. See the <a href="http://packages.python.org/distribute/pkg_resources.html#resource-extraction">pkg_resources (resource-extraction)</a> for details on this behaviour.</p>
<h2>Publishing</h2>
<p>If you want to make your package available to others, the obvious choice is <a href="http://pypi.python.org/pypi">pypi</a>. Python makes it easy to publish. Simply run:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ python setup.py register sdist upload</div></div>
<p>See <a href="http://guide.python-distribute.org/contributing.html#registering-projects">the hitchhiker's guide</a> for more details on this.</p>
<p>Before you publish on <tt>pypi</tt> you may want to test your upload process. For this reason, there is http://testpypi.python.org/pypi<br />
To use this (or any other package index), you need to specify the details in your <tt>~/.pypirc</tt>. Here is an example:</p>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[distutils]<br />
index-servers =<br />
&nbsp; &nbsp; pypi<br />
&nbsp; &nbsp; ppt<br />
<br />
[pypi]<br />
username:yourlogin<br />
password:yourpasswd<br />
<br />
[ppt]<br />
repository: http://testpypi.python.org/pypi<br />
username:test<br />
password:test</div></div>
<p>Having this, you can then upload packages to the given repositories by appending <tt>-r ppt</tt> for example.</p>
<div class="admonition warning">
I was testing this while I was writing this and it triggered an infinite recursion. Following the comment of Richard Jones it should work. Maybe someone can shed some light on this?
</div>
<p>But corporate policy may prevent you from publishing to the public domain. Or your project contains sensitive data which should not be made public. In this case, it is very easy to set up a local repository of packages. You only need to have a HTML document with the links available. A very easy way is to set up an Apache host which indexes a folder into which you upload your packages.</p>
<p>Even if not behind corporate restrictions, this is an easy way to publish pre-release packages which you don't want to push to pypi just yet.</p>
<p>To be able to use these repositories for your dependencies, you need to add the links into your setup.py file. Let's assume you create a new package depending on our <tt>helloworld</tt> package which we published on our local repository, and that your local repository is available as http://our.local.repo/. Then you would create a setup script like this:</p>
<div class="codecolorer-container python twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> setuptools <span style="color: #ff7700;font-weight:bold;">import</span> setup<span style="color: #66cc66;">,</span> find_packages<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span> <span style="color: #ff7700;font-weight:bold;">import</span> join<span style="color: #66cc66;">,</span> dirname<br />
<br />
setup<span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'myotherproject'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; version<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'1.0'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; packages<span style="color: #66cc66;">=</span>find_packages<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; long_description<span style="color: #66cc66;">=</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>dirname<span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'README.txt'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; install_requires<span style="color: #66cc66;">=</span><span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'helloworld==1.0'</span><br />
&nbsp; &nbsp; <span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; dependency_links <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'http://our.local.repo'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></div>
<p>Alternatively, when using <tt>pip</tt>, you can specify URLs at which to look for packages using <tt>pip -f ...</tt>.</p>
<h2>Food for thought</h2>
<p>As promised, here's another tidbit. For many python beginners, the <tt>setup.py</tt> file is some sort of black magic and must contain the call to the <tt>setup</tt> method and nothing else. But that is <strong>not</strong> true! The setup script is a completely normal python file which you execute. This has an <em>awesome</em> implication: You can do <em>whatever you want</em> before and after the call to <tt>setup</tt>. Everything you execute before the call to setup, will obviously be run before the setup process, everything after the setup call will in turn be run after the installation is finished. I will let your imagination run wild with what you can do. Keep in mind though, that you may want to keep away from user-prompts and so forth to avoid breaking automated installations! But it is your project and your choice what you will or won't do.</p>
<p>In most cases this level of fine-tuning is not needed however <tt>distribute</tt> and <tt>distutils</tt> already offer a <em>lot</em> of functionality. Investigate these first! Only do such things if there is really no other way around! Or if you want to play around <img src='http://foobar.lu/wp/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2>References</h2>
<ul>
<li><a href="http://guide.python-distribute.org/">The Hitchhiker's Guide to Python Packaging</a></li>
<li><a href="http://www.ibm.com/developerworks/opensource/library/os-pythonpackaging/">A Guide to Python Packagin (IBM)</a></li>
<li>The official Python documentation (<a href="http://docs.python.org/distutils/setupscript.html">setupscript</a>, <a href="http://docs.python.org/distutils/sourcedist.html">source-dist</a>)</li>
<li><a href="http://packages.python.org/distribute">Distribute</a></li>
<li><a href="http://www.python.org/dev/peps/pep-0386/">PEP 386 - Changing the version comparison module in Distutils</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/05/13/a-comprehensive-step-through-python-packaging-a-k-a-setup-scripts/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Git visualization with gource</title>
		<link>http://foobar.lu/wp/2012/05/07/git-visualization-with-gource/</link>
		<comments>http://foobar.lu/wp/2012/05/07/git-visualization-with-gource/#comments</comments>
		<pubDate>Mon, 07 May 2012 10:56:56 +0000</pubDate>
		<dc:creator>latz.twn</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=258</guid>
		<description><![CDATA[Are you using git/svn/mercurial/bazaar as version control system and you ever wanted to visualize your work, how the project developed over time well Gource is there to visualize all this in a beautiful way. It takes the history of your svn/git/mercurial/bazaar repository and visualizes the changes over time, by whom they were done and so [...]]]></description>
			<content:encoded><![CDATA[<p>Are you using git/svn/mercurial/bazaar as version control system and you ever wanted to visualize your work, how the project developed over time well <a href="http://code.google.com/p/gource/" title="Gource" target="_blank">Gource</a> is there to visualize all this in a beautiful way. It takes the history of your svn/git/mercurial/bazaar repository and visualizes the changes over time, by whom they were done and so forth.</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get install</span> gource</div></div>
<p>Now run the following with path/to/project being your projects root directory, and give gource the .git subfolder. Run it and you should see the animation being presented.</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">gource <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>project<span style="color: #000000; font-weight: bold;">/</span>.git<span style="color: #000000; font-weight: bold;">/</span></div></div>
<p>Now to export this to an mpeg4 video do the following.</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">gource <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>project<span style="color: #000000; font-weight: bold;">/</span>.git<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">--stop-at-end</span> <span style="color: #660033;">--output-ppm-stream</span> - <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">ffmpeg</span> <span style="color: #660033;">-y</span> <span style="color: #660033;">-b</span> 6000k <span style="color: #660033;">-r</span> <span style="color: #000000;">60</span> <span style="color: #660033;">-f</span> image2pipe <span style="color: #660033;">-vcodec</span> ppm <span style="color: #660033;">-i</span> - <span style="color: #660033;">-vcodec</span> mpeg4 <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>gource.mp4</div></div>
<p><a href="http://www.youtube.com/watch?v=ZV5DIbrOMzk">Here</a> an example I created from one of my projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/05/07/git-visualization-with-gource/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitoring memory on Solaris</title>
		<link>http://foobar.lu/wp/2012/04/24/monitoring-memory-on-solaris/</link>
		<comments>http://foobar.lu/wp/2012/04/24/monitoring-memory-on-solaris/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 16:20:20 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=253</guid>
		<description><![CDATA[I am currently writing a new munin plugin to monitor memory usage on Solaris machines. Strangely the existing plugins are fairly useless. Currently the script is running on a test-machine. If the results are satisfactory, I&#8217;ll post them here. Stay tuned.]]></description>
			<content:encoded><![CDATA[<p>I am currently writing a new munin plugin to monitor memory usage on Solaris machines. Strangely the existing plugins are fairly useless. Currently the script is running on a test-machine. If the results are satisfactory, I&#8217;ll post them here. Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/04/24/monitoring-memory-on-solaris/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>disqus</title>
		<link>http://foobar.lu/wp/2012/04/20/disqus/</link>
		<comments>http://foobar.lu/wp/2012/04/20/disqus/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 09:06:16 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=251</guid>
		<description><![CDATA[Yesterday evening I enabled disqus.com comments on foobar.lu. This should make commenting easier and more accessible in the future. Existing comments have been put into the the disqus importer queue, and according to them, they should appear after 24 hours. So nothing is lost!]]></description>
			<content:encoded><![CDATA[<p>Yesterday evening I enabled <a href="http://www.disqus.com">disqus.com</a> comments on foobar.lu. This should make commenting easier and more accessible in the future.</p>
<p>Existing comments have been put into the the disqus importer queue, and according to them, they should appear after 24 hours. So nothing is lost!</p>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/04/20/disqus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Custom bash completion for fabric tasks</title>
		<link>http://foobar.lu/wp/2012/03/20/custom-bash-completion-for-fabric-tasks/</link>
		<comments>http://foobar.lu/wp/2012/03/20/custom-bash-completion-for-fabric-tasks/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 15:08:07 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Coding Voodoo]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=244</guid>
		<description><![CDATA[Here&#8217;s a small bash function to provide TAB-completion for fabric tasks. Simply add the following to your ~/.bashrc You may already have a block like if [ -f /etc/bash_completion ]... in that case, simply add the extra line into that block. Have fun]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a small bash function to provide TAB-completion for fabric tasks.</p>
<p>Simply add the following to your <tt>~/.bashrc</tt></p>
<p>You may already have a block like <tt>if [ -f /etc/bash_completion ]...</tt> in that case, simply add the extra line into that block.</p>
<div id="gist-2136677" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c">#                                                                                                                                                                                                    </span></div><div class='line' id='LC2'><span class="c"># Bash completion for fabric                                                                                                                                                                         </span></div><div class='line' id='LC3'><span class="c">#                                                                                                                                                                                                    </span></div><div class='line' id='LC4'><span class="k">function </span>_fab_complete<span class="o">()</span> <span class="o">{</span>                                                                                                                                                                           </div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">local </span>cur                                                                                                                                                                                        </div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="o">[</span> -f <span class="s2">&quot;fabfile.py&quot;</span> <span class="o">]</span>; <span class="k">then                                                                                                                                                                     </span></div><div class='line' id='LC7'><span class="k">        </span><span class="nv">cur</span><span class="o">=</span><span class="s2">&quot;${COMP_WORDS[COMP_CWORD]}&quot;</span>                                                                                                                                                              </div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nv">COMPREPLY</span><span class="o">=(</span> <span class="k">$(</span><span class="nb">compgen</span> -W <span class="s2">&quot;$(fab -F short -l)&quot;</span> -- <span class="k">${</span><span class="nv">cur</span><span class="k">})</span> <span class="o">)</span>                                                                                                                                   </div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return </span>0                                                                                                                                                                                     </div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">else</span>                                                                                                                                                                                             </div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c"># no fabfile.py found. Don&#39;t do anything.</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return </span>1                                                                                                                                                                                     </div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">fi</span>                                                                                                                                                                                               </div><div class='line' id='LC14'><span class="o">}</span>                                                                                                                                                                                                    </div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC16'><span class="c"># enable programmable completion features (you don&#39;t need to enable                                                                                                                                  </span></div><div class='line' id='LC17'><span class="c"># this, if it&#39;s already enabled in /etc/bash.bashrc and /etc/profile                                                                                                                                 </span></div><div class='line' id='LC18'><span class="c"># sources /etc/bash.bashrc).                                                                                                                                                                         </span></div><div class='line' id='LC19'><span class="k">if</span> <span class="o">[</span> -f /etc/bash_completion <span class="o">]</span> <span class="o">&amp;&amp;</span> ! <span class="nb">shopt</span> -oq posix; <span class="k">then</span>                                                                                                                                            </div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;. /etc/bash_completion                                                                                                                                                                           </div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">complete</span> -o nospace -F _fab_complete fab                                                                                                                                                         </div><div class='line' id='LC22'><span class="k">fi</span>                                                                                                                                                                                                   </div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2136677/c72e808d75e285c9c8943fa0f3523866503cd354/gistfile1.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2136677#file_gistfile1.sh" style="float:right;margin-right:10px;color:#666">gistfile1.sh</a>
            <a href="https://gist.github.com/2136677">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Have fun</p>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/03/20/custom-bash-completion-for-fabric-tasks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>First steps with the closure library</title>
		<link>http://foobar.lu/wp/2012/03/01/first-steps-with-the-closure-library/</link>
		<comments>http://foobar.lu/wp/2012/03/01/first-steps-with-the-closure-library/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 11:42:39 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=232</guid>
		<description><![CDATA[I recently switched work, and now after a lot of JavaEE development for the past 5 years, I am finally back home: Web-development. During my Java time, I did some small web bits here and there. Mainly to keep up with evolution, and followed the massive move towards more JavaScript heavy development. During my free [...]]]></description>
			<content:encoded><![CDATA[<p>I recently switched work, and now after a lot of JavaEE development for the past 5 years, I am finally back home: Web-development. During my Java time, I did some small web bits here and there. Mainly to keep up with evolution, and followed the massive move towards more JavaScript heavy development. During my free time I took baby steps with a couple of JavaScript libraries, starting with Prototype, then <a href="http://script.aculo.us/">script.aculo.us</a>, <a href="http://mochi.github.com/mochikit/">MochiKit</a> and <a href="http://mootools.net/">MooTools</a> to get some visual effects done. Without doubt, I preferred MochiKit because of it&#8217;s similarity to Python. I also dipped into <a href="http://dojotoolkit.org/">Dojo</a> because of it&#8217;s nice HTML Form widgets, fooled around with <a href="http://documentcloud.github.com/backbone/">backbone.js</a>. But eventually I ended up with <a href="http://jquery.com/">jQuery</a>, simply because it currently has the backing of The Community. All I&#8217;ve done in all of these libraries can only be summarized as &#8220;wetting my feet&#8221;. At some point I consumed all the Crockford material I could find, and boy was that eye-opening. I realized I was not aware of the most important aspects of JavaScript (especially: <em>&#8220;Everything is global! Use Namespaces!&#8221;</em>)!</p>
<p>The next thing that caught my eye, was <a href="http://coffeescript.org/">CoffeeScript</a>. It allowed me to write pythonesque code, and compile right down to <strong><em>proper</em></strong> JavaScript.</p>
<p>So what has this to do with <a href="https://developers.google.com/closure/library/">the closure library</a>? Well, recently (as stated above) I started web-development again. And some parts of the project made it obvious, that a good dash of JavaScript would help the project a lot. So I needed to take a decision on what library I would base my work on. My first reflex was jQuery. But out of sheer coincidence I stumbled across a blog post from someone discussing jQuery and closure. Unfortunately, I don&#8217;t have the link anymore <img src='http://foobar.lu/wp/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  The TL;DR of that blog post was however (paraphrasing):</p>
<blockquote><p>If I had known about closure before, I would have used it instead of jQuery, because it makes it easier to structure the source code.</p></blockquote>
<p>This made me more that curious. So the next thing I did, was read the closure tutorials, and also read the API top to bottom. I wanted to know what was in there before deeming it useful. And boy did it look interesting! The most interesting feature, as the author of said blog post pointed out, it the ability to easily structure your code. Using <tt>goog.provides</tt> and <tt>goog.require</tt> you can very easily split your JS files into multiple, well structured files, and the closure compiler will then re-combine them into one file, all properly ordered. To me, this feels a lot like writing Java or Python, which both allow you to structure your code very well. This also allows you to easily write modules which can in turn be re-used with ease in other projects (or, you could publish them).</p>
<p>For now, I am not missing anything from jQuery except the easy DOM querying from it. But I can happily live without it.</p>
<p>With my current experience, I can see the following benefits:</p>
<ul>
<li>Makes it easy to structure code</li>
<li>The optional linter forces you to write proper/clean code. Especially with the <tt>--strict</tt> flag. Using it right from the start forces you to write in a uniform coding style, which makes code <em?much</em> more readable!</li>
<li>The compiler solves dependency chains with the help of <tt>goog.provide</tt> and <tt>goog.require</tt>, and can optionally minify your code.</li>
<li>The library feels very professional. It&#8217;s even got a <tt>Logger</tt> loosely inspired by <tt>java.util.logger</tt>, and let&#8217;s you do exactly what you expect it to! This is <b>awesome</b> for debugging!</li>
<li>The library source code is very readable</li>
</ul>
<p>And some disadvantages:</p>
<ul>
<li>The community is <em>much</em> smaller than the one around jQuery. But so far I could figure out all I needed by reading the code.</li>
<li>It does not seem to have versioned downloads. You have to checkout from SVN trunk. I would prefer to be able to say: &#8220;I am basing my work on version 1.0&#8243; instead of &#8220;trunk&#8221;</li>
<li>Instead of linking one CSS file (as in jQuery), you have to link multiple styles and figure out which ones by yourself. But given the filenames are self-explanatory, that&#8217;s not too difficult.</li>
<li>There are no predefined CSS themes. Something jQuery&#8217;s theme builder would be nice. But, I assume that the closure-style-sheet project should help writing CSS files easily. I did not yet look into that one!</li>
</ul>
<p>As I progress with the library I&#8217;ll post my findings&#8230;</p>
<p>Here are two related links I found while looking for the mentioned blog post:</p>
<ul>
<li><a href="http://stackoverflow.com/questions/1690197/what-does-google-closure-library-offer-over-jquery">http://stackoverflow.com/questions/1690197/what-does-google-closure-library-offer-over-jquery</a></li>
<li><a href="http://sayspy.blogspot.com/2010/10/lessons-learned-porting-from-jquery-to.html">http://sayspy.blogspot.com/2010/10/lessons-learned-porting-from-jquery-to.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2012/03/01/first-steps-with-the-closure-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JScript to query scheduled tasks</title>
		<link>http://foobar.lu/wp/2011/06/09/jscript-to-query-scheduled-tasks/</link>
		<comments>http://foobar.lu/wp/2011/06/09/jscript-to-query-scheduled-tasks/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 15:19:47 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Coding Voodoo]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=211</guid>
		<description><![CDATA[Soon, we will need to send out notifications as soon something bad happens with a scheduled task on Windows. The following JScript file runs natively on Windows and is capable of just that. It uses the command line tool &#8220;schtasks&#8221; to query the information and wraps the result into a list of usable object instances. [...]]]></description>
			<content:encoded><![CDATA[<p>Soon, we will need to send out notifications as soon something bad happens with a scheduled task on Windows. The following JScript file runs natively on Windows and is capable of just that. It uses the command line tool &#8220;schtasks&#8221; to query the information and wraps the result into a list of usable object instances.</p>
<p>It&#8217;s possible to use this list to react to important events in the job executions. For example, you could loop through the list and send emails to the appropriate people if the variable &#8220;lastResult&#8221; is non-zero.</p>
<div id="gist-1016899" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="cm">/**</span></div><div class='line' id='LC2'><span class="cm"> * Naive CSV splitter</span></div><div class='line' id='LC3'><span class="cm"> *</span></div><div class='line' id='LC4'><span class="cm"> * This splitter is *very* simplistic and may result in errors when parsing</span></div><div class='line' id='LC5'><span class="cm"> * unknown CSV sources. This works well in the current problem domain.</span></div><div class='line' id='LC6'><span class="cm"> *</span></div><div class='line' id='LC7'><span class="cm"> * As we have well defined data, with no escaped quotes inside the fields, we</span></div><div class='line' id='LC8'><span class="cm"> * can sefaly assume that this will work.</span></div><div class='line' id='LC9'><span class="cm"> */</span></div><div class='line' id='LC10'><span class="kd">function</span> <span class="nx">simpleCsvSplit</span><span class="p">(</span><span class="nx">lineText</span><span class="p">){</span></div><div class='line' id='LC11'>	<span class="kd">var</span> <span class="nx">columns</span> <span class="o">=</span> <span class="p">[];</span></div><div class='line' id='LC12'>	<span class="kd">var</span> <span class="nx">inside_quote</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span></div><div class='line' id='LC13'>	<span class="kd">var</span> <span class="nx">current_data</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span></div><div class='line' id='LC14'>	<span class="kd">var</span> <span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span></div><div class='line' id='LC15'>	<span class="k">for</span><span class="p">(</span><span class="nx">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">&lt;</span><span class="nx">lineText</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span></div><div class='line' id='LC16'>		<span class="kd">var</span> <span class="nx">chr</span> <span class="o">=</span> <span class="nx">lineText</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">i</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span></div><div class='line' id='LC17'>		<span class="k">if</span> <span class="p">(</span><span class="nx">chr</span> <span class="o">===</span> <span class="s2">&quot;\&quot;&quot;</span><span class="p">){</span></div><div class='line' id='LC18'>			<span class="nx">inside_quote</span> <span class="o">=</span> <span class="o">!</span><span class="nx">inside_quote</span><span class="p">;</span></div><div class='line' id='LC19'>			<span class="k">continue</span><span class="p">;</span></div><div class='line' id='LC20'>		<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">chr</span> <span class="o">===</span> <span class="s2">&quot;,&quot;</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">inside_quote</span><span class="p">){</span></div><div class='line' id='LC21'>			<span class="nx">columns</span><span class="p">[</span><span class="nx">columns</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span> <span class="o">=</span> <span class="nx">current_data</span><span class="p">;</span></div><div class='line' id='LC22'>			<span class="nx">current_data</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span></div><div class='line' id='LC23'>		<span class="p">}</span></div><div class='line' id='LC24'>		<span class="k">if</span> <span class="p">(</span><span class="nx">inside_quote</span><span class="p">){</span></div><div class='line' id='LC25'>			<span class="nx">current_data</span> <span class="o">+=</span> <span class="nx">chr</span><span class="p">;</span></div><div class='line' id='LC26'>		<span class="p">}</span></div><div class='line' id='LC27'>	<span class="p">}</span></div><div class='line' id='LC28'>	<span class="nx">columns</span><span class="p">[</span><span class="nx">columns</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span> <span class="o">=</span> <span class="nx">current_data</span><span class="p">;</span></div><div class='line' id='LC29'>	<span class="k">return</span> <span class="nx">columns</span><span class="p">;</span></div><div class='line' id='LC30'><span class="p">}</span></div><div class='line' id='LC31'><br/></div><div class='line' id='LC32'><span class="cm">/**</span></div><div class='line' id='LC33'><span class="cm"> * A container object for the task metadata</span></div><div class='line' id='LC34'><span class="cm"> * This makes further processing with the data a lot more expressive.</span></div><div class='line' id='LC35'><span class="cm"> *</span></div><div class='line' id='LC36'><span class="cm"> * @param lineText A string taken from the CSV output representing one line</span></div><div class='line' id='LC37'><span class="cm"> */</span></div><div class='line' id='LC38'><span class="kd">var</span> <span class="nx">Task</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">lineText</span><span class="p">){</span></div><div class='line' id='LC39'>	<span class="c1">// parse the CSV data</span></div><div class='line' id='LC40'>	<span class="nx">columns</span> <span class="o">=</span> <span class="nx">simpleCsvSplit</span><span class="p">(</span><span class="nx">lineText</span><span class="p">);</span></div><div class='line' id='LC41'><br/></div><div class='line' id='LC42'>	<span class="c1">// put everything into explicitly named variables</span></div><div class='line' id='LC43'>	<span class="k">this</span><span class="p">.</span><span class="nx">hostName</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span></div><div class='line' id='LC44'>	<span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span></div><div class='line' id='LC45'>	<span class="k">this</span><span class="p">.</span><span class="nx">nextRun</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span></div><div class='line' id='LC46'>	<span class="k">this</span><span class="p">.</span><span class="nx">status</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span></div><div class='line' id='LC47'>	<span class="k">this</span><span class="p">.</span><span class="nx">lastRun</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span></div><div class='line' id='LC48'>	<span class="k">this</span><span class="p">.</span><span class="nx">lastResult</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span></div><div class='line' id='LC49'>	<span class="k">this</span><span class="p">.</span><span class="nx">creator</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">6</span><span class="p">];</span></div><div class='line' id='LC50'>	<span class="k">this</span><span class="p">.</span><span class="nx">schedule</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">7</span><span class="p">];</span></div><div class='line' id='LC51'>	<span class="k">this</span><span class="p">.</span><span class="nx">command</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">8</span><span class="p">];</span></div><div class='line' id='LC52'>	<span class="k">this</span><span class="p">.</span><span class="nx">startIn</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">9</span><span class="p">];</span></div><div class='line' id='LC53'>	<span class="k">this</span><span class="p">.</span><span class="nx">comment</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">10</span><span class="p">];</span></div><div class='line' id='LC54'>	<span class="k">this</span><span class="p">.</span><span class="nx">scheduledState</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">11</span><span class="p">];</span></div><div class='line' id='LC55'>	<span class="k">this</span><span class="p">.</span><span class="nx">scheduledType</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">12</span><span class="p">];</span></div><div class='line' id='LC56'>	<span class="k">this</span><span class="p">.</span><span class="nx">startTime</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">13</span><span class="p">];</span></div><div class='line' id='LC57'>	<span class="k">this</span><span class="p">.</span><span class="nx">startDate</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">14</span><span class="p">];</span></div><div class='line' id='LC58'>	<span class="k">this</span><span class="p">.</span><span class="nx">endDate</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">15</span><span class="p">];</span></div><div class='line' id='LC59'>	<span class="k">this</span><span class="p">.</span><span class="nx">days</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span></div><div class='line' id='LC60'>	<span class="k">this</span><span class="p">.</span><span class="nx">months</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">17</span><span class="p">];</span></div><div class='line' id='LC61'>	<span class="k">this</span><span class="p">.</span><span class="nx">runAs</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">18</span><span class="p">];</span></div><div class='line' id='LC62'>	<span class="k">this</span><span class="p">.</span><span class="nx">deleteIfNotRescheduled</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">19</span><span class="p">];</span></div><div class='line' id='LC63'>	<span class="k">this</span><span class="p">.</span><span class="nx">stopIf</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">20</span><span class="p">];</span></div><div class='line' id='LC64'>	<span class="k">this</span><span class="p">.</span><span class="nx">repeatEvery</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">21</span><span class="p">];</span></div><div class='line' id='LC65'>	<span class="k">this</span><span class="p">.</span><span class="nx">repeatUntilTime</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">22</span><span class="p">];</span></div><div class='line' id='LC66'>	<span class="k">this</span><span class="p">.</span><span class="nx">repeatUntilDuration</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">23</span><span class="p">];</span></div><div class='line' id='LC67'>	<span class="k">this</span><span class="p">.</span><span class="nx">repeatStopIfRunning</span> <span class="o">=</span><span class="nx">columns</span><span class="p">[</span><span class="mi">24</span><span class="p">];</span></div><div class='line' id='LC68'>	<span class="k">this</span><span class="p">.</span><span class="nx">idleTime</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">25</span><span class="p">];</span></div><div class='line' id='LC69'>	<span class="k">this</span><span class="p">.</span><span class="nx">powerManagement</span> <span class="o">=</span> <span class="nx">columns</span><span class="p">[</span><span class="mi">26</span><span class="p">];</span></div><div class='line' id='LC70'><span class="p">};</span></div><div class='line' id='LC71'><br/></div><div class='line' id='LC72'><span class="c1">// execute the shell command to retrieve the scheduled tasks</span></div><div class='line' id='LC73'><span class="kd">var</span> <span class="nx">WshShell</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ActiveXObject</span><span class="p">(</span><span class="s2">&quot;WScript.Shell&quot;</span><span class="p">);</span></div><div class='line' id='LC74'><span class="kd">var</span> <span class="nx">oExec</span> <span class="o">=</span> <span class="nx">WshShell</span><span class="p">.</span><span class="nx">Exec</span><span class="p">(</span><span class="s2">&quot;schtasks /Query /FO CSV /V&quot;</span><span class="p">);</span></div><div class='line' id='LC75'><br/></div><div class='line' id='LC76'><span class="c1">// retrieve the lines from stdout and save them as tasks</span></div><div class='line' id='LC77'><span class="kd">var</span> <span class="nx">tasks</span> <span class="o">=</span> <span class="p">[];</span></div><div class='line' id='LC78'><span class="k">while</span><span class="p">(</span> <span class="o">!</span><span class="nx">oExec</span><span class="p">.</span><span class="nx">StdOut</span><span class="p">.</span><span class="nx">AtEndOfStream</span><span class="p">){</span></div><div class='line' id='LC79'>&nbsp;&nbsp;&nbsp;<span class="nx">tasks</span><span class="p">[</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span> <span class="o">=</span> <span class="nx">oExec</span><span class="p">.</span><span class="nx">StdOut</span><span class="p">.</span><span class="nx">ReadLine</span><span class="p">();</span></div><div class='line' id='LC80'><span class="p">}</span></div><div class='line' id='LC81'><br/></div><div class='line' id='LC82'><span class="c1">// now do something with the tasks</span></div><div class='line' id='LC83'><span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span><span class="o">=</span><span class="mi">2</span><span class="p">;</span> <span class="nx">i</span><span class="o">&lt;</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">){</span></div><div class='line' id='LC84'>	<span class="kd">var</span> <span class="nx">tmp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Task</span><span class="p">(</span><span class="nx">tasks</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span></div><div class='line' id='LC85'>	<span class="nx">WScript</span><span class="p">.</span><span class="nx">Echo</span><span class="p">(</span><span class="nx">tmp</span><span class="p">.</span><span class="nx">lastResult</span> <span class="o">+</span> <span class="s2">&quot; - &quot;</span> <span class="o">+</span> <span class="nx">tmp</span><span class="p">.</span><span class="nx">status</span><span class="p">);</span></div><div class='line' id='LC86'><span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1016899/6ca6bcea3da4909c690654e4355d6231db6bc1aa/inspectJobs.js" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1016899#file_inspect_jobs.js" style="float:right;margin-right:10px;color:#666">inspectJobs.js</a>
            <a href="https://gist.github.com/1016899">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2011/06/09/jscript-to-query-scheduled-tasks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows script to remove old files</title>
		<link>http://foobar.lu/wp/2011/06/08/windows-script-to-remove-old-files/</link>
		<comments>http://foobar.lu/wp/2011/06/08/windows-script-to-remove-old-files/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 09:42:16 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Coding Voodoo]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=206</guid>
		<description><![CDATA[Simple script&#8230; still, I thought I&#8217;d share&#8230;]]></description>
			<content:encoded><![CDATA[<p>Simple script&#8230; still, I thought I&#8217;d share&#8230;</p>
<div id="gist-1014084" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="cm">/**</span></div><div class='line' id='LC2'><span class="cm"> * Remove all files and folders that are older than a set number of days.</span></div><div class='line' id='LC3'><span class="cm"> *</span></div><div class='line' id='LC4'><span class="cm"> * @param rootURI The URI of the root folder. All old files and folders in this</span></div><div class='line' id='LC5'><span class="cm"> *                folder are removed.</span></div><div class='line' id='LC6'><span class="cm"> * @param days Files older than this number of days are deleted</span></div><div class='line' id='LC7'><span class="cm"> */</span></div><div class='line' id='LC8'><span class="kd">function</span> <span class="nx">purgeFiles</span><span class="p">(</span><span class="nx">rootURI</span><span class="p">,</span> <span class="nx">days</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'>&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">fso</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ActiveXObject</span><span class="p">(</span><span class="s2">&quot;Scripting.FileSystemObject&quot;</span><span class="p">);</span></div><div class='line' id='LC11'>&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">rootFolder</span> <span class="o">=</span> <span class="nx">fso</span><span class="p">.</span><span class="nx">GetFolder</span><span class="p">(</span><span class="nx">rootURI</span><span class="p">);</span></div><div class='line' id='LC12'>&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">subFolders</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Enumerator</span><span class="p">(</span><span class="nx">rootFolder</span><span class="p">.</span><span class="nx">SubFolders</span><span class="p">);</span></div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'>&nbsp;&nbsp;<span class="c1">// create a date before which files are considered &quot;old&quot;</span></div><div class='line' id='LC15'>&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">threshold_date</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span></div><div class='line' id='LC16'>&nbsp;&nbsp;<span class="nx">threshold_date</span><span class="p">.</span><span class="nx">setDate</span><span class="p">(</span><span class="nx">threshold_date</span><span class="p">.</span><span class="nx">getDate</span><span class="p">()</span><span class="o">-</span><span class="nx">days</span><span class="p">);</span></div><div class='line' id='LC17'><br/></div><div class='line' id='LC18'>&nbsp;&nbsp;<span class="c1">// loop over each file</span></div><div class='line' id='LC19'>&nbsp;&nbsp;<span class="nx">subFolders</span><span class="p">.</span><span class="nx">moveFirst</span><span class="p">();</span></div><div class='line' id='LC20'>&nbsp;&nbsp;<span class="k">for</span><span class="p">(;</span><span class="o">!</span><span class="nx">subFolders</span><span class="p">.</span><span class="nx">atEnd</span><span class="p">();</span> <span class="nx">subFolders</span><span class="p">.</span><span class="nx">moveNext</span><span class="p">()){</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">f</span> <span class="o">=</span> <span class="nx">subFolders</span><span class="p">.</span><span class="nx">item</span><span class="p">();</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span><span class="p">(</span><span class="nx">f</span><span class="p">.</span><span class="nx">DateCreated</span> <span class="o">&lt;</span> <span class="nx">threshold_date</span> <span class="p">){</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//WScript.Echo(&quot;Deleting &quot;+f.Name+&quot;  last accessed on: &quot;+f.DateCreated);</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">f</span><span class="p">.</span><span class="nx">Delete</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC26'>&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC27'><br/></div><div class='line' id='LC28'><span class="p">}</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'><span class="nx">purgeFiles</span><span class="p">(</span><span class="s2">&quot;C:/path/to/folder&quot;</span><span class="p">,</span> <span class="mi">300</span><span class="p">);</span></div><div class='line' id='LC31'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1014084/6f3aa6a391862d52f8d3a374e38a0f473190b66a/purgeFiles.js" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1014084#file_purge_files.js" style="float:right;margin-right:10px;color:#666">purgeFiles.js</a>
            <a href="https://gist.github.com/1014084">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2011/06/08/windows-script-to-remove-old-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change JPA EntityManager connection properties at Runtime</title>
		<link>http://foobar.lu/wp/2010/12/30/change-jpa-entitymanager-connection-properties-at-runtime/</link>
		<comments>http://foobar.lu/wp/2010/12/30/change-jpa-entitymanager-connection-properties-at-runtime/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 10:18:25 +0000</pubDate>
		<dc:creator>exhuma.twn</dc:creator>
				<category><![CDATA[Coding Voodoo]]></category>

		<guid isPermaLink="false">http://foobar.lu/wp/?p=119</guid>
		<description><![CDATA[There are many times you want to be able to use different connection options for a JPA EntityManager. The most obvious is different user-credentials (think of a user login-screen and re-using these credentials to connect to the DB), or to make the distinction between development/testing/production environment. However, if you let Netbeans create the persistence configuration, [...]]]></description>
			<content:encoded><![CDATA[<p>There are many times you want to be able to use different connection options for a JPA EntityManager. The most obvious is different user-credentials (think of a user login-screen and re-using these credentials to connect to the DB), or to make the distinction between development/testing/production environment.</p>
<p>However, if you let Netbeans create the persistence configuration, it will hardcode all connection parameters into the persistence.xml file. When retrieving an EntityManager instance, it will use this information to connect.</p>
<p>If, instead you would like to do this at runtime, you can do the following:</p>
<ol>
<li>Remove the &#8220;properties&#8221; tag from the persistence.xml. This may not be necessary, but this will make it clear, that the properties are set inside the code.</li>
<li>Create a &#8220;Map&lt;String, String&gt;&#8221; which will contain the properties. A list of standard properties can be found <a href="http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-eval-oth-JSpec/">in the specs in section 8.2.1.9</a>.</li>
<li>Use this map to create an EntityManagerFactory and use this to create your EntityManager</li>
</ol>
<p>An example persistence.xml without properties</p>
<div class="codecolorer-container xml twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;persistence</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;2.0&quot;</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://java.sun.com/xml/ns/persistence&quot;</span> <span style="color: #000066;">xmlns:xsi</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> xsi:schemaLo</span><br />
<span style="color: #009900;"> &nbsp;<span style="color: #000000; font-weight: bold;">&lt;persistence-unit</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;myTestPU&quot;</span> <span style="color: #000066;">transaction-type</span>=<span style="color: #ff0000;">&quot;RESOURCE_LOCAL&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;provider<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.eclipse.persistence.jpa.PersistenceProvider<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/provider<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>my.package.Entity1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>my.package.Entity2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/persistence-unit<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/persistence<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>In case Netbeans created a method &#8220;getEntityManager&#8221;, you can safely replace this. Here is an example I currently have in use. The &#8220;appConf&#8221; instance is a singleton I use to store configuration data in the user&#8217;s home folder, and yes, the password is stored in plain-text, but for this test-case I did not need to go any further:</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">private</span> EntityManager getEntityManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; Map<span style="color: #339933;">&lt;</span><span style="color: #003399;">String</span>, String<span style="color: #339933;">&gt;</span> dbProps <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashMap<span style="color: #339933;">&lt;</span><span style="color: #003399;">String</span>, String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;eclipselink.logging.level&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;eclipselink.logging.level&quot;</span>, <span style="color: #0000ff;">&quot;INFO&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// On linux, the GSSAPI is not available. Use a default user/password &nbsp; </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// pair to connect &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Linux&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">System</span>.<span style="color: #006633;">getProperty</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;os.name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;javax.persistence.jdbc.url&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">String</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc:jtds:sqlserver://%s/%s&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;db.host&quot;</span>, <span style="color: #0000ff;">&quot;my-default-host&quot;</span><span style="color: #009900;">&#41;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;db.database&quot;</span>, <span style="color: #0000ff;">&quot;my-default-db&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;javax.persistence.jdbc.driver&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;net.sourceforge.jtds.jdbc.Driver&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;javax.persistence.jdbc.password&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;db.password&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;javax.persistence.jdbc.user&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;db.user&quot;</span>, <span style="color: #0000ff;">&quot;my-default-username&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;javax.persistence.jdbc.url&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003399;">String</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc:sqlserver://%s;databaseName=%s;integratedSecurity=true&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;db.host&quot;</span>, <span style="color: #0000ff;">&quot;my-default-host&quot;</span><span style="color: #009900;">&#41;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;db.database&quot;</span>, <span style="color: #0000ff;">&quot;my-default-db&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbProps.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;javax.persistence.jdbc.driver&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;com.microsoft.sqlserver.jdbc.SQLServerDriver&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; appConf.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; EntityManagerFactory fact <span style="color: #339933;">=</span> Persistence.<span style="color: #006633;">createEntityManagerFactory</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;myTestPU&quot;</span>, dbProps<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> fact.<span style="color: #006633;">createEntityManager</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span></div></div>
<p>This example uses eclipselink. All available properties can be found it the <a href="http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)">EclipseLink Wiki</a></p>
]]></content:encoded>
			<wfw:commentRss>http://foobar.lu/wp/2010/12/30/change-jpa-entitymanager-connection-properties-at-runtime/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

