<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19347241</id><updated>2011-04-21T19:28:04.624-07:00</updated><category term='plone plone3 workingenv ploneout'/><category term='layers plone plonetestcase five'/><category term='plone wicked plone3'/><title type='text'>B.F.H.</title><subtitle type='html'>[B]ig [F]ine [H]ammer. 

If it looks like a nail, you must be using python.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19347241.post-1736112507605923158</id><published>2007-07-09T10:19:00.000-07:00</published><updated>2007-07-09T10:34:44.926-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plone plone3 workingenv ploneout'/><title type='text'>ploneout: workingenv and buildout working harmoniously</title><content type='html'>Having been busy with the &lt;a href="https://svn.openplans.org/svn/opencore/trunk/"&gt;opencore&lt;/a&gt; redesign for a while now, it's been awhile since I worked on plone3 or looked at the build situation with plone.   When I sat down to make some simple changes to wicked, I wasn't surprised that everything in my old plone3 dev environment broke with an svn up.&lt;br /&gt;&lt;br /&gt;I *&lt;span style="font-weight: bold;"&gt;was&lt;/span&gt;* pleasantly surprised to discover that I could install buildout and ploneout into a workingenv and get a running zope/plone3 instance without any problems.&lt;br /&gt;&lt;br /&gt;Kudos to those responsible whoever you may be!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-1736112507605923158?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/1736112507605923158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=1736112507605923158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/1736112507605923158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/1736112507605923158'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2007/07/ploneout-workingenv-and-buildout.html' title='ploneout: workingenv and buildout working harmoniously'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-424926404778654889</id><published>2007-01-25T21:45:00.000-08:00</published><updated>2007-01-25T22:36:43.236-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plone wicked plone3'/><title type='text'>wicked into plone</title><content type='html'>&lt;span style="font-size:100%;"&gt;Finally! A little late but it's in and waiting for framework team and wiggy's approval.  Was pretty happy at how little I actually had to touch plone or any of it's dependencies to get this done.&lt;br /&gt;&lt;br /&gt;&lt;a style="font-family: georgia;" class="moz-txt-link-freetext" href="http://dev.plone.org/plone/changeset/12050/"&gt;http://dev.plone.org/plone/changeset/12050/&lt;/a&gt;&lt;span style="font-family:georgia;"&gt;  &lt;/span&gt;- &lt;a style="font-family: georgia;" class="moz-txt-link-freetext" href="http://dev.plone.org/plone/changeset/12057/"&gt; http://dev.plone.org/plone/changeset/12057/&lt;/a&gt;&lt;span style="font-family:georgia;"&gt;&lt;br /&gt;&lt;br /&gt;check it out, let me know if you find anything.&lt;br /&gt;&lt;br /&gt;see: h&lt;a href="ttp://svn.plone.org/svn/plone/bundles/3.0/"&gt;ttp://svn.plone.org/svn/plone/bundles/3.0/ &lt;/a&gt;for instructions on setting up plone3(an automated build is coming via hanno)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:georgia;"&gt;wicked itself is available from the cheeseshop ( &lt;a href="http://cheeseshop.python.org/pypi/wicked/1.1"&gt;http://cheeseshop.python.org/pypi/wicked/1.1  &lt;/a&gt;) or svn ( &lt;a href="http://svn.plone.org/svn/collective/wicked/trunk"&gt;http://svn.plone.org/svn/collective/wicked/trunk&lt;/a&gt; )&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;br /&gt;There are some cool things under the hood in this release: directives for specifying exactly what field should be wicked on any existing content type, examples of multi-content type application of the filter, media wiki style bracket linking(optional), and fieldevent, a simple system for extending the render and storage of any field object's value.  Fieldevents could be particularily useful to anyone interested in any sort of wicked like behavior such as xslt pipelining, inline rendering of referenced content, pagination, etc. They could be used to add css id's and classes to existing markup that KSS could then bring alive.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-weight: bold;"&gt;Looking forward&lt;/span&gt;: the last little bit is to fix up the old Product style wicked package to handle old instances.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Though 1.1 was developed against  zope 2.10  (the plone integration depends on the persistent component registries), I  suspect it will work just fine with zope 2.9.   Products.wicked will essentially become a registry for calling in the necessary zcml from wicked.at and wicked.atcontent.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.openplans.org/"&gt;OpenPlans&lt;/a&gt; is planning some simple syntax extensions soon and soon we will need to integrate wicked into some non-zope apps (particularily excited about this).   In 1.1, I stubbed out a centralized cache / link map that would effectively let wicked get away from at references and the first step to moving it toward being more of a service rather than a zope or plone bound extension.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-424926404778654889?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/424926404778654889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=424926404778654889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/424926404778654889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/424926404778654889'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2007/01/wicked-into-plone.html' title='wicked into plone'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-115997256322749843</id><published>2006-10-04T07:25:00.000-07:00</published><updated>2006-10-04T07:36:03.236-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='layers plone plonetestcase five'/><title type='text'>PSA for PTC users</title><content type='html'>Important news for everyone using PloneTestCase trunk and Five::&lt;br /&gt;&lt;br /&gt;&lt;a href="http://permalink.gmane.org/gmane.comp.web.zope.plone.devel/12974"&gt;Debugging PTC Trunk&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Some minor things have changed on PloneTestCase trunk that will create breakage for some common but questionable test setups. This outlines the breakage and how to fix it.&lt;br /&gt;&lt;br /&gt;Suffice it to say this: death to installProduct('Five').&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-115997256322749843?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/115997256322749843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=115997256322749843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115997256322749843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115997256322749843'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/10/psa-for-ptc-users.html' title='PSA for PTC users'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-115767422845928227</id><published>2006-09-07T16:50:00.000-07:00</published><updated>2006-09-08T11:49:02.003-07:00</updated><title type='text'>#!bootstrap/environment</title><content type='html'>summary: Eggs are changing how things are done around these parts.  This entry will cover how to use Ian Bicking's workenv with Zope2 and take a sideway glance at zc.buildout.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Hello Eggs&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;One of the first things  plone developers noticed about eggs was the funny way they (by default) wriggle into your python's site-packages. Next thing noticed: the zope testrunner didn't know where to find them without symlinking them into Zope's lib/python.&lt;br /&gt;&lt;br /&gt;Zope(2) classically did not handle it's mountains of python like the rest of the python world did, so real surprise that zope did not jive with the new setuptools regime.  But things are getting better...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Building an Environment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Jim Fulton, pope of zope,  has been working on a system for composing large complex systems  called &lt;a href="http://www.zope.org/DevHome/Buildout/"&gt;zc.buildout&lt;span class="down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt; &lt;/span&gt;&lt;/a&gt;.   As part of this recipe driven strategy it can install eggs into a  local buildout directory(along with the rest of the buildout "parts").   Ostensibly, we will probably see recipes that can construct a  particular type of development environment for any variety of plonehead in the not too distant future.&lt;br /&gt;&lt;br /&gt;zc.buildout is a bit industrial to the first blush.  Nothing wrong with that, just a bit of framework comprehension and possibly simple programming required(if the current menu of recipes doesn't fit your bill).   zc.buildout looks very powerful and simple for deployment tasks, including building systems beyond python like squid or Apache. But maybe not the tool for playing around, testing and discarding your python ideas (yet).&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:78%;"&gt;note: If you are interested in zc.buildout for zope2, take a look at &lt;a href="https://svn.openplans.org/svn/topp.buildout/trunk/"&gt;topp.buildout&lt;/a&gt;, an initial experimental buildout attempt for &lt;a href="http://www.openplans.org/projects/opencore/getting-started"&gt;opencore stack&lt;/a&gt;.  For pedagologicaly purposes only. Ian says this is a bad buildout example.  look at zc.sharing.&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;Ian's &lt;a href="http://svn.colorstudy.com/home/ianb/workingenv"&gt;workingenv&lt;/a&gt; is a bit to the other side of the same spectrum.  It does a bit of the same thing but is more focussed on the python developer and python packages (as opposed to say a zope deployista with a host of other applications). It is more concerned with the problem of keeping those snakes on the plane than the care and feeding of your squid.&lt;br /&gt;&lt;br /&gt;workingenv allows you to create a temporarily constrained environment for python, substituting a localized work area for your site-packages. It plays nice with setuptools and is generally helpful.&lt;br /&gt;&lt;br /&gt;the self contained script runs like so::&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);font-family:courier new;" &gt;$ workingenv.py    mysandbox&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This bootstraps a local installation of setuptools to 'mysandbox', which now has  it's own bin, lib/python, conf and src directories.&lt;br /&gt;&lt;br /&gt;To activate the environment(using bash)::&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ source mysandbox/bin/activate&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once activated, you can install eggs like so (mysandbox/bin/easy_install is &lt;span style="font-style: italic;"&gt;now&lt;/span&gt; part of your path)::&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ easy_install  zc.buildout&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;All scripts are installed to the local bin.  Likewhise, any source packages you download and install via 'python setup.py develop' are installed in the local python directory.  For example::&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ cd mysandbox/src&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ svn co https://svn.openplans.org/svn/tagger/trunk tagger&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ cd tagger&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ python setup.py develop&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This puts an entry in mysandbox/lib/python/easy_install.pth pointing to my development directory in src/tagger.&lt;br /&gt;&lt;br /&gt;Even more convenient, workingenv.py will take a &lt;span style="color: rgb(153, 0, 0);"&gt;-r &lt;span style="color: rgb(0, 0, 0);"&gt;argument for an egg reciper.  This recipe may either be a url or a file.  To bootstrap a local turbogears development environment::&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 0, 0);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;$ workingenv.py  mytgsandbox&lt;/span&gt; -r &lt;/span&gt;&lt;span style="color: rgb(153, 0, 0);font-size:85%;" &gt;&lt;a href="http://svn.colorstudy.com/home/ianb/workingenv/tg-0.9.txt"&gt;http://svn.colorstudy.com/home/ianb/workingenv/tg-0.9.txt&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pretty nifty, eh? You may also embed -r into the recipes allowing recipes to be aggregates.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;workingenv and Zope 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For working with zope2, we can use workingenv's --env flag to set the INSTANCE_HOME and SOFTWARE_HOME environmental variables(needed for running tests without zopectl).  Zope install also expects the disutils --home flag, so we add it too.&lt;br /&gt;&lt;br /&gt;In this example, I create the environment first, pointing it at a zope src directory I have not created yet, then checking out the zope and installing zope that directory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ workingenv.py myzopesandbox --home --env=INSTANCE_HOME:~/mysandbox/zope --env=SOFTWARE_HOME:~/mysandbox/zope/lib/python&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ cd myzopesandbox; source bin/activate&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ svn co svn://svn.zope.org/repos/main/Zope/branches/2.9 zope&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ cd  zope&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ make inplace; make instance  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;This almost works.  For zopectl to see the lib/python inside the workingenv sandbox, you have to edit line 8 to read::&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;PYTHONPATH="$SOFTWARE_HOME:$PYTHONPATH"&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Now you have a fully functional constrained python environment for zope.  To deactivate::&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;$ deactivate&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-size:100%;" &gt;Python and shell return to their normal search path.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;The Zope Situation&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Not too shabby but not a great situation with zope. Obviously the match is a bit rough right now.  Editing a script is easy to forget, and all of Zope's legacy codebase exists as products, not eggs.&lt;br /&gt;&lt;br /&gt;This particular place where the road turns to dirt is where I think this may zc.buildout and workingenv might be able to work together for best effect.   zc.buildout lets us write recipes for zope2 installation and for handling products.   The recipes could recognize when they are executed in a workenv setting(workingenv.py sets an environmental variable) and smooth such rough spots as adding the current PYTHONPATH to zopectl's PYTHONPATH.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;TestRunner&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And maybe recipes could set the testrunner up to find the right eggs.  Currently, I have only found one sure fire way to have my testrunner run tests for a "development" egg (an egg installed via &lt;span style="color: rgb(204, 0, 0);"&gt;python setup.py develop&lt;/span&gt;)::&lt;br /&gt;&lt;br /&gt;For the tagger install example above(if it were installed into the zope sandbox)::&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);font-size:85%;" &gt;$ cd myzopesandbox&lt;br /&gt;$ zope/bin/zopectl&lt;br /&gt;zopectl&gt; test -s tagger --test-path=/myhome/myzopesandbox/src/tagger/src/tagger&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Part of the issue is the zope testrunner isn't really egg/setuptools aware yet(so it doesn't see those nifty pth files and follow them).  The other part of the issue, is that having the testrunner search the entire site-packages is slow.  This is the part workingenv solves; it's ok to search all available python pkgs because the environment is constrained to what you are working on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Final Thoughts&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'd like to see the testrunner handle setuptools better and I see potential in using zc.buildout to handle the ugly bits of bootstrapping one's environment.  I'd like to see both of this tools take advantage of workenv and it's developer and setuptools friendly way of doing  it's job.&lt;br /&gt;&lt;br /&gt;I look forward to more recipes for zc.buildout and a decent tutorial(nouri? bitte?).   Unlike workingenv, it's harder to get zc.buildout to doing something useful from the get go in the raw dev environment.&lt;br /&gt;&lt;br /&gt;My response to workingenv and zc.buildout is mostly viceral though; in the land of thousand frameworks, a "script that just works " like a cool glass of water.  We have deployment needs at work, but more commonly we have the need for bootstrapping consistent development environments.  workingenv plays nicely with existing tools like easy_install amd setup.py whereas zc.buildout requires everything to go through the buildout script.&lt;br /&gt;&lt;br /&gt;Right now, I prefer workingenv for developing and we are using zc.buildout for our buildbot. Still would like convergence though. Seems possible too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-115767422845928227?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/115767422845928227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=115767422845928227' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115767422845928227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115767422845928227'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/09/bootstrapenvironment.html' title='#!bootstrap/environment'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-115683559890936126</id><published>2006-08-29T00:11:00.000-07:00</published><updated>2006-08-29T00:13:18.913-07:00</updated><title type='text'>More on Layers</title><content type='html'>&lt;span style="font-family:georgia;"&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Riding Off into the Layered Sunset&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;a href="http://www.zope.org/Collectors/Zope/2179"&gt;&lt;br /&gt;ZopeTestCase still needs to grow up&lt;/a&gt;. Depending on code execution by import is pretty evil and forces developers to make choices that severely limit the ability of a framework to adapt to change(like say....adding zope3 component architecture to the mix). Controlling the exact order of import when dealing with code outside of your control is near impossible.&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;  The longer this remains as such, the more the engineering debt compounds and the worse someone will get hurt.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;In other words, do you want me to have to break your tests again and again?&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; Probably not.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;   Does ZopeTestCase have to die?  Maybe not. Maybe just get it's act in line with the current state of affairs.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Following PhiliKON's suggestion that ZopeTestCase should have it's own layer that handled installProduct calls, I did some preliminary investigation into what it would take to put the entire plone stack's testing onto layers including all of ZopeTestCase. The applied initial fruits of that investigation is the stop gap measure described in the last post.&lt;br /&gt;&lt;br /&gt;The complete work in progress is available at the following locations and goes much deeper into using layers to simplify the test structure:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="svn://svn.zope.org/repos/main/Zope/branches/2.9-layer-support"&gt;Zope 2.9 (layer enabled ZTC and Five)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;  &lt;a href="svn://svn.zope.org/repos/main/Zope/branches/whitmo-2.10-layers"&gt;Zope 2.10 (layer enable ZTC and Five)&lt;br /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="https://svn.plone.org/svn/plone/bundles/2.1-testing-layers/"&gt;Plone 2.1 for z2.9 (w/ all dependencies layer enabled and layer enable Five)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;In these brancheZopeTestCase has been refactored to isolate all behavior formerly triggered by import. In most cases, calls that were intended to act immediately defer there action until the appropriate layer via simple module level registries. This pattern is carried to PloneTestCase and other ZTC derivatives; for example, PloneTestCase has it's own layer that handles setting up the plone site the tests run against.&lt;br /&gt;&lt;br /&gt;The PTC layer inherits from the ZTC one and therefore all plone tests run as a section of the zope test case layer.&lt;br /&gt;&lt;br /&gt;The majority of the tests run without issue and most issues can be fixed with by removing code. More people need to bang on it, but it's ready to be banged on.&lt;br /&gt;&lt;br /&gt;Please bang away and let me know(or continue the work. would love some help here). With some feedback, this could get into Zope 2.11(only 3 months off).&lt;br /&gt;&lt;br /&gt;Finally, a big shout out to Stefan Holek. Without ZopeTestCase(and stefan to impress upon people the proper way to use it), many of us might still be rubbing rocks together in a dark cave, sacrificing hours to the zope gods hitting reload.&lt;br /&gt;&lt;br /&gt;Like many things in this world of code (like Zope2, AT, CMFFormController, etc), if it didn't work so well for so long we wouldn't be here to bitch about it now.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;  -w&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-115683559890936126?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/115683559890936126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=115683559890936126' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115683559890936126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115683559890936126'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/08/more-on-layers.html' title='More on Layers'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-115682121669739858</id><published>2006-08-28T19:53:00.000-07:00</published><updated>2006-08-29T00:11:34.483-07:00</updated><title type='text'>I Break Tests Because I Care</title><content type='html'>&lt;span style=";font-family:georgia;font-size:85%;"  &gt;First, a sincere apology to all of you who woke up this morning, updated your Plone bundle, ran your tests and suffered unexplainable breakage.   Thank you to those of you(particularily the observant stalwart developers of &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;a style="font-family: georgia;" href="http://zestsoftware.nl/"&gt;Zest Software&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;) who provided&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt; feedback and helped identify the following &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;a style="font-family: georgia;" href="http://www.zope.org/Collectors/Zope/2178"&gt;Zope 2 bug&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;It's 4am, do you know who your tests are bad touching?&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;&lt;br /&gt;Lately I've been working on the testing frameworks that are derivative of Testing.ZopeTestCase.  You may have read that&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;a style="font-family: georgia;" href="http://www.z3lab.org/sections/blogs/philipp-weitershausen/2006_03_10_death-to-zopetestcase?post_id=yeah-let-s-use-layers"&gt; ZopeTestCase must die&lt;/a&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;. You may have received a tongue lashing from a Five developer about writing a test that uses the infamous "installProduct('Five')".  You may simply have used the provided test framework unaware that your tests were treating other packages' tests like the Bush Administration treats personal civil liberties or poor people and minorities.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-weight: bold;"&gt;It's ok.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;If you can forgive me for breaking your tests, I'm sure all those hard working Five developers will find it in their hearts to forgive you for the fact you can't run Plone's test and Five's tests at the same time.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Until now&lt;/span&gt; (or about six months ago shrouded in the vault of zope.*),&lt;/span&gt;&lt;span style="font-size:85%;"&gt; the &lt;span style="font-weight: bold;"&gt;right way&lt;/span&gt; was hard and painful and full of &lt;span style="font-weight: bold;"&gt;stinky boilerplate&lt;/span&gt;.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Layers: The Neighbourly way to Set Up Your Zope 3 Components&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;In zope 2.9, the zope 3 testrunner became available to us z2 trogdolytes and with it the zope3 strategy for more efficient functional and integration testing:&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;layers&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;Layers&lt;/span&gt; are a little like social clubs for tests.   Just because your unit tests in your package live next to your integration tests doesn't mean that they should run together or even like each other.  Layers let everyone run where they are comfortable and happy and passing; the frat layers spills no beer on the goth layer, the goth layer doesn't bum out the church goers and so on.  This applies whether you run your tests alone, or with everyone elses.&lt;br /&gt;&lt;br /&gt;The testrunner groups test cases (think classes like ZopeTestCase, PloneTestCase etc) by their layer and runs them together (any tests lacking a testcase with a layer run in a group called&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt; unit tests&lt;/span&gt;&lt;span style="font-size:85%;"&gt;).    Between the setup and the teardown of a layer, all tests run inbetween are assure of having the environment they expect.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Cut to our dilemma.&lt;/span&gt; What we are currently most concerned about in this picture is the  component architecture.    The entire component architecture: all the views, adapters, events, etc that make up a running Zope 2 site.   If  you have ever had to debug a  rogue &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;ComponentLookUpError,&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;spent hours wondering where your views and adapters disappeared to, you know this pain.&lt;br /&gt;&lt;br /&gt;The current method of doing this,&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt; Testing.ZopeTestCase.installProduct('Five'),&lt;/span&gt; can only be called once and only once to set up the component architecture; all subsequent calls have no effect once Five has been loaded by ZopeTestCase.   Therefore, If a unit test happens to call zope.testing.placelesssetup.tearDown or zope.testing.cleanup.cleanUp&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:georgia;" &gt;&lt;span style="font-size:85%;"&gt;,  all following tests will have no component architecture.  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;Welcome to test debug hell&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:georgia;" &gt;&lt;span style="font-size:85%;"&gt;.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Fear not&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;&lt;span style="font-size:85%;"&gt;.&lt;/span&gt; There is hope for your fragile testing setup. layers can &lt;span style="color: rgb(255, 102, 102);"&gt;setUp&lt;/span&gt; and  &lt;span style="color: rgb(255, 102, 102);"&gt;tearDown&lt;/span&gt; the CA as often as needed.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;PloneTestCase and CMFTestCase now have some basic layer support to make this easy.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;a href="http://svn.plone.org/svn/collective/CMFTestCase/trunk/"&gt;http://svn.plone.org/svn/collective/CMFTestCase/trunk/&lt;br /&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;a href="http://svn.plone.org/svn/collective/PloneTestCase/trunk/"&gt;http://svn.plone.org/svn/collective/PloneTestCase/trunk/&lt;br /&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;   Any test that inherit from these classes gets the layer treatment that handle setting up the CA. Usage is usually as easy as simply putting these branches in your products directory.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Since &lt;span style="font-weight: bold;"&gt;layers are a useful tool to the test writer&lt;/span&gt;, let's take a loo&lt;span style="font-weight: bold;"&gt;K&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;at what is going on here. It's best to simply think of the layer as a named data block with 2 methods: setUp, and tearDown.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.plone.org/collective/browser/PloneTestCase/trunk/layer.py"&gt;&lt;br /&gt;Here we see the layer that loads the CA&lt;/a&gt;.  It is an old style class with a classmethod  setUp loads the entire CA(and does a bit to make sure ZCML error messages are not supressed due to ZTC optimization). The classmethod tearDown cleans up afterwards.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Pretty simple.&lt;br /&gt;&lt;br /&gt;The classmethod calls may look a bit strange. Again, think of this class as data block rather than an object factory; the layer will never be instanciated in the classic OOP sense.&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;    &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Note:&lt;/span&gt; The conventional pattern for layer is to use an old style class and classmethods; concievably, you could use a module with setUp and tearDown functions or an instanciated object with  setUp and tearDown methods, but an old style class with classmethod seems to be the most reliable and flexible.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-size:85%;"&gt;  Applying the layer is easy too.   &lt;a style="font-weight: bold;" href="http://dev.plone.org/collective/browser/PloneTestCase/trunk/PloneTestCase.py#L44"&gt;The layer is assigned as an attribute to the test class&lt;/a&gt;.  Currently for BBB a set of checks makes sure that layers are available(hence setup.USELAYER).  If you know you are developing against 2.9 or greater and don't need any BBB, this check is unnecessary.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Now when we run the the Plone tests (&lt;span style="color: rgb(204, 0, 0);"&gt;$ bin/zopectl test -s Products.CMFPlone&lt;/span&gt;), we see the following ::&lt;br /&gt;&lt;/span&gt;&lt;results&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;br /&gt;Running unit tests:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;Running:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;br /&gt;......................................................................................................................&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;br /&gt;Ran 158 tests with 0 failures and 0 errors in 1.465 seconds.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;&lt;br /&gt;Running Products.PloneTestCase.layer.ZCMLLayer tests:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;&lt;br /&gt;Set up Products.PloneTestCase.layer.ZCMLLayer in 0.883 seconds.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;br /&gt;Running:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;..................................................................................................... etc....&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;Ran 1750 tests with 11 failures and 0 errors in 182.200 seconds.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;Tearing down left over layers:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;Tear down Products.PloneTestCase.layer.ZCMLLayer in 0.002 seconds.&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;Total: 1908 tests, 11 failures, 0 errors&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;All tests not requiring the CA  or tests which handle all setup and teardown inside the test run first.  Then  ZMCLayer is set up, all tests that use it run, and the layer is torn down.  If you just wanted to run the CA dependent tests you could do so with the following command:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:78%;"&gt; ~/zopesite/ $&lt;span style="font-weight: bold;font-size:78%;" &gt;bin/zopectl test -s Products.CMFPlone --layer=Products.CMFPlone.layer.ZCMLLayer&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;    What does this mean to me and my work?&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;if you are lucky, it may just be a few more statistics spit out of your test runner (and the ability to run all your tests at once).  It could just work in many situations.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/results&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Chance are it won't work if your &lt;span style="font-weight: bold;"&gt;[Plone/CMF]TestCase&lt;/span&gt; test commits the following crimes against nature (check yourself if you've been wading in the z3 soup).&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;If your tests uses &lt;span style="font-weight: bold;"&gt;PloneTestCase&lt;/span&gt; and does the following:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;uses&lt;span style="color: rgb(255, 0, 0);"&gt; Products.Five.zcml.load_string or&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; Products.Five.zcml.load_config&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;uses aforementioned to load functions to load zcml that never gets loaded on Zope site loading&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;calls &lt;span style="color: rgb(255, 0, 0);"&gt;provideAdapter&lt;/span&gt; or other convenience registration functions&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;calls &lt;span style="color: rgb(255, 0, 0);"&gt;zope.testing.placelesssetup.tearDown&lt;/span&gt; or &lt;span style="color: rgb(255, 0, 0);"&gt;zope.testing.cleanup.cleanUp&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;1-3 will result in erratic behavior for tests within the ZCMLLayer layer&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;.  #4&lt;/span&gt;&lt;span style="font-size:85%;"&gt; will result in ComponentLookUpErrors due to the clearing of the registries of the component architecture.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Never fear: just following these easy refactorings.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;You must&lt;/span&gt;(fixes in order of issues):&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Delete it. you don't need it anymore&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;Slap yourself for doing this.&lt;/span&gt; Refactor your test into units and integration tests.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Repeat fix for #2&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Delete it. you don't need it.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;If you find that you are slapping yourself alot, you are feeling layers are in forcing us to use better testing practices.&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:georgia;font-size:85%;"  &gt;&lt;br /&gt;You may even find you need a special layer of specific zcml loads.&lt;/span&gt;&lt;span style="font-size:85%;"&gt; Mostly, you should just be deleting now useless boilerplate and loving it.  If not, let me know.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;You may notice that layers force us to divide our tests into more appropriate groupings of unit tests(atoms of code), and groups of p[roper integration tests(framework w/ code units)&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;It is important to understand that with this strategy&lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt; all the active zcml is loaded for a site&lt;/span&gt;&lt;span style="font-size:85%;"&gt;.  This means if some product or package overrides zcml effecting your test, your test may behave differently than you expect(hopefully, your test coverage will actually act like a canary in the coal mine in this situation).&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;Note&lt;/span&gt;&lt;span style="font-size:85%;"&gt;:&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;for working ZTC doctest layer support, a fresh checkout of the Zope 2.9 branch is required&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;&lt;br /&gt;Coming soon: The Future!!!!&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-115682121669739858?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/115682121669739858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=115682121669739858' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115682121669739858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/115682121669739858'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/08/i-break-tests-because-i-care.html' title='I Break Tests Because I Care'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-114900957728363213</id><published>2006-05-30T10:19:00.000-07:00</published><updated>2006-05-30T10:19:37.343-07:00</updated><title type='text'>zX</title><content type='html'>maybe zope should take a hint from OS X and use this fine release to dump some name baggage? 2.10 looks awesome.&lt;br /&gt;&lt;br /&gt;just a few hings I'm excited about:&lt;br /&gt;&lt;br /&gt;* wsgi &amp;amp; twisted&lt;br /&gt;&lt;br /&gt;* formlib&lt;br /&gt;&lt;br /&gt;* viewlets&lt;br /&gt;&lt;br /&gt;* clockserver&lt;br /&gt;&lt;br /&gt;* testbrowser&lt;br /&gt;&lt;br /&gt;* z3 ZPTs&lt;br /&gt;&lt;br /&gt;* no more traversable directives!&lt;br /&gt;&lt;br /&gt;* pythonproducts: zope2 code that lives on the pythonpath like normal python&lt;br /&gt;&lt;br /&gt;* native egg support&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.zope.org/Products/Zope/2.10.0b1/CHANGES.txt"&gt;Zope.org - Changes.txt&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-114900957728363213?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/114900957728363213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=114900957728363213' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114900957728363213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114900957728363213'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/05/zx.html' title='zX'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-114891492763115957</id><published>2006-05-29T08:02:00.000-07:00</published><updated>2006-05-29T08:06:35.876-07:00</updated><title type='text'>wonder what that graph looks like for Plone?</title><content type='html'>Interesting stuff bouncing around the Django and RoR blogs in relation to Django's recent effort to remove magic.&lt;br /&gt;&lt;br /&gt;This part of the discussion includes a visualization of change for RoR releases: &lt;a href="http://blog.zenspider.com/archives/2006/04/where_is_our_ma.html"&gt;Polishing Ruby: Where is our "magic-removal branch"?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is the idea that caught my eye: improving a system's refactorability as a quantifiable exercise.&lt;br /&gt;&lt;br /&gt;plus quantifying improvement can be a powerful motivator (as anyone who has gone on an optimization binge knows).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-114891492763115957?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/114891492763115957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=114891492763115957' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114891492763115957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114891492763115957'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/05/wonder-what-that-graph-looks-like-for.html' title='wonder what that graph looks like for Plone?'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-114805157346415479</id><published>2006-05-19T08:12:00.000-07:00</published><updated>2006-05-19T08:13:00.446-07:00</updated><title type='text'>Why are people still afraid of JavaScript? at Blue Sky On Mars</title><content type='html'>A question I've been meaning to ask (from the leader of another fine python project): &lt;a href="http://www.blueskyonmars.com/2006/05/19/why-are-people-still-afraid-of-javascript/"&gt;Why are people still afraid of JavaScript? at Blue Sky On Mars&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-114805157346415479?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/114805157346415479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=114805157346415479' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114805157346415479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114805157346415479'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/05/why-are-people-still-afraid-of.html' title='Why are people still afraid of JavaScript? at Blue Sky On Mars'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-114410787894669679</id><published>2006-04-03T16:44:00.000-07:00</published><updated>2006-04-25T07:59:51.350-07:00</updated><title type='text'>AdvancedQuery: discovering a new wrinkle</title><content type='html'>&lt;a href="http://www.dieter.handshake.de/pyprojects/zope/AdvancedQuery.html"&gt;AdvancedQuery&lt;/a&gt; by Dieter Mauer is one of my favorite zope extensions.  It gives the ZCatalog, zope's indexing system for the zodb the ability to do SQL-like and even more advanced queries against a set of indexes.&lt;br /&gt;&lt;br /&gt;While doing some work on &lt;a href="http://plone.org/products/wicked"&gt;wicked,&lt;/a&gt; I discovered another fantastic piece of syntactic sugar.  The query objects that you use to build the queries support inplace operations.  This allows for the elegant creation of aggregate queries. consider this contrived example for a keyword index::&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; from Products.AdvancedQuery import Eq&lt;br /&gt;&gt;&gt;&gt; tags = ['dogs', 'love', 'trucks']&lt;br /&gt;&gt;&gt;&gt; def findADate(gender, interests, iam_easy=True):&lt;br /&gt;...    q = lambda tag: Eq('keywords', tag) &amp; Eq('gender', 'gender')&lt;br /&gt;...&lt;br /&gt;...    # gotta start with something&lt;br /&gt;...    query=q(interest[0])&lt;br /&gt;...&lt;br /&gt;...    for interest in interest[1:]:&lt;br /&gt;...        if iam_easy: query |= q(interest)&lt;br /&gt;...        else: query &amp;= q(interest)&lt;br /&gt;...&lt;br /&gt;...    return query&lt;br /&gt;&lt;br /&gt;once we've built a query, we can use it&lt;br /&gt;with the special method AdvQ adds to all catalogs&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; from Products.CMFCore.utils import getToolByName&lt;br /&gt;&gt;&gt;&gt; catalog = getToolByName(app.portal, 'portal_catalog')&lt;br /&gt;&gt;&gt;&gt; q = findADate('female', tags)&lt;br /&gt;&gt;&gt;&gt; listofdates = catalog.evalAdvancedQuery(q)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Representing queries as objects is a bit more cumbersome for getting started than existing query languages, but being able to programatically build queries with the overhead of awkward string parsing is a big win.  The inplace "or" is icing on the cake.&lt;br /&gt;&lt;br /&gt;I could see AdvancedQuery forming the basis for a sqlish query language for the catalog and ZODB, something many rdb lovers complain is missing from the world of zope.  Since all statements would be backed by objects, programmatically creating queries would be as easy as just demonstrated.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;note: |= and &amp;= are also available for sets in python&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-114410787894669679?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/114410787894669679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=114410787894669679' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114410787894669679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114410787894669679'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/04/advancedquery-discovering-new-wrinkle.html' title='AdvancedQuery: discovering a new wrinkle'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-114149533304442722</id><published>2006-03-04T10:02:00.000-08:00</published><updated>2006-03-04T13:05:08.340-08:00</updated><title type='text'>zope, man, get it together</title><content type='html'>&lt;a href="http://griddlenoise.blogspot.com/2006/03/zope-crisis-of-faith-coming-this-march.html"&gt;Griddle Noise: Zope: A Crisis of Faith. Coming this March to TNT (TNT! TNT!)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;the entry above and &lt;a href="http://griddlenoise.blogspot.com/2006/03/crisis-of-faith-messengers-have-been.html"&gt;this followup comparing other web frameworks,&lt;/a&gt;&lt;br /&gt;encapsulates alot of the same emotions I have about this technology and community.&lt;br /&gt;&lt;br /&gt;I haven't read the zope3 naming thread, but judging from the ripples in the pond, it may be a while before I have the time to read it and recover from the resulting depression.&lt;br /&gt;&lt;br /&gt;In the zope world, I believe we have a tragedy of the commons.  Too many people depend on the decisions of too few.  Unlike TG which is a community of self sufficient communities, we wallow in dependency.  Downstream and upstream.&lt;br /&gt;&lt;br /&gt;Maybe the best argument for small frameworks is that they require less gurus to maintain effectively.  Maybe zope(2 or 3) is simply too big for the small number of core developers to truly fix all the broken windows(to truly serve it's massive audience of developers, designers, integrators, etc).&lt;br /&gt;&lt;br /&gt;I think there is a strong argument here for smaller pieces that can be effectively supported.   That can have effective messages.  That can have effective documentation.  That can solve a single problem most effectively.  Than can exist without depending on anything larger than itself.&lt;br /&gt;&lt;br /&gt;That can really do what they are suppose to do best without being obscured by a heap of other concerns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-114149533304442722?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/114149533304442722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=114149533304442722' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114149533304442722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114149533304442722'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/03/zope-man-get-it-together.html' title='zope, man, get it together'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-114070985581031077</id><published>2006-02-23T07:50:00.000-08:00</published><updated>2006-02-23T07:50:55.870-08:00</updated><title type='text'>hmm....who posted this from PloneBlog?</title><content type='html'>The author of a post doesn't show up in planetplone which causes cognitive dissonance for me.   For some reason PlanetPlone and the PloneBlog can't seem to communicate who the author of PloneBlog's posts are.&lt;br /&gt;&lt;br /&gt;I know this is a bitchy information architecture gripe, but the author is possibly the most import piece of context for this sort of free form media. If I have ten minutes to catch up on plone, scanning for author is really important.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://theploneblog.org/"&gt;http://theploneblog.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://planet.plone.org/"&gt;http://planet.plone.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;so whatya say?  can this broken window be fixed?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-114070985581031077?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/114070985581031077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=114070985581031077' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114070985581031077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/114070985581031077'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/02/hmmwho-posted-this-from-ploneblog.html' title='hmm....who posted this from PloneBlog?'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-113925180422512777</id><published>2006-02-06T10:50:00.000-08:00</published><updated>2006-02-06T10:50:04.273-08:00</updated><title type='text'>hasta la pork knuckle baby!</title><content type='html'>&lt;style type="text/css"&gt;.flickr-photo { border: solid 1px #000000; }.flickr-frame { float: left; text-align: center; margin-right: 15px; margin-bottom: 15px; }.flickr-caption { font-size: 0.8em; margin-top: 0px; }&lt;/style&gt;&lt;div class="flickr-frame"&gt;	&lt;a href="http://www.flickr.com/photos/15935247@N00/94268798/" title="photo sharing"&gt;&lt;img src="http://static.flickr.com/11/94268798_9c66072d8f_t.jpg" class="flickr-photo" alt="SnowSprint20060201-201654.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;	&lt;span class="flickr-caption"&gt;		&lt;a href="http://www.flickr.com/photos/15935247@N00/94268798/"&gt;SnowSprint20060201-201654.JPG&lt;/a&gt;,&lt;br /&gt; originally uploaded by &lt;a href="http://www.flickr.com/people/15935247@N00/"&gt;sashav&lt;/a&gt;.	&lt;/span&gt;&lt;/div&gt;via la pork knuckle!&lt;br /&gt;&lt;br /&gt;The sprint is over. and after a canceled flight and a night in Zurich, I'm back home to Nashville.  &lt;br /&gt;&lt;br /&gt;There is still alot to be done with explaining how the Zope 3 story fits with Plone's story, as well as many coding projects to get finished.  But I learned alot and took part in alot of healthy discussions.&lt;br /&gt;&lt;br /&gt;At sprint we saw the fufillment of the promise of Goldegg as a zeitgeist for development; you couldn't turn around without someone mentioning adapter patterns, interfaces, views or namespaces.  This translated into some of the best thought out and carefully tested code I've seen come out of a snow sprint. &lt;br /&gt;&lt;br /&gt;On the Plone front, I am very positive about the future.  It's just a matter of getting concerns separated out into the proper places.  Zope 3 doesn't need to be the boogy man of the future present.&lt;br /&gt;&lt;br /&gt;Everyone needs to remember this is not a Zope 2 vs. Zope 3 platform advocacy argument.  We should not be "switching" anything drastically, except for possibly some old  slow zope2-centric ways of developing for some faster more python-centric ones.&lt;br /&gt;&lt;br /&gt;To paraphrase James Carville: It's about the python stupid. and writing python in a way that makes the most sense.  Finally, we have some tools to do this with.  They happened to be named Zope 3 and Five.&lt;br /&gt;&lt;br /&gt;On the home front, despite all the meat and cheese, plone-jobs, flying heirscht, and time zone changes, I feel rested and ready to go.  &lt;br /&gt;&lt;br /&gt;A good sprint is like hitting reset and starting with fresh batteries.&lt;br /&gt;&lt;br /&gt;So, in closing, a big thanks to Jodok and the rest of the lovelies for making this happen once again and until next year, auf wiedersehen!&lt;br clear="all" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-113925180422512777?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/113925180422512777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=113925180422512777' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113925180422512777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113925180422512777'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/02/hasta-la-pork-knuckle-baby.html' title='hasta la pork knuckle baby!'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-113869997688773890</id><published>2006-01-31T01:32:00.000-08:00</published><updated>2006-01-31T01:32:56.913-08:00</updated><title type='text'>snow sprint 2006: the end of the world as you know it</title><content type='html'>It's the law of critically organizing phenomena.  Everyday is the end of the world as you know it.  Simply  put, some days it is more apparent than others.&lt;br /&gt;&lt;br /&gt;Last night stephan richter created an area in the Plone svn repository for the the plone namespace package for zope3.&lt;br /&gt;&lt;br /&gt;Why is this important? &lt;br /&gt;&lt;br /&gt;To my knowledge, this is the first time that Plone the brand has decoupled from CMFPlone the Zope 2 `Product` for anything other than t-shirts and the occasional conference topic.  My perspective is the plone communities vice of platform monotheism as having isolated us from sharing our virtues.&lt;br /&gt;&lt;br /&gt;Most of what makes Plone valuable is not architectural. The knowledge about user experience and usability, the solutions to a myriad of use cases, the practical experience informing the product is broadly applicable to a larger space. &lt;br /&gt;&lt;br /&gt;This is not to say parts of the Plone stack are envelope-pushing examples of what can be done with Zope 2 and Zope's Content Management Framework. &lt;br /&gt;&lt;br /&gt;Dually, Plone has been a shining example for the need for Zope 3, at once a demonstration of the power and business potential of Zope 2 and CMF, and a tremendous example of the issues of Zope 2 and CMF that propogated and educated the Zope 3 rewrite.&lt;br /&gt;&lt;br /&gt;Zope 3 is a ground up rewrite of Zope 2 embodying these lessons learned by the Zope, web development, and python community over the last five or so years in the creation of systems like the current Plone CMS.   Ruthless refactoring has led to a raw, powerful  and developer friendly system for solving problems in the webspace.  It is conveniently focussed on making life more fun and productive for those who have paid their dues in Zope2 working with systems like CMFPlone.&lt;br /&gt;&lt;br /&gt;If we look at Plone, we see a majority of issues that are pain points for the Plone community of integrators, solution providers, service providers and development community stem from issues with maintainablility, orthogonality, migration, dependency and quality management that Zope 3 has rigorously improved on over Zope2 both in process and in code.&lt;br /&gt;&lt;br /&gt;On the other hand, the emphasis on design, usability, and user experience that make Plone so compelling is lacking in Zope3.   Though Zope3 has all the necessary tool to develop a full blown CMS (see TIKS), Plone is still considered to be a preferable alternative if what you need is a CMS, in spite of the maintenance costs and learning curve inherent with deploying Zope 2 systems.&lt;br /&gt;&lt;br /&gt;Complementary interests and strengths? absolutely.  Is plone on zope3 a fork of CMFPlone?&lt;br /&gt;&lt;br /&gt;absolutely not.&lt;br /&gt;&lt;br /&gt;Zope3's biggest contribution to python at large is it's component architecture.  zope.interface has found it's way into a number major projects such as Twisted and rdflib and zope.component will undoubtably find it's way into many more.   A road tested and ruthless refactored system, it is currently finding it's way back into Zope 2 as a powerful tool for extending old Zope 2 applications and building new ones.&lt;br /&gt;&lt;br /&gt;What does this mean?  CMFPlone can use Zope3 components today, and Zope3 can use components written for CMFPlone.  This means that beyond adaptation needed for compatibility, the rest of the python written is interchangeable and reusable.&lt;br /&gt;&lt;br /&gt;No forking is necessary to `rewrite` plone or CMFPlone.  All that is necessary is for Plone developers to refactor old behavior as components and develop new behavior as components.   Bite-sized, simple, easily testable, sensible components.   On the zope3 side, a basic scaffolding can be built with existing components.&lt;br /&gt;&lt;br /&gt;Plone can return to being a skin rather than a framework.  Zope3 can benefit from the availability of a new set of components informed by Plone experience in the CMS space. &lt;br /&gt;&lt;br /&gt;Having a unified architecture for componentization allows this.  Now we have a plone namespace where plone developer can start developing....free of the cruft of Zope2 et. al.   Like a clean lab to work in, Zope3 will allow better quality control, faster development cycles, better feedback, and better productivity.&lt;br /&gt;&lt;br /&gt;Don't get me wrong.&lt;br /&gt;&lt;br /&gt;It's not a silver bullet.  It doesn't remove the complexity of a fullblown CMS with 4 + years of rapid development.  It requires a little extra conscious effort and some hard thought about what Plone is doing right and wrong.  It require some scrutiny to how components should be licensed to encourage reuse and proliferation.&lt;br /&gt;&lt;br /&gt;It requires alot of active engagement by the plone community. It requires changes in the way we do things and some work to make the flow of components from Zope3 to CMFPlone and back as efficient as possible.&lt;br /&gt;&lt;br /&gt;But....&lt;br /&gt;&lt;br /&gt;it makes me excited to write code for plone and for zope[3] again.   and I haven't felt that way in a while.   This community has always had a tremendous spark; it classicaly has attracted interesting  smart enthusiastic people doing interesting things.&lt;br /&gt;&lt;br /&gt;hopefully, this will help keep that tradition by making it easier to quickly manifest those ideas.&lt;br /&gt;&lt;br /&gt;Because, singularity or not, that is what it's all about......&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-113869997688773890?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/113869997688773890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=113869997688773890' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113869997688773890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113869997688773890'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2006/01/snow-sprint-2006-end-of-world-as-you.html' title='snow sprint 2006: the end of the world as you know it'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-113407170542924006</id><published>2005-12-08T11:55:00.000-08:00</published><updated>2005-12-08T15:54:10.656-08:00</updated><title type='text'>a nice listing of zope3 resources  /  so what about that z3 website</title><content type='html'>&lt;style type="text/css"&gt;.flickr-photo { border: solid 1px #000000; }.flickr-frame { float: left; text-align: center; margin-right: 15px; margin-bottom: 15px; }.flickr-caption { font-size: 0.8em; margin-top: 0px; }&lt;/style&gt;&lt;div class="flickr-frame"&gt; &lt;a href="http://www.flickr.com/photos/58966261@N00/71548819/" title="photo sharing"&gt;&lt;img src="http://static.flickr.com/34/71548819_235b501788_t.jpg" class="flickr-photo" alt="mrnatty" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span class="flickr-caption"&gt;  &lt;a href="http://www.flickr.com/photos/58966261@N00/71548819/"&gt;mrnatty&lt;/a&gt;,&lt;br /&gt;originally uploaded by &lt;a href="http://www.flickr.com/people/58966261@N00/"&gt;morriss&lt;/a&gt;. &lt;/span&gt;&lt;/div&gt;The z3 dev team is the classic web-developer without a homepage syndrome I imagine.&lt;br /&gt;&lt;br /&gt;Jeff Shell kindly lends a hand with this blog entry:&lt;a href="http://griddlenoise.blogspot.com/2005/10/some-zope-3-quick-starts-and-resources.html"&gt;Griddle Noise: Some Zope 3 Quick Starts and Resources&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Web framework homepages are often dogbowls: demonstrations and operating points of pain for the framework (exhibit A for pain, the old zope CMF site, now thankfully retired).     Without doubt, they reflect upon the community like wearing a clean shirt on a first date.   If RoR had an ugly site, would the python community have spawned half as many Ruby-on-Rails alternatives?&lt;br /&gt;&lt;br /&gt;In my neck of the woods, the &lt;a href="http://plone.org/"&gt;new plone.org site&lt;/a&gt; just got launched. I think it is a good example of serving what you sell.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;and yeah,&lt;/span&gt; it makes me a little proud that these are the people I drink beer and code with. &lt;span style="font-size:78%;"&gt;[small disclaimer, plone is a *CMS* not a *web framework*]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The plone.org site deploys solutions like PlonePas (enterprise pluggable authentication) and CacheFu (a caching framework for CMF that allows a site implementor to play nicely with such caching solutions as the &lt;a href="http://www.squid-cache.org/"&gt;squid proxy server&lt;/a&gt; and &lt;a href="http://www.danga.com/memcached/"&gt;memcached&lt;/a&gt;).  &lt;br /&gt;&lt;br /&gt;At the same time, it doesn't try to do everything in plone and plone alone; &lt;a href="http://paste.plone.org/"&gt;paste.plone.org&lt;/a&gt; is a php app and trac is used for svn browsing, issue collectors, and developer wiki.  &lt;a href="http://planet.plone.org/"&gt;planet.plone.org&lt;/a&gt; runs a python implementation of planet for blogs.&lt;br /&gt;&lt;br /&gt;It's really nice mix of technologies, but  this is a hard won balance.   The hammer impulse often has made it difficult for members of the plone community, especially one who have just got their sea legs, from making the dive into interoperability or not reinvent wheel. Plone has suffered as people pushed to do things they simply shouldn't (I myself can claim a few formerly square holes rammed into plone shaped ones).    Too many times we have answered the question "what is plone good for" with "whatever you want to do!"&lt;br /&gt;&lt;br /&gt;As Mr. Natural says, "Use the Right Tool for the Job".  &lt;br /&gt;&lt;br /&gt;In this spirit, many people have left the zope in the past, declaring it insane and written their own python web frameworks (this is a popular pythonist weekend activity) while the zope community (all of us still in the looney bin), plugged along contributing tons of code....to the zope community.&lt;br /&gt;&lt;br /&gt;Happily, this is changing, at least on the zope side. Zope Interface are showing up places like rdflib and twisted, as well as in Zope2.  But alot of the misconceptions still linger on..... &lt;br /&gt;&lt;br /&gt;A new zope3 webpage, ahem, might help this.  Thanks to &lt;a href="http://tinyurl.com/ck274"&gt;enTransit&lt;/a&gt;, it could even use plone as it's CMS.....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-113407170542924006?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/113407170542924006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=113407170542924006' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113407170542924006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113407170542924006'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2005/12/nice-listing-of-zope3-resources-so.html' title='a nice listing of zope3 resources  /  so what about that z3 website'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-113404778200756626</id><published>2005-12-08T05:16:00.000-08:00</published><updated>2005-12-08T05:16:22.023-08:00</updated><title type='text'>lispers in the dark</title><content type='html'>...the language / framework / geek-web-tribe wars rage on:&lt;a href="http://www.aaronsw.com/weblog/rewritingreddit"&gt;Rewriting Reddit (Aaron Swartz: The Weblog)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My favorite is the props from the &lt;a href="http://smallthought.com/avi/?p=3"&gt;RoR guys to Seaside&lt;/a&gt;.  That's right lisp, smalltalk (and ruby and python) is whooping your butt in the mindshare department.&lt;br /&gt;&lt;br /&gt;In my little world, none of this really matters (yet), but the lessons are important.  Nothing from lisp has hit my radar where my pocket book lives, except one area, emacs (which might as well be my OS).  &lt;br /&gt;&lt;br /&gt;OTOH Seaside got me to actually take a look at smalltalk and install Squeak. Because of immediately apparent value to what I am doing right now (and this is the reason I know Perl, Python, PHP and snippets of a handful of other language).&lt;br /&gt;&lt;br /&gt;The ends may or may not justify the means, but they will bring the needing to your door if the ends do the needful.  &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-113404778200756626?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/113404778200756626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=113404778200756626' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113404778200756626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113404778200756626'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2005/12/lispers-in-dark.html' title='lispers in the dark'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-113388839680695685</id><published>2005-12-06T08:59:00.000-08:00</published><updated>2005-12-06T09:03:03.906-08:00</updated><title type='text'>double, triple, quadruple happiness</title><content type='html'>oh the power!  google and ye' shall find.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mjtsai.com/blog/2003/01/02/multiple_emacs_shell_buff/"&gt;Michael Tsai - Blog - Multiple Emacs Shell Buffers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I always wondered why I could only run one shell in emacs.  Of course, I was wrong, so wrong. &lt;br /&gt;&lt;br /&gt;Now I can use the python debugger *and* run a zope process in the forground *and* run unit tests *and* a zope debug session all from the comfort of emacs  with power of python mode.&lt;br /&gt;&lt;br /&gt;I'm *so* not putting on pants today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-113388839680695685?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/113388839680695685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=113388839680695685' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113388839680695685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113388839680695685'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2005/12/double-triple-quadruple-happiness.html' title='double, triple, quadruple happiness'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19347241.post-113307202669054345</id><published>2005-11-26T21:29:00.000-08:00</published><updated>2005-11-27T00:05:39.793-08:00</updated><title type='text'>welcome to the stick factory</title><content type='html'>&lt;span style="font-family:georgia;"&gt;Sometimes you take a little time out of your vacation to spend an afternoon with a friend scratching an itch for the collective group.&lt;br /&gt;&lt;br /&gt;Sometimes this is more of an exploration, an attempt to learn more about the problem and employ techniques that might lessen pain in the future and solve a variety of problems in the same domain.&lt;br /&gt;&lt;br /&gt;Sometimes someone else fixes the specific problem, &lt;a href="http://bcsaller.blogspot.com/2005/11/plotting-course.html"&gt;reads a blog entry of  your friend&lt;/a&gt; and &lt;a href="http://awkly.org/archive/stop-please-someone-make-them-stop"&gt;then digs up some fine quotes in the blogosphere to bludgeon your co-conspirator over the head.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nice stick.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Sometimes we've had a bad day and just want to righteously wail on something or someone.&lt;br /&gt;&lt;br /&gt;Enter the handy stick.   &lt;a href="http://plope.com/Members/chrism/pythonic"&gt;Like pythonic.&lt;/a&gt; Or YAGNI or DRY or KISS or RTFM or the idea that "less code is better". or whatever your favorite XP whip is. or in this case, that frameworks suck (just like everything else).&lt;br /&gt;&lt;br /&gt;From the perspective of personal practice, these are all important ideas, and used in the correct context, result in better code. They can act as a sort of flashlight for illuminating new ways of thinking about things. These new ways of thinking about things frequently benefit those who adopt them, hence their popularity.&lt;br /&gt;&lt;br /&gt;Applied loosely in a public forum, these fine phrases or concepts, married with a link or two, can satisfylingly polarize conversations, completely erase any meaningful dialogue and summon waves of stop energy from all those who may not understand the actual nuts and bolts of the debate, but respond positively to the buzzmemes used.&lt;br /&gt;&lt;br /&gt;In this context, they are statements of culture, banners of association, not of use to constructively solving the problems that have evoked the discourse in the first place.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:georgia;"&gt;goodbye nuance and feedback.&lt;/span&gt; hello dogma.&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;br /&gt;thwap. end of conversation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19347241-113307202669054345?l=bfhammer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bfhammer.blogspot.com/feeds/113307202669054345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19347241&amp;postID=113307202669054345' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113307202669054345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19347241/posts/default/113307202669054345'/><link rel='alternate' type='text/html' href='http://bfhammer.blogspot.com/2005/11/welcome-to-stick-factory.html' title='welcome to the stick factory'/><author><name>whit</name><uri>http://www.blogger.com/profile/03539857445736145486</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
