[Checkins] SVN: z3c.builder.core/trunk/ initial import.

Paul Carduner paulcarduner at gmail.com
Fri Mar 27 04:50:42 EDT 2009


Log message for revision 98391:
  initial import.

Changed:
  A   z3c.builder.core/trunk/
  A   z3c.builder.core/trunk/CHANGES.txt
  A   z3c.builder.core/trunk/README.txt
  A   z3c.builder.core/trunk/assumptions.txt
  A   z3c.builder.core/trunk/bootstrap.py
  A   z3c.builder.core/trunk/buildout.cfg
  A   z3c.builder.core/trunk/design.txt
  A   z3c.builder.core/trunk/sample-project.xml
  A   z3c.builder.core/trunk/setup.py
  A   z3c.builder.core/trunk/src/
  A   z3c.builder.core/trunk/src/z3c/
  A   z3c.builder.core/trunk/src/z3c/__init__.py
  A   z3c.builder.core/trunk/src/z3c/builder/
  A   z3c.builder.core/trunk/src/z3c/builder/__init__.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/
  A   z3c.builder.core/trunk/src/z3c/builder/core/README.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/__init__.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/base.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/buildout.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/buildout.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.dot
  A   z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.png
  A   z3c.builder.core/trunk/src/z3c/builder/core/example.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__namespace.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/add-form.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/bootstrap.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/buildout.cfg
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/edit-form.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/gpl3-header.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/proprietary-header.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/setup.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.pt
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zboiler-doc-header.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zpl-header.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/form.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/form.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/index.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/interfaces.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/project.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/project.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/python.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/python.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/setup.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/setup.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/testing.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/tests/
  A   z3c.builder.core/trunk/src/z3c/builder/core/tests/__init__.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/tests/test_doc.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/trove-classifiers.txt
  A   z3c.builder.core/trunk/src/z3c/builder/core/zcml.py
  A   z3c.builder.core/trunk/src/z3c/builder/core/zcml.txt

-=-
Added: z3c.builder.core/trunk/CHANGES.txt
===================================================================
--- z3c.builder.core/trunk/CHANGES.txt	                        (rev 0)
+++ z3c.builder.core/trunk/CHANGES.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,8 @@
+=======
+CHANGES
+=======
+
+Version 0.1.0 (2009-03-27)
+--------------------------
+
+- Initial Release


Property changes on: z3c.builder.core/trunk/CHANGES.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/README.txt
===================================================================
--- z3c.builder.core/trunk/README.txt	                        (rev 0)
+++ z3c.builder.core/trunk/README.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,124 @@
+======================================
+The Zope 3 Community's Project Builder
+======================================
+
+z3c.builder is a tool that helps you jump start development of a Zope
+3 application by generating all the boiler plate code and
+configuration for you.
+
+Goals
+-----
+
+ * Easy to use
+ * Easy to extend
+ * More or less complete
+
+
+Brainstorming
+-------------
+
+The easiest thing to tackle is just generating all the files that are
+needed without necessarily any customizable contents.  A minimal eggs
+and buildout based project would have a directory structure like this::
+
+  package-name/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    README.txt
+    CHANGES.txt
+    src/
+      namespace-package/
+        __init__.py
+        package/
+          __init__.py
+
+Each section of this directory structure can be further configured ad
+infinitum.  The tricky part is deciding when enough is enough.  Let's
+consider each of these sections and what they offer.
+
+bootstrap.py
+~~~~~~~~~~~~
+
+This is brain dead simple.  There is a standard file that everyone
+uses and we just need to copy it in.  I don't think there is any
+potential customization points.
+
+
+buildout.cfg
+~~~~~~~~~~~~
+
+There are pretty much an infinite number of generic customizations you
+can make to a buildout.cfg file.  Here are some of the ones we might
+want to support out of the box:
+
+  - Creation of multiple buildout.cfg files, for different uses
+    (developers, production, minimal?)
+
+  - kgs hookup, with support for using a remote extends buildout
+    option, or downloading a versions.cfg file upon project creation.
+
+  - Some typically used and useful parts:
+    - tests
+    - coverage
+    - python interpreter
+    - ctags
+    - documentation generators
+
+    (note that some of these parts require additional files to be
+     added to the src tree in order to make sense)
+
+  - Zope Server setup.
+    This bleeds into all the zope 3 configuration that we might
+    want to do and also paster setup.  This would include basically
+    anything you can configure in zope.conf files.
+
+setup.py
+~~~~~~~~
+
+This is relatively straight forward.  There are the obvious keyword
+arguments that are passed to the setup() command that we'll want to
+configure. There are however some slightly more interesting peices:
+
+  - long_description: Since this is what becomes the python page,
+    we'll want to hook up the boiler plate code for using a
+    combination of README.txt, CHANGES.txt and others to generate the
+    full long description.  This shouldn't be that hard.
+
+  - classifiers: It's always a pain in the ass to remember what all
+    the different classifiers can be and how they should be
+    formatted.
+
+  - extras_requires: we may want to configure what extras_requires
+    sections there are.  Typically we would have a test and an app
+    section. There might also be a docs section and others.
+
+  - entry_points: this is where it gets a bit trickier.  Paster has
+    it's own entry point boiler plate code that you need.  We may also
+    want to configure any number of additonal command line script
+    entry points.
+
+README.txt
+~~~~~~~~~~
+
+Just a simple file dump with maybe some configurable initial content.
+
+CHANGES.txt
+~~~~~~~~~~~
+
+Another simple file dump with an example of the change log format that
+we've standardized on.
+
+Other Python Files
+~~~~~~~~~~~~~~~~~~
+
+The rest of the files are just for mkaing proper python modules and
+should be brain dead simple.
+
+Conclusion
+~~~~~~~~~~
+
+I think starting by making a project builder for simple egg/buildout
+based projects is a good starting point.  It's an atainable and useful
+goal which will give us the experience we need to tackle the more
+complex task of zope boiler plate.


Property changes on: z3c.builder.core/trunk/README.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/assumptions.txt
===================================================================
--- z3c.builder.core/trunk/assumptions.txt	                        (rev 0)
+++ z3c.builder.core/trunk/assumptions.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,17 @@
+===========
+Assumptions
+===========
+
+In order to make this a successful tool that can be implemented in a decent
+amount of time, we need to make some hard assumptions that restrict the scope.
+
+- Do not support any possible configuration.
+
+- Only support WSGI setups.
+
+- Support paster setups only (?)
+
+- only support z3c.form (for now)
+
+- all references should be by string, so that we do nto create insane
+  dependency trees.


Property changes on: z3c.builder.core/trunk/assumptions.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/bootstrap.py
===================================================================
--- z3c.builder.core/trunk/bootstrap.py	                        (rev 0)
+++ z3c.builder.core/trunk/bootstrap.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)


Property changes on: z3c.builder.core/trunk/bootstrap.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/buildout.cfg
===================================================================
--- z3c.builder.core/trunk/buildout.cfg	                        (rev 0)
+++ z3c.builder.core/trunk/buildout.cfg	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,45 @@
+[buildout]
+extends=http://download.zope.org/zope3.4/3.4.0/versions.cfg
+develop = .
+parts = test
+        coverage-test
+        coverage-report
+        python
+        gtkeggdeps
+        docs
+versions = versions
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.builder.core [test]
+
+[coverage-test]
+recipe = zc.recipe.testrunner
+eggs = z3c.builder.core [test]
+defaults = ['--coverage', '../../coverage']
+
+[coverage-report]
+recipe = zc.recipe.egg
+eggs = z3c.coverage
+scripts = coverage=coverage-report
+arguments = ('coverage', 'coverage/report')
+
+[python]
+recipe = zc.recipe.egg
+interpreter = python
+eggs = z3c.builder.core
+
+[gtkeggdeps]
+recipe = zc.recipe.egg
+scripts = gtkeggdeps
+eggs = gtkeggdeps
+       z3c.builder.core
+
+[docs]
+recipe = z3c.recipe.sphinxdoc
+eggs = z3c.recipe.sphinxdoc
+       z3c.builder.core [docs]
+default.css =
+layout.html =
+doc-eggs = z3c.builder.core
+build-dir = ${buildout:directory}/docs

Added: z3c.builder.core/trunk/design.txt
===================================================================
--- z3c.builder.core/trunk/design.txt	                        (rev 0)
+++ z3c.builder.core/trunk/design.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,198 @@
+======
+Design
+======
+
+Challenge
+---------
+
+There exists a natural impedence mismatch between the setup necessary to start
+a zope 3 application and the level and detail of information that a new user
+is willing or able to give.
+
+Solution
+--------
+
+`z3c.builder` will attempt to bridge that mismatch by generating functional
+Zope 3 applications from high-level feature descriptions. The user will, with
+the help of some UI (CLI or Web page), create an XML file with formal
+descriptions of the features. See `sample-project.xml`. The software will then
+process this XML file to produce an internal representation of the
+project. That internal representation is then used to render the action
+source.
+
+UI -> Feature XML -> Project Object -> Project Soruce
+
+The main purpose of `z3c.builder` is to convert the feature XML to the project
+object.
+
+Details
+-------
+
+Two models:
+
+- Project Definition
+
+  The project definition is a Python representation of the XML file
+
+- Project
+
+  The Python object representing the actual code to be generated.
+
+
+ProjectDefinition
+  name
+  features = []
+  update(project)
+
+Feature
+  interface
+  dependencies = ()
+  update(project)
+
+---
+
+Project
+  name
+  setup --> setup.py content
+  buildout --> buildout.cfg content
+  package
+  render(directory)
+
+Package
+  interfaces --> interfaces
+  content --> content classes
+  classes --> other classes
+  configuration --> list of configuration directives
+  subPackages --> list of sub-packages
+
+Note: Key is naming conventions.
+
+Example
+-------
+
+The goal is to create a simple "Hello World" CRUD application.
+
+Initialize project with minimal amount of data.
+
+  >>> from z3c.builder import project
+  >>> hw = project.ProjectBuilder('helloworld')
+
+  >>> hw.setup.version = '0.1.0'
+  >>> hw.setup.license = 'ZPL 2.1'
+
+At this point, the project should render, but nothing very useful is produced.
+
+Let's add some buildout configuration. First we set the KGS version:
+
+  >>> hw.buildout.sections['buildout'].extends = 'versions-3.4.0.cfg'
+
+Next we create the necessary sections for a Zope 3 application:
+
+  >>> from z3c.builder import buildout
+  >>> hw.buildout.sections.add(buildout.SectionBuilder('zope3'))
+  >>> hw.buildout.sections['zope3'].location = '.'
+
+  >>> hw.buildout.sections.add(buildout.SectionBuilder('app'))
+  >>> hw.buildout.sections['app'].recipe = 'zc.zope3recipes:app'
+  >>> hw.buildout.sections['app'].site_zcml = '<include package="hell .../>'
+  >>> hw.buildout.sections['app'].eggs = 'helloworld'
+
+  >>> hw.buildout.sections.add(buildout.SectionBuilder('hw'))
+  >>> hw.buildout.sections['hw'].recipe = 'zc.zope3recipes:instance'
+  >>> hw.buildout.sections['hw'].application = 'app'
+  >>> hw.buildout.sections['hw'].zope_conf = ${database:zconfig}'
+
+  >>> hw.buildout.sections.add(buildout.SectionBuilder('database'))
+  >>> hw.buildout.sections['database'].recipe = 'zc.recipe.filestorage'
+
+At this point the project should render and produce a working Zope 3 server.
+
+Let's now create a simple hello world content object and its CRUD
+forms. First, we need to create an interface:
+
+  >>> from z3c.builder import iface
+  >>> # could be even the real iface class.
+  >>> ihw = iface.InterfaceBuilder('IHelloWorld')
+  >>> ihw['who'] = iface.TextLine()
+  >>> ihw['when'] = iface.Datetime()
+  >>> ihw['what'] = iface.Choice(values=['sunny', 'quiet', 'nice'])
+
+  >>> hw.package.interfaces.add(ihw)
+
+Next we create a content class:
+
+  >>> from z3c.builder import content
+  >>> chw = content.ContentClass('HelloWorld')
+  >>> chw.interface = 'IHelloWorld'
+  >>> chw.inheritsFrom = ('persistent.Persistent', 'zope.location.Location')
+
+  >>> hw.package.classes.add(chw)
+
+We also need to declare security:
+
+  >>> from z3c.builder import security
+  >>> sec = security.SecurityBuilder('HelloWorld')
+  >>> sec.allow(schema='IHelloWorld')
+  >>> sec.allow(setSchema='IHelloWorld')
+
+  >>> hw.package.configuration.add(sec)
+
+Let's now create the forms. First we need to create an add form:
+
+  >>> from z3c.builder import form
+  >>> addForm = form.AddFormBuilder('HelloWorldAddForm')
+  >>> addForm.interface = 'IHelloWorld'
+  >>> addForm.fields = ('who', 'when', 'what')
+  >>> addForm.factory = 'HelloWorld'
+  >>> addForm.visitAfterCreation = True
+
+  >>> hw.package.subPackages['browser'].classes.add(addForm)
+
+  >>> from z3c.builder import page
+  >>> addReg = page.PageRegistrationBuilder()
+  >>> addReg.name = 'add.html'
+  >>> addReg.view = 'HelloWorldAddForm'
+  >>> addReg.permission = 'zope.Public' # should be default
+
+  >>> hw.package.subPackages['browser'].configuration.add(addReg)
+
+Next is the simple display form.
+
+  >>> displayForm = form.DisplayFormBuilder('HelloWorldDusplayForm')
+  >>> displayForm.interface = 'IHelloWorld'
+  >>> displayForm.fields = ('who', 'when', 'what')
+  >>> displayForm.simpleTemplate = \
+  ...     'A ${what} Hello World from ${who} on ${when}.'
+  >>> displayForm.linkToAddForm = 'add.html'
+  >>> displayForm.linkToEditForm = 'edit.html'
+
+  >>> hw.package.subPackages['browser'].classes.add(displayForm)
+
+  >>> displayReg = page.PageRegistrationBuilder()
+  >>> displayReg.name = 'index.html'
+  >>> displayReg.view = 'HelloWorldDisplayForm'
+
+  >>> hw.package.subPackages['browser'].configuration.add(displayReg)
+
+Finally the edit form.
+
+  >>> editForm = form.EditFormBuilder('HelloWorldEditForm')
+  >>> editForm.interface = 'IHelloWorld'
+  >>> editForm.fields = ('who', 'when', 'what')
+  >>> editForm.linkAfterEdit = 'index.html'
+
+  >>> hw.package.subPackages['browser'].classes.edit(editForm)
+
+  >>> editReg = page.PageRegistrationBuilder()
+  >>> editReg.name = 'edit.html'
+  >>> editReg.view = 'HelloWorldEditForm'
+
+  >>> hw.package.subPackages['browser'].configuration.edit(editReg)
+
+If we now render the project, we should have a fully functional package:
+
+  >>> import os
+  >>> import tempfile
+  >>> dir = os.path.join(tempfile.mkdtemp(), 'hw')
+
+  >>> hw(dir)


Property changes on: z3c.builder.core/trunk/design.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/sample-project.xml
===================================================================
--- z3c.builder.core/trunk/sample-project.xml	                        (rev 0)
+++ z3c.builder.core/trunk/sample-project.xml	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,124 @@
+<project name="z3c.sampleproject">
+
+  <feature type="z3c.feature.core:meta-data">
+    <license>ZPL</license>
+    <version>0.1.0</version>
+    <author>Paul Carduner and Stephan Richter</author>
+    <author-email>zope-dev at zope.org</author-email>
+    <description>A utility to help jump start Zope 3 projects</description>
+    <license>ZPL 2.1</license>
+    <keywords>zope3 project builder</keywords>
+    <url>http://pypi.python.org/pypi/z3c.builder</url>
+    <namespace-packages>z3c</namespace-packages>
+    <feature type="z3c.feature.core:comment-header-ZPL">
+      <year>2009</year>
+    </feature>
+
+  </feature>
+
+  <feature type="z3c.feature.core:python-interpreter">
+    <executableName>py</executableName>
+  </feature>
+
+  <feature type="z3c.feature.core:unit-testing"/>
+  <feature type="z3c.feature.core:script"/>
+  <feature type="z3c.feature.core:documentation"/>
+
+  <!--feature type="z3c.builder:application">
+    <database type="zodb">
+      <name>main</name>
+      <storage type="filestorage">
+        <file>Data.fs</file>
+      </storage>
+    </database>
+  </feature-->
+
+  <!--feature type="z3c.builder:server">
+    <server>zope.server</server>
+    <port>8080</port>
+    <interface>0.0.0.0</interface>
+  </feature-->
+
+  <!--feature type="z3c.builder:test">
+    <functional-layer name="SPLayer" zcml="ftesting.zcml" />
+  </feature-->
+
+  <!--feature type="z3c.builder:coverage">
+    <script-name>coverage</script-name>
+    <directory>coverage</directory>
+  </feature-->
+
+  <!--feature type="z3c.builder:importchecker">
+    <script-name>check</script-name>
+  </feature-->
+
+  <!--feature type="z3c.builder:package">
+    <name>z3c.rml</name>
+    <version>0.7.3</version>
+  </feature-->
+
+  <!-- Simple Hello World Example -->
+
+  <!--feature type="z3c.builder:page">
+    <name>hello-world.html</name>
+    <!- - By default the template, some sample content and view class is
+          created by default. - ->
+  </feature-->
+
+  <!-- Simple Content Component with CRUD -->
+
+  <!--feature type="z3c.builder:skin" name="hw-skin">
+    <name>hw</name>
+  </feature-->
+
+  <!--feature type="z3c.builder:simple-content-crud" depends-on="hw-skin">
+    <content>
+      <name>HelloWorld</name>
+      <schema>
+        <field name="who" type="TextLine" />
+        <field name="when" type="Date" />
+        <field name="what" type="Choice">
+          <choices>
+            <choice name="cool">cool</choice>
+            <choice name="sunny">sunny</choice>
+            <choice name="silent">silent</choice>
+            <choice name="best">best</choice>
+          </choices>
+        </field>
+      </schema>
+    </content>
+    <!- - Optional - ->
+    <forms type="z3c.builder:z3c.form">
+      <skin>hw</skin>
+    </forms>
+  </feature-->
+
+  <!-- OR -->
+
+  <!--feature type="z3c.builder:content">
+    <name>HelloWorld</name>
+    <schema>
+      <field name="who" type="TextLine" />
+      <field name="when" type="Date" />
+      <field name="what" type="Choice">
+        <choices>
+          <choice name="cool">cool</choice>
+          <choice name="sunny">sunny</choice>
+          <choice name="silent">silent</choice>
+          <choice name="best">best</choice>
+        </choices>
+      </field>
+    </schema>
+  </feature-->
+
+  <!--feature type="z3c.builder:form-crud" depends-on="content">
+    <content>HelloWorld</content>
+    <skin>hw-skin</skin>
+    <fields>
+      <field>who</field>
+      <field>when</field>
+      <field>what</field>
+    </fields>
+  </feature-->
+
+</project>


Property changes on: z3c.builder.core/trunk/sample-project.xml
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/setup.py
===================================================================
--- z3c.builder.core/trunk/setup.py	                        (rev 0)
+++ z3c.builder.core/trunk/setup.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,64 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup
+
+$Id$
+"""
+import os
+import xml.sax.saxutils
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    text = open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+    text = unicode(text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
+    return xml.sax.saxutils.escape(text)
+
+setup (
+    name='z3c.builder.core',
+    version='0.1.0',
+    author = "Paul Carduner, Stephan Richter, and hopefully others...",
+    author_email = "zope-dev at zope.org",
+    description = "A utility to help jump start Zope 3 projects",
+    long_description=(
+        read('README.txt')
+        +"\n\n"+
+        read('CHANGES.txt')
+        ),
+    license = "ZPL 2.1",
+    keywords = "zope3 project builder",
+    url = 'http://pypi.python.org/pypi/z3c.builder.core',
+    packages = find_packages('src'),
+    include_package_data = True,
+    package_dir = {'':'src'},
+    namespace_packages = ['z3c'],
+    extras_require = dict(
+        test = [
+            'zope.testing',
+            'z3c.coverage',
+            ],
+        docs = ['Sphinx'],
+        ),
+    install_requires = [
+        'rwproperty',
+        'setuptools',
+        'zc.buildout',
+        'zope.component',
+        'zope.configuration',
+        'zope.container',
+        'zope.interface',
+        'zope.schema',
+        'lxml',
+        ],
+    zip_safe = False,
+    )


Property changes on: z3c.builder.core/trunk/setup.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/__init__.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/__init__.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/__init__.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,7 @@
+try:
+    # Declare this a namespace package if pkg_resources is available.
+    import pkg_resources
+    pkg_resources.declare_namespace(__name__)
+except ImportError:
+    pass
+


Property changes on: z3c.builder.core/trunk/src/z3c/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/__init__.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/__init__.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/__init__.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,7 @@
+try:
+    # Declare this a namespace package if pkg_resources is available.
+    import pkg_resources
+    pkg_resources.declare_namespace(__name__)
+except ImportError:
+    pass
+


Property changes on: z3c.builder.core/trunk/src/z3c/builder/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/README.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/README.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/README.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,187 @@
+==========================
+The Zope 3 Project Builder
+==========================
+
+The Zope 3 Project Builder was designed to interpret a high-level feature list
+into a functional Python project. This package implements the code generation
+pieces without worrying about the high-level features.
+
+This package uses the concept of builders to construct a new project. The
+process of building consists of two phases: (1) updating, and (2)
+rendering/writing. Only (1) is well-defined at the fundamental level. In
+addition, every builder *must* have a name.
+
+  >>> from z3c.builder.core import base
+  >>> builder = base.BaseBuilder(u'myBuilder')
+  >>> builder
+  <BaseBuilder u'myBuilder'>
+
+  >>> builder.name
+  u'myBuilder'
+  >>> builder.update()
+  Updating <BaseBuilder u'myBuilder'>
+
+Builders often use sub-builders to complete the rendering. So another
+important base class is the builder container:
+
+  >>> container = base.BuilderContainer(u'myContainer')
+  >>> container.add(builder)
+  u'myBuilder'
+
+  >>> container.update()
+  Updating <BuilderContainer u'myContainer'>
+  Updating <BaseBuilder u'myBuilder'>
+
+  >>> container.remove(builder)
+  >>> container.keys()
+  []
+
+It is also an ordered container:
+
+  >>> container.add(base.BaseBuilder(u'n1'))
+  u'n1'
+  >>> container.add(base.BaseBuilder(u'n2'))
+  u'n2'
+
+  >>> container.keys()
+  [u'n1', u'n2']
+  >>> container.updateOrder([u'n2', u'n1'])
+  >>> container.keys()
+  [u'n2', u'n1']
+
+
+Rendering versus Writing
+------------------------
+
+Beyond the base builder, there are two types of builders, the ones that render
+content and the ones the write files/directories.
+
+The basic content rendering builder is named `ContentBuilder`.
+
+  >>> content = base.ContentBuilder(u'content')
+  >>> content
+  <ContentBuilder u'content'>
+
+Every content builder must implement the `render()` method:
+
+  >>> content.render()
+  Traceback (most recent call last):
+  ...
+  NotImplementedError: The `render()` method is not implemented by
+                       <ContentBuilder u'content'>.
+
+As you can see the `ContentBuilder` class is meant to be used as a base class.
+
+Let's now look at builders that write files. They are known as filesystem
+builders.
+
+  >>> fs = base.FilesystemBuilder(u'fs')
+  >>> fs
+  <FilesystemBuilder u'fs'>
+
+Every filesystem builder must implement the `write(target)` method, where the
+target is a path to the directory the builder is writing to.
+
+  >>> fs.write(buildPath)
+  Traceback (most recent call last):
+  ...
+  NotImplementedError: The `write(target)` method is not implemented.
+
+There are two implementations of the filesystem builder, the
+`DirectoryBuilder` and the `FileBuilder` class.
+
+The name of the directory builder is used as the initial directory name that
+it creates.
+
+  >>> dir = base.DirectoryBuilder(u'myDir')
+  >>> dir
+  <DirectoryBuilder u'myDir'>
+  >>> dir.dirname
+  'myDir'
+
+When the builder is written, it creates the directory.
+
+  >>> dir.update()
+  Updating <DirectoryBuilder u'myDir'>
+  >>> dir.write(buildPath)
+  Creating directory .../myDir
+
+The name of the file builder is used to create the filename as well.
+
+  >>> file = base.FileBuilder(u'myFile.txt')
+  >>> file
+  <FileBuilder u'myFile.txt'>
+  >>> file.filename
+  'myFile.txt'
+
+When the builder is written, it creates the file. It turns out that the file
+builder is both, a filesystem and content builder.
+
+  >>> file.update()
+  Updating <FileBuilder u'myFile.txt'>
+
+  >>> file.write(buildPath)
+  Traceback (most recent call last):
+  ...
+  NotImplementedError: The `render()` method is not implemented.
+
+So, the `render()` method is not implemented. However, there is a simple file
+builder that creates files based on a template file.
+
+  >>> import os
+  >>> template = os.path.join(buildPath, 'template.txt')
+  >>> open(template, 'w').write('File Contents')
+
+  >>> file = base.SimpleFileBuilder(u'rendered.txt', template)
+  >>> file.update()
+  Updating <SimpleFileBuilder u'rendered.txt'>
+  >>> file.write(buildPath)
+  Creating file .../rendered.txt
+
+Let's now look at the generated file.
+
+  >>> more(buildPath, 'rendered.txt')
+  File Contents
+
+Those are all the basic builders. In the "Specific Builders" section below you
+can find a list of documents that document the fully implemented
+builders. Those builders can be used to build full projects.
+
+
+Builder Classes Layout
+----------------------
+
+A layout (UML class diagram) of all builder classes can be found at::
+
+  ./class-diagram.png
+
+All green classes can be used directly for building a project. Yellow and red
+classes are meant to be used as abstract builder classes.
+
+
+Specific Builders
+-----------------
+
+- ``project.txt``
+
+  Documents the project builder, the most upper-level builder.
+
+- ``python.txt``
+
+  Documents and demonstrates builders that produce Python code.
+
+- ``setup.txt``
+
+  Documents the setup builder which generates the `setup.py` file.
+
+- ``buildout.txt``
+
+  Documents the buidlout builder that generates the ``buildout.cfg`` file.
+
+- ``zcml.txt``
+
+  Documents the generation of ZCML directives.
+
+- ``form.txt``
+
+  Documents the builders for `z3c.form`-based forms.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/README.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/__init__.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/__init__.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/__init__.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1 @@
+#package


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/base.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/base.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/base.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,159 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Base Builder Components
+
+$Id$
+"""
+import logging
+import os
+import uuid
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+from zope.container import contained, ordered
+from z3c.builder.core import interfaces
+
+formatter = logging.Formatter('%(levelname)s - %(message)s')
+logger = logging.getLogger('info')
+
+def getTemplatePath(fn):
+    return os.path.join(os.path.dirname(__file__), 'file-templates', fn)
+
+def getUUID():
+    return str(uuid.uuid4())
+
+class ProjectGetter(object):
+    zope.interface.implements(interfaces.IProjectGetter)
+
+    def getProject(self):
+        project = self
+        while not interfaces.IProjectBuilder.providedBy(project):
+            project = project.__parent__
+            if project is None:
+                raise ValueError(
+                    'No project builder was found and the root node of '
+                    'the project tree was reached.')
+        return project
+
+
+class BaseBuilder(contained.Contained):
+    zope.interface.implements(interfaces.IBaseBuilder)
+
+    name = FieldProperty(interfaces.IBaseBuilder['name'])
+
+    def __init__(self, name):
+        self.name = name
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        logger.debug("Updating %s" %self)
+
+    def __repr__(self):
+        return '<%s %r>' %(self.__class__.__name__, self.name)
+
+
+class BuilderContainer(BaseBuilder, ordered.OrderedContainer):
+    zope.interface.implements(interfaces.IBuilderContainer)
+
+    def __init__(self, name):
+        super(BuilderContainer, self).__init__(name)
+        ordered.OrderedContainer.__init__(self)
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        super(BuilderContainer, self).update()
+        for subBuilder in self.values():
+            subBuilder.update()
+
+    def add(self, builder):
+        """See interfaces.IBuilderContainer"""
+        self[builder.name] = builder
+        return builder.name
+
+    def remove(self, builder):
+        """See interfaces.IBuilderContainer"""
+        del self[builder.__name__]
+
+
+class ContentBuilder(BaseBuilder, ProjectGetter):
+    zope.interface.implements(interfaces.IContentBuilder)
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        raise NotImplementedError(
+            "The `render()` method is not implemented by %s." %self)
+
+
+class FilesystemBuilder(BaseBuilder, ProjectGetter):
+    zope.interface.implements(interfaces.IFilesystemBuilder)
+
+    def write(self, target):
+        """See interfaces.IFilesystemBuilder"""
+        raise NotImplementedError(
+            "The `write(target)` method is not implemented.")
+
+
+class DirectoryBuilder(FilesystemBuilder, BuilderContainer):
+    zope.interface.implements(interfaces.IDirectoryBuilder)
+
+    dirname = FieldProperty(interfaces.IDirectoryBuilder['dirname'])
+
+    def __init__(self, name, dirname=None):
+        super(DirectoryBuilder, self).__init__(name)
+        # Use the builder name as the default directory name.
+        if dirname is None:
+            dirname = str(name)
+        self.dirname = dirname
+
+    def write(self, target):
+        """See interfaces.IFilesystemBuilder"""
+        dirpath = os.path.join(target, self.dirname)
+        logger.info("Creating directory %s" % dirpath)
+        os.mkdir(dirpath)
+        for subBuilder in self.values():
+            subBuilder.write(dirpath)
+
+
+class FileBuilder(FilesystemBuilder):
+    zope.interface.implements(interfaces.IFileBuilder)
+
+    filename = FieldProperty(interfaces.IFileBuilder['filename'])
+
+    def __init__(self, name, filename=None):
+        super(FileBuilder, self).__init__(name)
+        if filename is None:
+            filename = str(name)
+        self.filename = filename
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        raise NotImplementedError("The `render()` method is not implemented.")
+
+    def write(self, target):
+        """See interfaces.IFilesystemBuilder"""
+        filepath = os.path.join(target, self.filename)
+        logger.info("Creating file %s" % filepath)
+        file = open(filepath, 'w')
+        file.write(self.render())
+        file.close()
+
+
+class SimpleFileBuilder(FileBuilder):
+
+    def __init__(self, name, template, filename=None):
+        super(SimpleFileBuilder, self).__init__(name, filename)
+        self.template = template
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        return open(self.template, 'r').read()


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/base.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/buildout.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/buildout.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/buildout.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,85 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Buildout Configuration Builder
+
+$Id$
+"""
+import os
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+from z3c.builder.core import base, interfaces
+
+class PartBuilder(base.ContentBuilder):
+    zope.interface.implements(interfaces.IPartBuilder)
+
+    values = FieldProperty(interfaces.IPartBuilder['values'])
+    autoBuild = FieldProperty(interfaces.IPartBuilder['autoBuild'])
+
+    def __init__(self, name, values=None, autoBuild=True):
+        super(PartBuilder, self).__init__(name)
+        if values is None:
+            values = []
+        self.values = list(values)
+        self.autoBuild = autoBuild
+
+    def addValue(self, key, value):
+        self.values.append((key, value))
+
+    def removeValue(self, key):
+        for item in self.values:
+            if item[0] == key:
+                self.values.remove(item)
+                return
+
+    def render(self):
+        output = ''
+        output += '[%s]\n' %self.name
+        for key, value in self.values:
+            output += '%s = %s\n' %(key, value)
+        return output
+
+
+class BuildoutConfigBuilder(base.BuilderContainer, base.FileBuilder):
+    zope.interface.implements(interfaces.IBuildoutConfigBuilder)
+
+    extends = FieldProperty(interfaces.IBuildoutConfigBuilder['extends'])
+    names = FieldProperty(interfaces.IBuildoutConfigBuilder['names'])
+
+    def __init__(self):
+        super(BuildoutConfigBuilder, self).__init__(u'buildout.cfg')
+        self.extends = [u'http://download.zope.org/zope3.4/3.4.0/versions.cfg']
+        self.names = []
+
+    def update(self):
+        self.names = [part.name for part in self.values()
+                      if part.autoBuild]
+        for part in self.values():
+            part.update()
+
+    def render(self):
+        output = ''
+        output += '[buildout]\n'
+        output += 'extends = %s\n' %('   \n'.join(self.extends))
+        output += 'develop = .\n'
+        output += 'parts = %s\n' %' '.join(self.names)
+        output += 'versions = versions\n'
+        if len(self):
+            output += '\n'
+        for part in self.values():
+            output += part.render()
+            output += '\n'
+        return output
+
+    def __repr__(self):
+        return '<%s for %r>' %(self.__class__.__name__, self.getProject().name)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/buildout.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/buildout.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/buildout.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/buildout.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,93 @@
+==============================
+Buildout Configuration Builder
+==============================
+
+The buildout configuration builder creates the `buildout.cfg` file, which
+drives the behavior of `zc.buildout`. Buildout is a software building and
+deployment tool, similar to `make` and `ant`.
+
+  >>> from z3c.builder.core import buildout, interfaces
+  >>> builder = buildout.BuildoutConfigBuilder()
+
+This object provides the ``IBuildoutConfigBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IBuildoutConfigBuilder, builder)
+  True
+
+Like most builders, this builder also expects to be able to reach its project
+builder:
+
+  >>> from z3c.builder.core import project
+  >>> builder.__parent__ = project.ProjectBuilder(u'z3c.myproject')
+  >>> builder
+  <BuildoutConfigBuilder for u'z3c.myproject'>
+
+One of the important global settings is the list of other buildout
+configuration this one extends. By default it points to the versions of the
+latest stable set of packages:
+
+  >>> builder.extends
+  [u'http://download.zope.org/zope3.4/3.4.0/versions.cfg']
+
+There is also a `names` attribute that lists all the part names that should be
+automatically build. But first we need some parts.
+
+  >>> part = buildout.PartBuilder(u'python')
+  >>> part
+  <PartBuilder u'python'>
+
+Let's now add some values to the part.
+
+  >>> part.addValue(u'recipe', 'zc.recipe.egg')
+  >>> part.addValue(u'interpreter', 'python')
+  >>> part.addValue(u'eggs', 'myproject')
+  >>> part.addValue(u'foo', 'bar')
+
+Unfortunately, the last value was unwanted, so let's remove it again.
+
+  >>> part.removeValue('foo')
+
+Now, we can also specify whether a part should be built whenever buildout is
+run:
+
+  >>> part.autoBuild
+  True
+
+Let's now render the part:
+
+  >>> part.update()
+  >>> print part.render()
+  [python]
+  recipe = zc.recipe.egg
+  interpreter = python
+  eggs = myproject
+  <BLANKLINE>
+
+We can now add the part to the buildout configuration and update it:
+
+  >>> builder.add(part)
+  u'python'
+  >>> builder.update()
+
+Since auto-build is turned on for the part, the builder now has it in its
+list:
+
+  >>> builder.names
+  [u'python']
+
+Okay, enough of the details. Here is the rendered builder:
+
+  >>> print builder.render()
+  [buildout]
+  extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+  develop = .
+  parts = python
+  versions = versions
+  <BLANKLINE>
+  [python]
+  recipe = zc.recipe.egg
+  interpreter = python
+  eggs = myproject
+
+And that's it.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/buildout.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.dot
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.dot	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.dot	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,188 @@
+digraph Z3cBuilderClassDiagram {
+  nodesep=0.3;
+  ranksep=0.9;
+
+  fontname = "Bitstream Vera Sans"
+  fontsize = 8
+
+  node [
+    fontname = "Bitstream Vera Sans"
+    fontsize = 8
+    shape = "record"
+  ];
+  edge [
+    fontname = "Bitstream Vera Sans"
+    fontsize = 8
+    arrowhead = "empty"
+  ]
+
+  OrderedContainer [
+      label = "{OrderedContainer}"
+  ];
+  BuilderContainer [
+      label = "{BuilderContainer|add(builder)\lremove(builder)}"
+      style = filled
+      fillcolor = "#FF000033"
+  ];
+  Contained [
+      label = "{Contained|object : __parent__\lunicode : __name__}"
+  ];
+
+  PythonPathGetter [
+      label = "{PythonPathGetter|getPythonPath()}"
+      style = filled
+      fillcolor = "#0000FF33"
+  ];
+  ProjectGetter [
+      label = "{ProjectGetter|getProject()}"
+      style = filled
+      fillcolor = "#0000FF33"
+  ];
+
+
+  BaseBuilder [
+      label = "{BaseBuilder|unicode : name|update()}"
+      style = filled
+      fillcolor = "#FF000033"
+  ];
+
+  FilesystemBuilder [
+      label = "{FilessytemBuilder|write(target)}"
+      style = filled
+      fillcolor = "#FFFF0033"
+  ];
+
+  ContentBuilder [
+      label = "{ContentBuilder|render()}"
+      style = filled
+      fillcolor = "#FFFF0033"
+  ];
+
+  DirectoryBuilder [
+      label = "{DirectoryBuilder|str : dirname}"
+      style = filled
+      fillcolor = "#FFFF0033"
+  ];
+  FileBuilder [
+      label = "{FileBuilder|str : filename}"
+      style = filled
+      fillcolor = "#FFFF0033"
+  ];
+
+  ClassBuilder [
+      label = "{ClassBuilder}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  InterfaceBuilder [
+      label = "{InterfaceBuilder}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  BuildoutPartBuilder [
+      label = "{BuildoutPartBuilder}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+
+  ProjectBuilder [
+      label = "{ProjectBuilder|str : projectName|write(target, force=False)}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  SrcDirectoryBuilder [
+      label = "{SrcDirectoryBuilder}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  PackageBuilder [
+      label = "{PackageBuilder|str : packageName\lpath : initTemplate}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  NamespacePackageBuilder [
+      label = "{NamespacePackageBuilder}"
+      style = filled
+      fillcolor = "#00FF0066"
+  ];
+
+  SimpleFileBuilder [
+      label = "{SimpleFileBuilder|str : template}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  ModuleBuilder [
+      label = "{ModuleBuilder|str : moduleName\llist : imports}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  SetupFileBuilder [
+      label = "{SetupFileBuilder}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  BuildoutFileBuilder [
+      label = "{BuildoutFileBuilder}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+  ZCMLFileBuilder [
+      label = "{ZCMLFileBuilder|list : namespaces}"
+      style = filled
+      fillcolor = "#00FF0033"
+  ];
+
+  BuildoutProjectBuilder [
+      label = "{BuildoutProjectBuilder|PackageBuilder : package \lSetupFileBuilder : setup \lBuildoutFileBuilder : buildout}"
+      style = filled
+      fillcolor = "#00FF0066"
+  ];
+
+  BaseBuilder -> Contained;
+  BuilderContainer -> OrderedContainer;
+  BuilderContainer -> BaseBuilder;
+
+  FilesystemBuilder -> BaseBuilder;
+  ContentBuilder -> BaseBuilder;
+
+  FilesystemBuilder -> ProjectGetter;
+  ContentBuilder -> ProjectGetter;
+
+  DirectoryBuilder -> FilesystemBuilder;
+  FileBuilder -> FilesystemBuilder;
+  FileBuilder -> ContentBuilder;
+
+  ClassBuilder -> ContentBuilder;
+  InterfaceBuilder -> ContentBuilder;
+  BuildoutPartBuilder -> ContentBuilder;
+
+  ProjectBuilder -> DirectoryBuilder;
+  SrcDirectoryBuilder -> DirectoryBuilder;
+  PackageBuilder -> DirectoryBuilder;
+
+  SimpleFileBuilder -> FileBuilder;
+  ModuleBuilder -> FileBuilder;
+  SetupFileBuilder -> FileBuilder;
+  BuildoutFileBuilder -> FileBuilder;
+  ZCMLFileBuilder -> FileBuilder;
+
+  BuildoutProjectBuilder -> ProjectBuilder;
+
+  PackageBuilder -> PythonPathGetter;
+  ModuleBuilder -> PythonPathGetter;
+
+  DirectoryBuilder -> BuilderContainer;
+  ModuleBuilder -> BuilderContainer;
+  BuildoutFileBuilder -> BuilderContainer;
+  ZCMLFileBuilder -> BuilderContainer;
+
+  NamespacePackageBuilder -> PackageBuilder;
+
+  {rank=same; FileBuilder; DirectoryBuilder}
+  {rank=same; BuilderContainer; BaseBuilder}
+  {rank=same; Contained; OrderedContainer}
+//  {rank=same; PackageBuilder; ModuleBuilder; SrcDirectoryBuilder;
+//              ProjectBuilder; BuildoutFileBuilder; ZCMLFileBuilder;
+//              SimpleFileBuilder; SetupFileBuilder; BuildoutPartBuilder;
+//              ClassBuilder; InterfaceBuilder}
+}

Added: z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.png
===================================================================
(Binary files differ)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/class-diagram.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: z3c.builder.core/trunk/src/z3c/builder/core/example.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/example.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/example.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,891 @@
+=========================
+The "Hello World" Example
+=========================
+
+This document describes how to build a Zope 3 based hello world Web
+application. Without much chatter, let's get started. In the simplest case, we
+just have a plain project builder:
+
+  >>> from z3c.builder.core import interfaces, project
+  >>> builder = project.BuildoutProjectBuilder(u'helloworld')
+  >>> builder
+  <BuildoutProjectBuilder u'helloworld'>
+
+This object provides the ``IProjectBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IProjectBuilder, builder)
+  True
+
+We can now write the project to a directory of our choice.
+
+  >>> import tempfile
+  >>> buildDir = tempfile.mkdtemp()
+
+  >>> builder.update()
+  >>> builder.write(buildDir)
+
+We now have a very basic project:
+
+  >>> ls(buildDir)
+  helloworld/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      helloworld/
+        __init__.py
+
+
+Configuring the Buildout
+------------------------
+
+Initially, the buildout should be completely empty:
+
+  >>> more(buildDir, 'helloworld', 'buildout.cfg')
+  [buildout]
+  extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+  develop = .
+  parts =
+  versions = versions
+
+Let's now add a part that installs a Python interpreter:
+
+  >>> from z3c.builder.core import buildout
+  >>> part = buildout.PartBuilder(u'python')
+  >>> part.addValue(u'recipe', 'zc.recipe.egg')
+  >>> part.addValue(u'interpreter', 'python')
+  >>> part.addValue(u'eggs', builder.name)
+
+  >>> builder.buildout.add(part)
+  u'python'
+
+When rebuilding the project, the part should now be available.
+
+  >>> builder.update()
+  >>> builder.write(buildDir, True)
+
+  >>> more(buildDir, 'helloworld', 'buildout.cfg')
+  [buildout]
+  extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+  develop = .
+  parts = python
+  versions = versions
+  <BLANKLINE>
+  [python]
+  recipe = zc.recipe.egg
+  interpreter = python
+  eggs = helloworld
+
+
+Configuring the setup.py file
+-----------------------------
+
+A setup.py file is always directly associated with a project, and
+every project has one by default.
+
+    >>> builder.setup
+    <SetupBuilder for u'helloworld'>
+
+    >>> verifyObject(interfaces.ISetupBuilder, builder.setup)
+    True
+
+We can add some additional packages that we want to depend on.
+
+    >>> builder.setup.install_requires.append('zope.component')
+    >>> builder.setup.install_requires.append('zope.interface')
+    >>> builder.setup.install_requires.append('zope.container')
+
+And some other meta data:
+
+    >>> builder.setup.version = u'0.5.0dev'
+    >>> builder.setup.author = u'Paul Carduner'
+    >>> builder.setup.license = u'ZPL'
+    >>> builder.setup.author_email = u'paul at carduner.net'
+
+And also some extra specialized requirements:
+
+    >>> builder.setup.extras_require
+    {}
+    >>> builder.setup.addExtrasRequires('test', ['z3c.coverage', 'zope.testing'])
+    >>> builder.setup.addExtrasRequires('test', ['zope.app.testing'])
+    >>> builder.setup.extras_require
+    {'test': ['z3c.coverage', 'zope.testing', 'zope.app.testing']}
+
+Now we can render the setup.py file.
+
+    >>> builder.update()
+    >>> print builder.setup.render()
+    #######################################################################...
+    #
+    # This file is part of helloworld. ...
+    #
+    #######################################################################...
+    <BLANKLINE>
+    """Setup"""
+    from setuptools import setup, find_packages
+    <BLANKLINE>
+    setup (
+        name = 'helloworld',
+        version = '0.5.0dev',
+        author = u"Paul Carduner",
+        author_email = u"paul at carduner.net",
+        description = u"",
+        license = "ZPL",
+        keywords = u"",
+        url = "http://pypi.python.org/pypi/helloworld",
+        classifiers = [],
+        packages = find_packages('src'),
+        include_package_data = True,
+        package_dir = {'':'src'},
+        namespace_packages = [],
+        extras_require = {'test': ['z3c.coverage',
+               'zope.testing',
+               'zope.app.testing']},
+        install_requires = [
+            'setuptools',
+            'zope.component',
+            'zope.interface',
+            'zope.container',
+            ],
+        zip_safe = False,
+        entry_points = {},
+        )
+
+
+Rendering Interfaces
+--------------------
+
+We are now ready to generate the actual code. To do that, let's create an
+`interfaces.py` file module:
+
+  >>> from z3c.builder.core import python
+  >>> ifaces = python.ModuleBuilder(u'interfaces.py')
+  >>> builder.package['interfaces'] = ifaces
+
+Next we add a simple interface.
+
+  >>> ihw = python.InterfaceBuilder(u'IHelloWorld')
+  >>> ifaces.add(ihw)
+  u'IHelloWorld'
+
+Let's now create the project again:
+
+  >>> builder.update()
+  >>> builder.write(buildDir, True)
+
+  >>> ls(buildDir)
+  helloworld/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      helloworld/
+        __init__.py
+        interfaces.py
+
+  >>> more(buildDir, 'helloworld', 'src', 'helloworld', 'interfaces.py')
+  #######################################################################...
+  #
+  # This file is part of helloworld. ...
+  #
+  #######################################################################...
+  from zope.interface import Interface
+  <BLANKLINE>
+  class IHelloWorld(Interface):
+      """"""
+  <BLANKLINE>
+
+Next we add some fields and methods to the interface:
+
+  >>> ihw.add(python.FieldBuilder(
+  ...     name = u'who',
+  ...     type = 'zope.schema.TextLine',
+  ...     title=u'Who',
+  ...     description=u'Name of the person sending the message',
+  ...     required=True))
+  u'who'
+
+  >>> ihw.add(python.FieldBuilder(
+  ...     name = u'when',
+  ...     type = 'zope.schema.Date',
+  ...     title=u'When',
+  ...     description=u'Date of the message sent.',
+  ...     required=True))
+  u'when'
+
+  >>> ihw.add(python.FieldBuilder(
+  ...     name = u'what',
+  ...     type = 'zope.schema.Choice',
+  ...     title = u'What',
+  ...     description = u'What type of message it is.',
+  ...     values = ['cool', 'sunny', 'best'],
+  ...     default=u'cool',
+  ...     required=True))
+  u'what'
+
+  >>> ihw.add(python.FunctionBuilder(
+  ...     name = u'getMessage',
+  ...     args = (),
+  ...     kwargs = {'template':'A %(what)s world from %(who)s on %(when)s.'},
+  ...     docstring = 'Return the full hello world message'
+  ...     ))
+  u'getMessage'
+
+Now a full interface/schema should be rendered:
+
+  >>> builder.update()
+  >>> builder.write(buildDir, True)
+
+  >>> more(buildDir, 'helloworld', 'src', 'helloworld', 'interfaces.py')
+  #######################################################################...
+  #
+  # This file is part of helloworld. ...
+  #
+  #######################################################################...
+  """Module Documentation"""
+  from zope.interface import Interface
+  from zope.schema import Choice
+  from zope.schema import Date
+  from zope.schema import TextLine
+  <BLANKLINE>
+  class IHelloWorld(Interface):
+      """"""
+      who = TextLine(
+          title=u'Who',
+          description=u'Name of the person sending the message',
+          required=True,
+          )
+  <BLANKLINE>
+      when = Date(
+          title=u'When',
+          description=u'Date of the message sent.',
+          required=True,
+          )
+  <BLANKLINE>
+      what = Choice(
+          title=u'What',
+          description=u'What type of message it is.',
+          values=['cool', 'sunny', 'best'],
+          required=True,
+          default=u'cool',
+          )
+  <BLANKLINE>
+      def getMessage(template='A %(what)s world from %(who)s on %(when)s.'):
+          """Return the full hello world message"""
+
+
+Rendering Classes
+-----------------
+
+Now that we have an interface, let's create a content class for it:
+
+  >>> content = python.ModuleBuilder(u'content.py')
+  >>> builder.package.add(content)
+  u'content.py'
+
+  >>> chw = python.ClassFromInterfaceBuilder(
+  ...     name = u'HelloWorld',
+  ...     interface = 'helloworld.interfaces.IHelloWorld',
+  ...     bases = ('persistent.Persistent',
+  ...              'zope.container.contained.Contained'),
+  ...     )
+
+  >>> chw.addImplementation(
+  ...     'getMessage',
+  ...     'return template %self.__dict__')
+
+  >>> content.add(chw)
+  u'HelloWorld'
+
+Let's see what the output looks like.
+
+    >>> builder.update()
+    >>> builder.write(buildDir, True)
+
+    >>> ls(buildDir)
+    helloworld/
+      bootstrap.py
+      buildout.cfg
+      setup.py
+      src/
+        helloworld/
+          __init__.py
+          content.py
+          interfaces.py
+
+    >>> more(buildDir, 'helloworld', 'src', 'helloworld', 'content.py')
+    #######################################################################...
+    #
+    # This file is part of helloworld. ...
+    #
+    #######################################################################...
+    """Module Documentation"""
+    from helloworld.interfaces import IHelloWorld
+    from persistent import Persistent
+    from zope.container.contained import Contained
+    from zope.interface import implements
+    from zope.schema.fieldproperty import FieldProperty
+    <BLANKLINE>
+    class HelloWorld(Persistent, Contained):
+        """Implementation of ``helloworld.interfaces.IHelloWorld``"""
+        implements(IHelloWorld)
+    <BLANKLINE>
+        who = FieldProperty(IHelloWorld['who'])
+        when = FieldProperty(IHelloWorld['when'])
+        what = FieldProperty(IHelloWorld['what'])
+    <BLANKLINE>
+        def getMessage(self, template='A %(what)s world ...'):
+            """See ``helloworld.interfaces.IHelloWorld``."""
+            return template %self.__dict__
+
+
+Rendering Configuration
+-----------------------
+
+Now that we have a content, we have content, let's secure it using ZCML
+configuration. First we create a ZCML file builder.
+
+  >>> from z3c.builder.core import zcml
+  >>> config = zcml.ZCMLFileBuilder(u'configure.zcml')
+  >>> builder.package.add(config)
+  u'configure'
+
+Next we add a class directive with the necessary security declarations:
+
+  >>> shw = zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'class',
+  ...     attributes = {'class': '.content.HelloWorld'}
+  ...     )
+  >>> config.add(shw)
+  '...'
+
+  >>> shw.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'allow',
+  ...     attributes = {'interface': '.interfaces.IHelloWorld'}
+  ...     ))
+  '...'
+
+  >>> shw.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'allow',
+  ...     attributes = {'set_schema': '.interfaces.IHelloWorld'}
+  ...     ))
+  '...'
+
+Let's now render the project again to see the result:
+
+  >>> builder.update()
+  >>> builder.write(buildDir, True)
+
+  >>> ls(buildDir)
+  helloworld/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      helloworld/
+        __init__.py
+        configure.zcml
+        content.py
+        interfaces.py
+
+  >>> more(buildDir, 'helloworld', 'src', 'helloworld', 'configure.zcml')
+  <configure
+      xmlns:zope="http://namespaces.zope.org/zope"
+      i18n_domain="helloworld"
+      >
+    <zope:class
+        class=".content.HelloWorld"
+        >
+      <zope:allow
+          interface=".interfaces.IHelloWorld"
+          />
+      <zope:allow
+          set_schema=".interfaces.IHelloWorld"
+          />
+    </zope:class>
+  </configure>
+
+
+Rendering Forms
+---------------
+
+All browser code usually lives in a sub-package of that name.
+
+  >>> builder.package.add(python.PackageBuilder(u'browser'))
+  u'browser'
+
+  >>> config.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'include',
+  ...     attributes = {
+  ...         'package': '.browser'}
+  ...     ))
+  '3ed2441d-fbb9-4b32-864a-2786516ee4ba'
+
+  >>> config = zcml.ZCMLFileBuilder(u'configure.zcml')
+  >>> builder.package['browser'].add(config)
+  u'configure'
+
+We'll also create a module for the forms.
+
+  >>> forms = python.ModuleBuilder(u'form.py')
+  >>> builder.package['browser'].add(forms)
+  u'form.py'
+
+Let's see what we got:
+
+  >>> builder.update()
+  >>> builder.write(buildDir, True)
+
+  >>> ls(buildDir)
+  helloworld/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      helloworld/
+        __init__.py
+        configure.zcml
+        content.py
+        interfaces.py
+        browser/
+          __init__.py
+          configure.zcml
+          form.py
+
+Let's first build an add form and register it:
+
+  >>> from z3c.builder.core import form
+  >>> forms.add(form.AddFormBuilder(
+  ...     name=u'HelloWorldAddForm',
+  ...     interface='helloworld.interfaces.IHelloWorld',
+  ...     fields=('who', 'when', 'what'),
+  ...     factory='helloworld.content.HelloWorld',
+  ...     next='index.html'
+  ...     ))
+  u'HelloWorldAddForm'
+
+  >>> config.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.BROWSER_NS,
+  ...     name = u'page',
+  ...     attributes = {
+  ...         'name': 'index.html',
+  ...         'for': 'zope.container.interfaces.IContainer',
+  ...         'class': '.forms.HelloWorldAddForm',
+  ...         'permission': 'zope.Public'}
+  ...     ))
+  '...'
+
+Next is the edit form:
+
+  >>> forms.add(form.EditFormBuilder(
+  ...     name=u'HelloWorldEditForm',
+  ...     interface='helloworld.interfaces.IHelloWorld',
+  ...     fields=('who', 'when', 'what')
+  ...     ))
+  u'HelloWorldEditForm'
+
+  >>> config.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.BROWSER_NS,
+  ...     name = u'page',
+  ...     attributes = {
+  ...         'name': 'edit.html',
+  ...         'for': 'helloworld.interfaces.IHelloWorld',
+  ...         'class': '.forms.HelloWorldEditForm',
+  ...         'permission': 'zope.Public'}
+  ...     ))
+  '...'
+
+Finally the display form:
+
+  >>> builder.package['browser']['form.py'].add(form.SimpleDisplayFormBuilder(
+  ...     name=u'HelloWorldDisplayForm',
+  ...     interface='helloworld.interfaces.IHelloWorld',
+  ...     fields=('who', 'when', 'what'),
+  ...     template = u'A %(what)s world from %(who)s on %(when)s.'
+  ...     ))
+  u'HelloWorldDisplayForm'
+
+  >>> config.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.BROWSER_NS,
+  ...     name = 'page',
+  ...     attributes = {
+  ...         'name': 'index.html',
+  ...         'for': 'helloworld.interfaces.IHelloWorld',
+  ...         'class': '.forms.HelloWorldDisplayForm',
+  ...         'permission': 'zope.Public'}
+  ...     ))
+  '...'
+
+New we are finally ready to generate the code:
+
+    >>> builder.update()
+    >>> builder.write(buildDir, True)
+
+    >>> more(buildDir, 'helloworld', 'src', 'helloworld',
+    ...      'browser', 'form.py')
+    #######################################################################...
+    #
+    # This file is part of helloworld. ...
+    #
+    #######################################################################...
+    """Module Documentation"""
+    from helloworld.content import HelloWorld
+    from helloworld.interfaces import IHelloWorld
+    from z3c.form.field import Fields
+    from z3c.form.form import AddForm
+    from z3c.form.form import DisplayForm
+    from z3c.form.form import EditForm
+    from z3c.form.form import Form
+    from zope.traversing.browser import absoluteURL
+    <BLANKLINE>
+    class HelloWorldAddForm(AddForm):
+        """Add form for IHelloWorld"""
+    <BLANKLINE>
+        label = u'Add Form'
+        fields = Fields(IHelloWorld).select('who', 'when', 'what')
+    <BLANKLINE>
+        def create(self, data):
+            object = HelloWorld()
+            for name, value in data.items():
+                setattr(object, name, value)
+            return object
+    <BLANKLINE>
+        def add(self, object):
+            count = 0
+            while 'HelloWorld-%i' %count in self.context:
+                count += 1;
+            self._name = 'HelloWorld-%i' %count
+            self.context[self._name] = object
+            return object
+    <BLANKLINE>
+        def nextURL(self):
+            return absoluteURL(
+                self.context[self._name], self.request) + '/index.html'
+    <BLANKLINE>
+    <BLANKLINE>
+    class HelloWorldEditForm(EditForm):
+        """Edit form for IHelloWorld"""
+    <BLANKLINE>
+        label = u'Edit Form'
+        fields = Fields(IHelloWorld).select('who', 'when', 'what')
+    <BLANKLINE>
+    <BLANKLINE>
+    class HelloWorldDisplayForm(DisplayForm, Form):
+        """Display form for IHelloWorld"""
+        fields = Fields(IHelloWorld).select('who', 'when', 'what')
+
+    >>> more(buildDir, 'helloworld', 'src', 'helloworld',
+    ...      'browser', 'configure.zcml')
+    <configure
+        xmlns:browser="http://namespaces.zope.org/browser"
+        i18n_domain="helloworld"
+        >
+      <browser:page
+          class=".forms.HelloWorldAddForm"
+          for="zope.container.interfaces.IContainer"
+          name="index.html"
+          permission="zope.Public"
+          />
+      <browser:page
+          class=".forms.HelloWorldEditForm"
+          for="helloworld.interfaces.IHelloWorld"
+          name="edit.html"
+          permission="zope.Public"
+          />
+      <browser:page
+          class=".forms.HelloWorldDisplayForm"
+          for="helloworld.interfaces.IHelloWorld"
+          name="index.html"
+          permission="zope.Public"
+          />
+    </configure>
+
+Note that we also got an include statement in the main configuration file now:
+
+  >>> more(buildDir, 'helloworld', 'src', 'helloworld', 'configure.zcml')
+  <configure
+      xmlns:zope="http://namespaces.zope.org/zope"
+      i18n_domain="helloworld"
+      >
+    ...
+    <zope:include
+        package=".browser"
+        />
+  </configure>
+
+
+Finishing the Application
+-------------------------
+
+Now that we have all the business objects built, we have to provide some
+additional setup.
+
+1. Create an overall application ZCML file.
+
+  >>> appConfig = zcml.ZCMLFileBuilder(u'application.zcml')
+  >>> builder.package['appConfig'] = appConfig
+
+  >>> for name in ('zope.app.component',
+  ...              'zope.app.component.browser',
+  ...              'zope.app.form.browser',
+  ...              'zope.app.pagetemplate',
+  ...              'zope.app.publication',
+  ...              'zope.app.publisher',
+  ...              'zope.app.security',
+  ...              'zope.app.securitypolicy',
+  ...              'zope.viewlet',
+  ...              'z3c.form',
+  ...              'z3c.macro',
+  ...              'z3c.pagelet',
+  ...              'z3c.template'):
+  ...     id = appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...         namespace = zcml.ZOPE_NS,
+  ...         name = 'include',
+  ...         attributes = {
+  ...             'package': name,
+  ...             'file': 'meta.zcml'}
+  ...         ))
+
+  >>> appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.BROWSER_NS,
+  ...     name = 'menu',
+  ...     attributes = {
+  ...         'id': 'zmi_views',
+  ...         'title': 'Views'}
+  ...     ))
+  '...'
+
+  >>> appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.BROWSER_NS,
+  ...     name = 'menu',
+  ...     attributes = {
+  ...         'id': 'zmi_actions',
+  ...         'title': 'Actions'}
+  ...     ))
+  '...'
+
+  >>> for name in ('zope.app.appsetup',
+  ...              'zope.app.component',
+  ...              'zope.app.container',
+  ...              'zope.app.error',
+  ...              'zope.app.i18n',
+  ...              'zope.app.publication',
+  ...              'zope.app.security',
+  ...              'zope.app.securitypolicy',
+  ...              'zope.app.session',
+  ...              'zope.app.twisted',
+  ...              'zope.app.wsgi',
+  ...              'zope.annotation',
+  ...              'zope.component',
+  ...              'zope.contentprovider',
+  ...              'zope.location',
+  ...              'zope.publisher',
+  ...              'zope.traversing',
+  ...              'zope.traversing.browser',
+  ...              'zope.viewlet',
+  ...              'z3c.form',
+  ...              'z3c.formui',
+  ...              'z3c.layer.pagelet',
+  ...              'z3c.macro',
+  ...              'z3c.pagelet'):
+  ...     id = appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...         namespace = zcml.ZOPE_NS,
+  ...         name = 'include',
+  ...         attributes = {'package': name}
+  ...         ))
+
+  >>> appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.BROWSER_NS,
+  ...     name = 'defaultView',
+  ...     attributes = {
+  ...         'name': 'index.html'}
+  ...     ))
+  '...'
+
+  >>> appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'securityPolicy',
+  ...     attributes = {
+  ...         'component': 'zope.securitypolicy.zopepolicy.ZopeSecurityPolicy'}
+  ...     ))
+  '...'
+
+  >>> appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'role',
+  ...     attributes = {
+  ...         'id': 'zope.Anonymous',
+  ...         'title': 'Everybody'}
+  ...     ))
+  '...'
+
+  >>> appConfig.add(zcml.ZCMLDirectiveBuilder(
+  ...     namespace = zcml.ZOPE_NS,
+  ...     name = 'grantAll',
+  ...     attributes = {
+  ...         'role': 'zope.Anonymous'}
+  ...     ))
+  '...'
+
+2. We need to create a few more buildout parts.
+
+  >>> builder.buildout.add(buildout.PartBuilder(
+  ...     u'zope3',
+  ...     [('location', '.')],
+  ...     autoBuild=False
+  ...     ))
+  u'zope3'
+
+  >>> builder.buildout.add(buildout.PartBuilder(
+  ...     u'%s-app' %builder.name,
+  ...     [('recipe', 'zc.zope3recipes:app'),
+  ...      ('site.zcml',
+  ...       '<include package="helloworld" file="application.zcml" />'),
+  ...      ('eggs', builder.name)]
+  ...     ))
+  u'helloworld-app'
+
+  >>> builder.buildout.add(buildout.PartBuilder(
+  ...     builder.name,
+  ...     [('recipe', 'zc.zope3recipes:instance'),
+  ...      ('application', '%s-app' %builder.name),
+  ...      ('zope.conf', '${database:zconfig}'),
+  ...      ('eggs', builder.name)]
+  ...     ))
+  u'helloworld'
+
+  >>> builder.buildout.add(buildout.PartBuilder(
+  ...     u'database',
+  ...     [('recipe', 'zc.recipe.filestorage')],
+  ...     autoBuild=False
+  ...     ))
+  u'database'
+
+  >>> builder.buildout.add(buildout.PartBuilder(
+  ...     u'versions',
+  ...     [('z3c.layer.pagelet', '1.0.1')],
+  ...     autoBuild=False
+  ...     ))
+  u'versions'
+
+3. We also need a add a bunch of dependencies:
+
+  >>> builder.setup.install_requires += [
+  ...     'zdaemon',
+  ...     'z3c.form',
+  ...     'z3c.formui',
+  ...     'z3c.layer.pagelet',
+  ...     'z3c.pagelet',
+  ...     'z3c.template',
+  ...     'zc.zope3recipes',
+  ...     'zope.app.securitypolicy',
+  ...     'zope.app.session',
+  ...     'zope.app.twisted',
+  ...     'zope.viewlet',
+  ...     ]
+
+Let's do a final rendering now:
+
+  >>> builder.update()
+  >>> builder.write(buildDir, True)
+
+  >>> ls(buildDir)
+  helloworld/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      helloworld/
+        __init__.py
+        application.zcml
+        configure.zcml
+        content.py
+        interfaces.py
+        browser/
+          __init__.py
+          configure.zcml
+          display.pt
+          form.py
+
+  >>> more(buildDir, 'helloworld', 'buildout.cfg')
+  [buildout]
+  extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+  develop = .
+  parts = python helloworld-app helloworld
+  versions = versions
+  <BLANKLINE>
+  [python]
+  recipe = zc.recipe.egg
+  interpreter = python
+  eggs = helloworld
+  <BLANKLINE>
+  [zope3]
+  location = .
+  <BLANKLINE>
+  [helloworld-app]
+  recipe = zc.zope3recipes:app
+  site.zcml = <include package="helloworld" file="application.zcml" />
+  eggs = helloworld
+  <BLANKLINE>
+  [helloworld]
+  recipe = zc.zope3recipes:instance
+  application = helloworld-app
+  zope.conf = ${database:zconfig}
+  eggs = helloworld
+  <BLANKLINE>
+  [database]
+  recipe = zc.recipe.filestorage
+  <BLANKLINE>
+  [versions]
+  z3c.layer.pagelet = 1.0.1
+
+
+Building the Application
+------------------------
+
+Now that we have generated the full application, let's try building it.
+
+  >>> import sys
+  >>> projectDir = buildDir + '/helloworld'
+
+  >>> print cmd((sys.executable, 'bootstrap.py'), projectDir)
+  Exit Status: 0...
+  Creating directory '.../helloworld/bin'.
+  Creating directory '.../helloworld/parts'.
+  Creating directory '.../helloworld/develop-eggs'.
+  Generated script '.../helloworld/bin/buildout'.
+
+  >>> print cmd(('./bin/buildout', '-N'), projectDir)
+  Exit Status: 0
+  Develop: '.../helloworld/.'
+  Installing python.
+  Generated interpreter '.../helloworld/bin/python'.
+  Installing helloworld-app.
+  Generated script '.../helloworld/parts/helloworld-app/runzope'.
+  Generated script '.../helloworld/parts/helloworld-app/debugzope'.
+  Installing database.
+  Installing helloworld.
+  Generated script '.../helloworld/bin/helloworld'.
+
+Let's now load the configuration to check that we have a fully functioning
+package.
+
+  >>> testCode = '''
+  ... import zope.app.twisted.main
+  ... from zc.zope3recipes import debugzope
+  ... options = debugzope.load_options(
+  ...     ('-C', '%(dir)s/parts/helloworld/zope.conf',),
+  ...     zope.app.twisted.main)
+  ... print debugzope.zglobals(options.configroot)['root']
+  ... ''' % {'dir': projectDir}
+
+  >>> print cmd(('./bin/python', '-c', testCode), projectDir)
+  Exit Status: 0
+  <zope.app.folder.folder.Folder object at ...>
+
+And that's it! We have a functioning Zope 3 application.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/example.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1 @@
+# Make a package.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__namespace.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__namespace.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__namespace.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,7 @@
+try:
+    # Declare this a namespace package if pkg_resources is available.
+    import pkg_resources
+    pkg_resources.declare_namespace(__name__)
+except ImportError:
+    pass
+


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/__init__namespace.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/add-form.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/add-form.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/add-form.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,23 @@
+class %(className)s(AddForm):
+    """Add form for %(interface)s"""
+
+    label = u'%(label)s'
+    fields = Fields(%(interface)s).select(%(fields)s)
+
+    def create(self, data):
+        object = %(factory)s()
+        for name, value in data.items():
+            setattr(object, name, value)
+        return object
+
+    def add(self, object):
+        count = 0
+        while '%(factory)s-%%i' %%count in self.context:
+            count += 1;
+        self._name = '%(factory)s-%%i' %%count
+        self.context[self._name] = object
+        return object
+
+    def nextURL(self):
+        return absoluteURL(
+            self.context[self._name], self.request) + '/%(next)s'


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/add-form.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/bootstrap.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/bootstrap.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/bootstrap.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/bootstrap.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/buildout.cfg
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/buildout.cfg	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/buildout.cfg	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,5 @@
+[buildout]
+extends=http://download.zope.org/zope3.4/3.4.0/versions.cfg
+develop = .
+parts =
+versions = versions

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/edit-form.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/edit-form.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/edit-form.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,5 @@
+class %(className)s(EditForm):
+    """Edit form for %(interface)s"""
+
+    label = u'%(label)s'
+    fields = Fields(%(interface)s).select(%(fields)s)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/edit-form.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/gpl3-header.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/gpl3-header.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/gpl3-header.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,18 @@
+##############################################################################
+#
+# This file is part of %(name)s.
+#
+# %(name)s is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# %(name)s is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with %(name)s.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/gpl3-header.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/proprietary-header.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/proprietary-header.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/proprietary-header.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,5 @@
+###############################################################################
+#
+# Copyright %(year)s by %(company)s, %(location)s
+#
+###############################################################################


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/proprietary-header.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/setup.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/setup.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/setup.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,25 @@
+%(commentHeader)s
+"""Setup"""
+from setuptools import setup, find_packages
+
+setup (
+    name = '%(name)s',
+    version = '%(version)s',
+    author = u"%(author)s",
+    author_email = u"%(author_email)s",
+    description = u"%(description)s",
+    license = "%(license)s",
+    keywords = u"%(keywords)s",
+    url = "%(url)s",
+    classifiers = %(classifiers)s,
+    packages = find_packages('src'),
+    include_package_data = True,
+    package_dir = {'':'src'},
+    namespace_packages = [%(namespacePackages)s],
+    extras_require = %(extras_require)s,
+    install_requires = [
+        'setuptools',%(install_requires)s
+        ],
+    zip_safe = False,
+    entry_points = %(entry_points)s,
+    )


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/setup.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.pt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.pt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.pt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <h1 tal:content="structure context/getContent">Data</h1>
+  </body>
+</html>


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.pt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,3 @@
+class %(className)s(DisplayForm, Form):
+    """Display form for %(interface)s"""
+    fields = Fields(%(interface)s).select(%(fields)s)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/simple-display-form.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zboiler-doc-header.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zboiler-doc-header.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zboiler-doc-header.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,13 @@
+=========================================================
+Documentation About Project Features Generated by ZBoiler
+=========================================================
+
+ZBoiler (http://zboiler.com) was used to generate the boiler plate
+code for this project.  To build your project, run these commands::
+
+  $ python bootstrap.py
+  $ ./bin/buildout
+
+What happens next depends on the features you used to generate your
+project.  Check out more information about each feature below.
+


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zboiler-doc-header.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zpl-header.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zpl-header.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zpl-header.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,13 @@
+##############################################################################
+#
+# Copyright (c) %(year)s %(author)s.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/file-templates/zpl-header.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/form.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/form.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/form.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,134 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Representation of Form view classes.
+
+$Id$
+"""
+import os
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+from z3c.builder.core import base, interfaces, python
+
+class AddFormBuilder(python.ModuleBuilderGetter, base.ContentBuilder):
+    zope.interface.implements(interfaces.IAddFormBuilder)
+
+    interface = FieldProperty(interfaces.IAddFormBuilder['interface'])
+    factory = FieldProperty(interfaces.IAddFormBuilder['factory'])
+    fields = FieldProperty(interfaces.IAddFormBuilder['fields'])
+    next = FieldProperty(interfaces.IAddFormBuilder['next'])
+    label = FieldProperty(interfaces.IAddFormBuilder['label'])
+
+    def __init__(self, name, interface, factory,
+                 fields=(), next='index.html', label=u'Add Form'):
+        super(AddFormBuilder, self).__init__(name)
+        self.interface = interface
+        self.factory = factory
+        self.fields = tuple([str(f) for f in fields])
+        self.next = next
+        self.label = label
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        self.getModuleBuilder().imports += [
+            'z3c.form.form.AddForm',
+            'z3c.form.field.Fields',
+            'zope.traversing.browser.absoluteURL',
+            self.interface,
+            self.factory]
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        template = open(base.getTemplatePath('add-form.py'), 'r').read()
+        output = (template %{
+            'interface': self.interface.rsplit('.', 1)[-1],
+            'label': self.label,
+            'fields': ', '.join([repr(field) for field in self.fields]),
+            'factory': self.factory.rsplit('.', 1)[-1],
+            'next': self.next,
+            'className':self.name,
+            })
+        output += '\n'
+        return output
+
+
+class EditFormBuilder(python.ModuleBuilderGetter, base.ContentBuilder):
+    zope.interface.implements(interfaces.IEditFormBuilder)
+
+    interface = FieldProperty(interfaces.IEditFormBuilder['interface'])
+    fields = FieldProperty(interfaces.IEditFormBuilder['fields'])
+    label = FieldProperty(interfaces.IEditFormBuilder['label'])
+
+    def __init__(self, name, interface, fields=(), label=u'Edit Form'):
+        super(EditFormBuilder, self).__init__(name)
+        self.interface = interface
+        self.fields = tuple([str(f) for f in fields])
+        self.label = label
+
+    def update(self):
+        self.getModuleBuilder().imports += [
+            'z3c.form.form.EditForm',
+            'z3c.form.field.Fields',
+            self.interface]
+
+    def render(self):
+        template = open(base.getTemplatePath('edit-form.py'), 'r').read()
+        output = (template %{
+            'interface': self.interface.rsplit('.', 1)[-1],
+            'label': self.label,
+            'fields': ', '.join([repr(field) for field in self.fields]),
+            'className':self.name,
+            })
+        output += '\n'
+        return output
+
+
+class SimpleDisplayFormBuilder(python.ModuleBuilderGetter, base.ContentBuilder):
+    zope.interface.implements(interfaces.IDisplayFormBuilder)
+
+    interface = FieldProperty(interfaces.IDisplayFormBuilder['interface'])
+    fields = FieldProperty(interfaces.IDisplayFormBuilder['fields'])
+    template = FieldProperty(interfaces.IDisplayFormBuilder['template'])
+
+    def __init__(self, name, interface, template=None, fields=()):
+        super(SimpleDisplayFormBuilder, self).__init__(name)
+        self.interface = interface
+        self.template = template
+        self.fields = tuple([str(f) for f in fields])
+
+    def update(self):
+        self.getModuleBuilder().imports += [
+            'z3c.form.form.Form',
+            'z3c.form.form.DisplayForm',
+            'z3c.form.field.Fields',
+            self.interface]
+        # Add the template for the form.
+        if self.template:
+            browserPackage = self.getModuleBuilder().__parent__
+            if 'display.pt' not in browserPackage:
+                zpt = base.SimpleFileBuilder(
+                    u'display.pt', base.getTemplatePath('simple-display-form.pt'))
+                browserPackage.add(zpt)
+                zpt.update()
+
+    def render(self):
+        template = open(
+            base.getTemplatePath('simple-display-form.py'), 'r').read()
+        output = (template %{
+            'interface': self.interface.rsplit('.', 1)[-1],
+            'fields': ', '.join([repr(field) for field in self.fields]),
+            'template': self.template,
+            'className': self.name,
+            })
+        output += '\n'
+        return output


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/form.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/form.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/form.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/form.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,172 @@
+============
+Form Builder
+============
+
+The `form` module provides a set of simple builders to produce add, edit and
+display forms.
+
+  >>> from z3c.builder.core import form, interfaces
+
+Add Form
+--------
+
+The add form produces a simple add form.
+
+  >>> builder = form.AddFormBuilder(
+  ...     u'AddProjectForm',
+  ...     'my.project.interfaces.IProject',
+  ...     'my.project.content.Project',
+  ...     ('name', 'author', 'version'))
+  >>> builder
+  <AddFormBuilder u'AddProjectForm'>
+
+This object provides the ``IAddFormBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IAddFormBuilder, builder)
+  True
+
+Let's now render the builder:
+
+  >>> builder.update()
+  Traceback (most recent call last):
+  ...
+  ValueError: No module builder was found and the root node of the
+              project tree was reached.
+
+We have to add a module and project:
+
+  >>> from z3c.builder.core import python, project
+
+  >>> module = python.ModuleBuilder(u'browser')
+  >>> module.update()
+  >>> module.__parent__ = project.ProjectBuilder(u'z3c.myproject')
+
+  >>> builder.__parent__ = module
+
+Let's try this again:
+
+  >>> builder.update()
+  >>> print builder.render()
+  class AddProjectForm(AddForm):
+      """Add form for IProject"""
+  <BLANKLINE>
+      label = u'Add Form'
+      fields = Fields(IProject).select('name', 'author', 'version')
+  <BLANKLINE>
+      def create(self, data):
+          object = Project()
+          for name, value in data.items():
+              setattr(object, name, value)
+          return object
+  <BLANKLINE>
+      def add(self, object):
+          count = 0
+          while 'Project-%i' %count in self.context:
+              count += 1;
+          self._name = 'Project-%i' %count
+          self.context[self._name] = object
+          return object
+  <BLANKLINE>
+      def nextURL(self):
+          return absoluteURL(
+              self.context[self._name], self.request) + '/index.html'
+
+That's it.
+
+
+Edit Form
+---------
+
+The edit form produces a simple edit form.
+
+  >>> builder = form.EditFormBuilder(
+  ...     u'EditProjectForm',
+  ...     'my.project.interfaces.IProject',
+  ...     ('name', 'author', 'version'))
+  >>> builder
+  <EditFormBuilder u'EditProjectForm'>
+
+This object provides the ``IEditFormBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IEditFormBuilder, builder)
+  True
+
+Let's now render the builder:
+
+  >>> builder.update()
+  Traceback (most recent call last):
+  ...
+  ValueError: No module builder was found and the root node of the
+              project tree was reached.
+
+We have to edit a module and project:
+
+  >>> from z3c.builder.core import python, project
+
+  >>> module = python.ModuleBuilder(u'browser')
+  >>> module.update()
+  >>> module.__parent__ = project.ProjectBuilder(u'z3c.myproject')
+
+  >>> builder.__parent__ = module
+
+Let's try this again:
+
+  >>> builder.update()
+  >>> print builder.render()
+  class EditProjectForm(EditForm):
+      """Edit form for IProject"""
+  <BLANKLINE>
+      label = u'Edit Form'
+      fields = Fields(IProject).select('name', 'author', 'version')
+
+That's it.
+
+
+Simple Display Form
+-------------------
+
+The display form produces a simple display form.
+
+  >>> builder = form.SimpleDisplayFormBuilder(
+  ...     u'DisplayProjectForm',
+  ...     'my.project.interfaces.IProject',
+  ...     u'%(name)s %(version)s by %(author)s.',
+  ...     ('name', 'author', 'version'))
+  >>> builder
+  <SimpleDisplayFormBuilder u'DisplayProjectForm'>
+
+This object provides the ``IDisplayFormBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IDisplayFormBuilder, builder)
+  True
+
+Let's now render the builder:
+
+  >>> builder.update()
+  Traceback (most recent call last):
+  ...
+  ValueError: No module builder was found and the root node of the
+              project tree was reached.
+
+We have to display a module and project:
+
+  >>> from z3c.builder.core import python, project
+
+  >>> module = python.ModuleBuilder(u'browser')
+  >>> module.update()
+  >>> module.__parent__ = project.ProjectBuilder(u'z3c.myproject')
+
+  >>> builder.__parent__ = module
+
+Let's try this again:
+
+  >>> builder.update()
+  >>> print builder.render()
+  class DisplayProjectForm(DisplayForm, Form):
+      """Display form for IProject"""
+      fields = Fields(IProject).select('name', 'author', 'version')
+
+That's it.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/form.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/index.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/index.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/index.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,24 @@
+=========================
+Z3C Builder Documentation
+=========================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   README
+   example
+   project
+   python
+   setup
+   buildout
+   zcml
+   form
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/index.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/interfaces.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/interfaces.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/interfaces.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,498 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Builder interfaces
+
+$Id$
+"""
+import os
+import zope.interface
+import zope.schema
+from zope.container.constraints import contains, containers
+from zope.container.interfaces import IOrderedContainer, IContained
+from zope.schema.vocabulary import SimpleTerm
+from zope.schema.vocabulary import SimpleVocabulary
+
+troveClassifiers = open(os.path.join(os.path.dirname(__file__),
+                                     'trove-classifiers.txt')).read().split('\n')
+troveClassiferVocabulary = SimpleVocabulary(map(SimpleTerm,
+                                                troveClassifiers))
+
+class FileExistsException(Exception):
+    """Exception to throw if a file that will be written already exists."""
+
+    filename = None
+
+    def __init__(self, filename, message=u''):
+        super(FileExistsException, self).__init__(message)
+        self.filename = filename
+
+
+# --- Basic Builder Components ------------------------------------------------
+
+class IBaseBuilder(IContained):
+    """A builder constructs code from a programmatic desciption."""
+
+    name = zope.schema.TextLine(
+        title=u'Name',
+        description=u'The name of the builder instance.')
+
+    def update():
+        """Update the builder before rendering.
+
+        The purpose of this method is to prepare the builder and dependents
+        for rendering.
+        """
+
+class IBuilderContainer(IBaseBuilder, IOrderedContainer):
+    """A container for other builders."""
+    contains(IBaseBuilder)
+
+    def add(builder):
+        """Add a builder to the container.
+
+        The name is usually computed from the name of the builder.
+
+        The name of the builder in the component is returned.
+        """
+
+    def remove(builder):
+        """Remove the builder from the container."""
+
+
+class IProjectGetter(zope.interface.Interface):
+    """Gets the project the builser belongs to."""
+
+    def getProject():
+        """Return the project instance."""
+
+
+class IContentBuilder(IBaseBuilder):
+    """Build a piece of content/code within a file."""
+
+    def render():
+        """Render the code and return the result as a string."""
+
+
+class IFilesystemBuilder(IBaseBuilder):
+    """Builds and writes a filesystem-level component."""
+
+    def write(target):
+        """Write the new file(s) into the target directory."""
+
+
+class IFileBuilder(IFilesystemBuilder):
+    """Bulder to construct a single file with all its content."""
+
+    filename = zope.schema.ASCIILine(
+        title=u'File Name',
+        description=u'The name of the file to be created.')
+
+
+class IDirectoryBuilder(IFilesystemBuilder, IBuilderContainer):
+    """Builder to construct a directory and all its content."""
+    contains(IFileBuilder, '.IDirectoryBuilder')
+
+    dirname = zope.schema.ASCIILine(
+        title=u'Directory Name',
+        description=u'The name of the directory to be created.')
+
+
+# --- Python Code Builders ----------------------------------------------------
+
+class IPythonPathRoot(zope.interface.Interface):
+    """Marker interface flagging the root directory."""
+
+
+class IPythonPathGetter(zope.interface.Interface):
+    """Gets a full Python path of the current builder."""
+
+    def getPythonPath():
+        """Return full Python path as a string."""
+
+
+class IModuleBuilderGetter(zope.interface.Interface):
+    """Gets the next module builder."""
+
+    def getModuleBuilder():
+        """Return the next module builder."""
+
+
+class IPackageBuilder(IDirectoryBuilder, IPythonPathGetter):
+    """Builds a full Python package or sub-package."""
+
+    packageName = zope.schema.ASCIILine(
+        title=u'Package Name',
+        description=u'The name of the package to be created.',
+        required=True)
+
+    initTemplate = zope.schema.Bytes(
+        title=u'Init Template',
+        description=u'The content template for the `__init__.py` file.',
+        required=True)
+
+
+class IModuleBuilder(IFileBuilder, IBuilderContainer, IPythonPathGetter):
+    """Builds a Python module."""
+
+    moduleName = zope.schema.ASCIILine(
+        title=u'Module Name',
+        description=u'The name of the module to be created.')
+
+    imports = zope.schema.List(
+        title=u'Import List',
+        description=u'The list of objects to import.')
+
+
+# --- Content Builders --------------------------------------------------------
+
+class IFunctionBuilder(IContentBuilder):
+    """A builder to construct a function."""
+
+    args = zope.schema.Tuple(
+        title=u'Args',
+        description=u'List of function arguments.',
+        required=False)
+
+    kwargs = zope.schema.Dict(
+        title=u'Kwargs',
+        description=u'<apping of function keyword arguments.',
+        required=False)
+
+    docstring = zope.schema.ASCII(
+        title=u'Interface Docstring',
+        description=u'The docstring of the function.')
+
+    indent = zope.schema.Int(
+        title=u'Indentation Level',
+        description=u'The number of columns to indent the function.',
+        default=0)
+
+    code = zope.schema.ASCII(
+        title=u'Code',
+        description=u'The source code of the function.')
+
+
+class IFieldBuilder(IContentBuilder):
+    """A builder to create a field for an interface builder."""
+
+    fieldName = zope.schema.ASCIILine(
+        title=u'Field Name',
+        description=u'The name of the field.',
+        required=True)
+
+    type = zope.schema.ASCIILine(
+        title=u'Type',
+        description=u'The full Python path of the type of the field.',
+        required=True)
+
+    attributes = zope.schema.Dict(
+        title=u'Attributes',
+        key_type = zope.schema.ASCIILine(),
+        value_type = zope.schema.Field(),
+        description=u'The attributes of the field.')
+
+    indent = zope.schema.Int(
+        title=u'Indentation Level',
+        description=u'The number of columns to indent the field.',
+        default=0)
+
+
+class IInterfaceBuilder(IPythonPathGetter, IContentBuilder):
+    """A builder to construct interfaces and schemas."""
+
+    docstring = zope.schema.ASCII(
+        title=u'Interface Docstring',
+        description=u'The docstring of the itnerface.')
+
+    bases = zope.schema.List(
+        title=u'Bases',
+        description=u'A list of base interfaces.')
+
+
+class IClassFromInterfaceBuilder(IContentBuilder):
+
+    #className = zope.schema.TextLine(
+    #    title=u'Class Name',
+    #    description=u'The name of the generated class.')
+
+    interface = zope.schema.Field(
+        title=u'Interface',
+        description=u'The interface to generate the class from.')
+
+    docstring = zope.schema.ASCII(
+        title=u'Interface Docstring',
+        description=u'The docstring of the interface.')
+
+    bases = zope.schema.List(
+        title=u'Bases',
+        description=u'A list of base interfaces (full Python path).',
+        value_type=zope.schema.DottedName(title=u'Full Python Path'))
+
+    implementations = zope.schema.Dict(
+        title=u'Implementations',
+        description=u'A collection of method implementations.',
+        key_type=zope.schema.ASCIILine(),
+        value_type=zope.schema.ASCII())
+
+
+# --- Setup Builders ---------------------------------------------------------
+
+class ISetupBuilder(IFileBuilder):
+
+    version = zope.schema.TextLine(
+        title=u"Version",
+        default=u"0.1.0",
+        required=False)
+
+    license = zope.schema.TextLine(
+        title=u"License",
+        default=u"GPLv3",
+        required=False)
+
+    author = zope.schema.TextLine(
+        title=u"Author",
+        default=u"",
+        required=False)
+
+    author_email = zope.schema.TextLine(
+        title=u"Author Email",
+        default=u"",
+        required=False)
+
+    description = zope.schema.TextLine(
+        title=u"Description",
+        default=u"",
+        required=False)
+
+    keywords = zope.schema.List(
+        title=u"Keywords",
+        value_type=zope.schema.TextLine(),
+        required=False)
+
+    namespace_packages = zope.schema.List(
+        title=u'Namespace Packages',
+        value_type=zope.schema.TextLine(),
+        required=False)
+
+    url = zope.schema.TextLine(
+        title=u'URL',
+        required=False)
+
+    classifiers = zope.schema.List(
+        title=u"Trove Classifiers",
+        value_type=zope.schema.Choice(
+            vocabulary=troveClassiferVocabulary),
+        required=False)
+
+    install_requires = zope.schema.List(
+        title=u"Install Requires",
+        value_type=zope.schema.ASCIILine(),
+        required=False)
+
+    extras_require = zope.schema.Dict(
+        title=u"Extras Require",
+        key_type=zope.schema.TextLine(),
+        value_type=zope.schema.List(value_type=zope.schema.TextLine()))
+
+    entry_points = zope.schema.Dict(
+        title=u"Extras Require",
+        key_type=zope.schema.TextLine(),
+        value_type=zope.schema.List(value_type=zope.schema.TextLine()))
+
+    def addExtrasRequires(name, requirements):
+        """Add the requirements to the named extra.
+
+        Multiple calls should not override each other.
+        """
+
+    def removeExtrasRequires(name):
+        """Remove the requirements from the named extra."""
+
+    def addEntryPoints(name, entries):
+        """Add entry points for the given name.
+
+        Multiple calls should not override each other.
+        """
+
+    def removeEntryPoints(name):
+        """Remove the entry points from the named section."""
+
+
+# --- Buildout Config Builders ------------------------------------------------
+
+class IPartBuilder(IFileBuilder):
+
+    values = zope.schema.List(
+        title=u"Values",
+        description=(u"A list of values set for this part."),
+        required=True)
+
+    autoBuild = zope.schema.Bool(
+        title=u"Auto-Build",
+        description=(u"A flag, when set, causes the part to be built "
+                     u"automatically"),
+        default=True,
+        required=True)
+
+    def addValue(key, value):
+        """Add a value to the part."""
+
+    def removeValue(key):
+        """Remove a value by key."""
+
+
+class IBuildoutConfigBuilder(IBuilderContainer, IFileBuilder):
+    """An object generating the  `buildout.cfg` file."""
+
+    extends = zope.schema.List(
+        title=u"Extends",
+        description=(u"A list of buildout configurations used to extend the "
+                     u"configuration file."),
+        value_type=zope.schema.TextLine(),
+        required=True)
+
+    names = zope.schema.List(
+        title=u"Names",
+        description=u"A list of part names that are automatically built.",
+        value_type=zope.schema.TextLine(),
+        required=True)
+
+
+# --- ZCML Builders -----------------------------------------------------------
+
+class IZCMLDirectiveBuilder(IBuilderContainer, IContentBuilder):
+    """A ZCML Directive Builder."""
+
+    namespace = zope.schema.URI(
+        title=u'Namespace',
+        description=u'Namespace URI of the directive.',
+        required=False)
+
+    #name = zope.schema.TextLine(
+    #    title=u'Name',
+    #    description=u'The directive name.',
+    #    required=True)
+
+    attributes = zope.schema.Dict(
+        title=u'Attributes',
+        description=u'A collection of attributes of the ZCML directive.',
+        required=False)
+
+    indent = zope.schema.Int(
+        title=u'Indentation Level',
+        description=u'The number of columns to indent the directive.',
+        default=0)
+
+    def getZCMLBuilder():
+        """Get the ZCML File Builder."""
+
+
+class IZCMLFileBuilder(IZCMLDirectiveBuilder, IFileBuilder):
+    """A ZCML File Builder."""
+
+    i18n_domain = zope.schema.TextLine(
+        title=u'I18n Domain',
+        description=u'The I18n domain to use for localization.',
+        required=False)
+
+    namespaces = zope.schema.List(
+        title=u'Namespaces',
+        description=u'A list of namespaces used in the file.',
+        required=True)
+
+
+# --- Form Builders -----------------------------------------------------------
+
+class IFormBuilder(IContentBuilder):
+    """Generic form builder."""
+
+    interface = zope.schema.ASCIILine(
+        title=u'Interface',
+        description=u'Full path to the interface.')
+
+    fields = zope.schema.Tuple(
+        title=u'Fields',
+        description=u'A list of fields to display.',
+        value_type=zope.schema.ASCIILine())
+
+
+class IAddFormBuilder(IFormBuilder):
+    """Add form builder."""
+
+    label = zope.schema.TextLine(
+        title=u'Label',
+        description=u'A label of the form.')
+
+    factory = zope.schema.ASCIILine(
+        title=u'Factory',
+        description=u'Full path to the factory.')
+
+    next = zope.schema.ASCII(
+        title=u'Next URL',
+        description=u'The relative URL to go to after adding the object.')
+
+
+class IEditFormBuilder(IFormBuilder):
+    """Edit form builder."""
+
+    label = zope.schema.TextLine(
+        title=u'Label',
+        description=u'A label of the form.')
+
+
+class IDisplayFormBuilder(IFormBuilder):
+    """Display form builder."""
+
+    template = zope.schema.Text(
+        title=u'Template',
+        description=u'A template for displaying the data.',
+        required=False)
+
+
+# --- Project Builders --------------------------------------------------------
+
+class IProjectBuilder(IDirectoryBuilder):
+    """A Python Project Builder."""
+
+    projectName = zope.schema.ASCIILine(
+        title=u"Project Name")
+
+    commentHeader = zope.schema.Text(
+        title=u"Comment Header",
+        required=False)
+
+    def write(target, force=False):
+        """Write the new project in the target directory.
+
+        If `force` is set, then any existing project in the target path is
+        ignored, and the new one is wrtten over it.
+        """
+
+class IBuildoutProjectBuilder(IProjectBuilder):
+    """A Buildout-based Python Project Builder."""
+
+    package = zope.schema.Object(
+        title=u"Project Code Package",
+        schema=IPackageBuilder,
+        readonly=True)
+
+    setup = zope.schema.Object(
+        title=u"Project Setup",
+        schema=ISetupBuilder,
+        readonly=True)
+
+    buildout = zope.schema.Object(
+        title=u"Project Buildout",
+        schema=IFileBuilder,
+        readonly=True)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/interfaces.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/project.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/project.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/project.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Representation of a Python Project
+
+$Id$
+"""
+import os
+import shutil
+import zope.interface
+from rwproperty import getproperty
+from zope.schema.fieldproperty import FieldProperty
+
+from z3c.builder.core import base, buildout, interfaces, python, setup
+
+
+class ProjectBuilder(base.DirectoryBuilder):
+    zope.interface.implements(interfaces.IProjectBuilder)
+
+    projectName = FieldProperty(interfaces.IProjectBuilder['projectName'])
+    commentHeader = FieldProperty(interfaces.IProjectBuilder['commentHeader'])
+
+    def __init__(self, name, projectName=None):
+        super(ProjectBuilder, self).__init__(name)
+        if projectName is None:
+            projectName = str(name)
+        self.projectName = self.dirname = projectName
+        self.commentHeader = unicode(open(
+            base.getTemplatePath('gpl3-header.py'), 'r').read())
+
+
+    def update(self):
+        self.directoryPath = unicode(self.name)
+        self.commentHeader = self.commentHeader %self.__dict__
+        for builder in self.values():
+            builder.update()
+
+    def write(self, target, force=False):
+        """See interfaces.IProjectBuilder"""
+        dirPath = os.path.join(target, self.dirname)
+        if os.path.exists(dirPath):
+            if not force:
+                raise interfaces.FileExistsException(dirPath)
+            shutil.rmtree(dirPath)
+        super(ProjectBuilder, self).write(target)
+
+
+class BuildoutProjectBuilder(ProjectBuilder):
+    zope.interface.implements(interfaces.IBuildoutProjectBuilder)
+
+    @getproperty
+    def setup(self):
+        return self['setup.py']
+
+    @getproperty
+    def buildout(self):
+        return self['buildout.cfg']
+
+    @getproperty
+    def package(self):
+        return self['src'].package
+
+    def __init__(self, name, projectName=None):
+        super(BuildoutProjectBuilder, self).__init__(name, projectName)
+        # Create the minimum amount files necessary to build a valid project
+        self['bootstrap.py'] = base.SimpleFileBuilder(
+            u'bootstrap.py', base.getTemplatePath('bootstrap.py'))
+        self['setup.py'] = setup.SetupBuilder()
+        self['buildout.cfg'] = buildout.BuildoutConfigBuilder()
+        self['src'] = SrcDirectoryBuilder()
+        self['src'].updateModules(self.name)
+
+
+class SrcDirectoryBuilder(base.DirectoryBuilder):
+
+    zope.interface.implements(interfaces.IPythonPathRoot)
+
+    def __init__(self):
+        super(SrcDirectoryBuilder, self).__init__(u'src')
+        self.package = python.PackageBuilder(u'')
+
+    def updateModules(self, projectName):
+        modules = list(reversed(unicode(projectName).split('.')))
+        builder = self
+        while len(modules) > 0:
+            name = modules.pop()
+            nextBuilder = python.PackageBuilder(name)
+            if len(modules) == 0:
+                nextBuilder = self.package
+                nextBuilder.dirname = nextBuilder.packageName = str(name)
+                nextBuilder.name = name
+            builder.add(nextBuilder)
+            builder = nextBuilder
+
+    def update(self):
+        for builder in self.values():
+            builder.update()
+
+    def __repr__(self):
+        return '<%s for %r>' %(self.__class__.__name__, self.getProject().name)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/project.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/project.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/project.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/project.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,171 @@
+====================
+The Project Builders
+====================
+
+The root node of the builder object tree is the project builder. As with all
+builders, the project builder has a name:
+
+  >>> from z3c.builder.core import interfaces, project
+  >>> builder = project.ProjectBuilder(u'myproject')
+  >>> builder
+  <ProjectBuilder u'myproject'>
+
+This object provides the ``IProjectBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IProjectBuilder, builder)
+  True
+
+By default, the project name is equal to the builder name, except that the
+latter is a simple string:
+
+  >>> builder.name
+  u'myproject'
+  >>> builder.projectName
+  'myproject'
+
+Optionally, you can specify a different string for the project name.
+
+  >>> builder = project.ProjectBuilder(u'MyProject', 'myproject')
+  >>> builder
+  <ProjectBuilder u'MyProject'>
+
+  >>> builder.name
+  u'MyProject'
+  >>> builder.projectName
+  'myproject'
+
+When rendering the project, always the directory name is used, which is set to
+the project name:
+
+  >>> builder.update()
+  >>> builder.write(buildPath)
+
+  >>> ls(buildPath)
+  myproject/
+
+Trying to rebuild the project fails, because the directory now exists already:
+
+  >>> builder.write(buildPath)
+  Traceback (most recent call last):
+  ...
+  FileExistsException
+
+So we can optionally force a rebuild:
+
+  >>> builder.write(buildPath, force=True)
+
+  >>> ls(buildPath)
+  myproject/
+
+
+Buildout Project
+----------------
+
+An extension to the simple project builder is the `BuildoutProjectBuilder`
+class, which provides a setup for buildout-based projects.
+
+  >>> builder = project.BuildoutProjectBuilder(u'myproject')
+  >>> builder
+  <BuildoutProjectBuilder u'myproject'>
+
+This object provides the ``IBuildoutProjectBuilder`` interface.
+
+  >>> verifyObject(interfaces.IBuildoutProjectBuilder, builder)
+  True
+
+In particular, this version of a project builder exposes several other
+builders:
+
+- Buildout Configuration Builder
+
+    >>> builder.buildout
+    <BuildoutConfigBuilder for u'myproject'>
+
+    >>> builder['buildout.cfg']
+    <BuildoutConfigBuilder for u'myproject'>
+
+  See `buildout.txt` for more details of this builder.
+
+- Setup Builder
+
+    >>> builder.setup
+    <SetupBuilder for u'myproject'>
+
+    >>> builder['setup.py']
+    <SetupBuilder for u'myproject'>
+
+  See `setup.txt` for more details of this builder.
+
+- Python Package Builder
+
+    >>> builder.package
+    <PackageBuilder u'myproject'>
+
+  Initially the name of the package builder is empty, until we update the
+  project builder:
+
+    >>> builder.update()
+    >>> builder.package
+    <PackageBuilder u'myproject'>
+
+The builder also installs a source directory builder, which does the package
+source setup.
+
+  >>> builder['src']
+  <SrcDirectoryBuilder for u'myproject'>
+
+Let's now render the project and see what it creates:
+
+  >>> builder.update()
+  >>> builder.write(buildPath, True)
+
+  >>> ls(buildPath)
+  myproject/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      myproject/
+        __init__.py
+
+Note that the project also installed the `bootstrap.py` file, which is used to
+initialize the buildout script.
+
+  >>> import os, shutil
+  >>> shutil.rmtree(os.path.join(buildPath, 'myproject'))
+
+Let's now create a project with a namespace and see what is being generated.
+
+  >>> builder = project.BuildoutProjectBuilder(u'z3c.myproject')
+  >>> builder
+  <BuildoutProjectBuilder u'z3c.myproject'>
+
+Let's now render the builder:
+
+  >>> builder.update()
+  >>> builder.write(buildPath, True)
+
+  >>> ls(buildPath)
+  z3c.myproject/
+    bootstrap.py
+    buildout.cfg
+    setup.py
+    src/
+      z3c/
+        __init__.py
+        myproject/
+          __init__.py
+
+Note that the source directory builder also correctly created the namespace
+`__init__.py` file:
+
+  >>> more(buildPath, 'z3c.myproject', 'src', 'z3c', '__init__.py')
+  try:
+      # Declare this a namespace package if pkg_resources is available.
+      import pkg_resources
+      pkg_resources.declare_namespace(__name__)
+  except ImportError:
+      pass
+
+Look in the other text files for more details on the various builders.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/project.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/python.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/python.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/python.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,329 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Python Builder Components
+
+$Id$
+"""
+import types
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+from z3c.builder.core import base, interfaces
+
+
+class ModuleBuilderGetter(object):
+    zope.interface.implements(interfaces.IModuleBuilderGetter)
+
+    def getModuleBuilder(self):
+        module = self
+        while not interfaces.IModuleBuilder.providedBy(module):
+            module = module.__parent__
+            if module is None:
+                raise ValueError(
+                    'No module builder was found and the root node of '
+                    'the project tree was reached.')
+        return module
+
+
+class PackageBuilder(base.DirectoryBuilder):
+    zope.interface.implements(interfaces.IPackageBuilder)
+
+    initTemplate = base.getTemplatePath('__init__.py')
+    initNamespaceTemplate = base.getTemplatePath('__init__namespace.py')
+    packageName = FieldProperty(interfaces.IPackageBuilder['packageName'])
+
+    def __init__(self, name, packageName=None):
+        if packageName is None:
+            packageName = str(name)
+        super(PackageBuilder, self).__init__(name, packageName)
+        self.packageName = packageName
+
+    def getPythonPath(self):
+        if interfaces.IPythonPathRoot.providedBy(self.__parent__):
+            return self.packageName
+        if self.__parent__ is None:
+            return self.packageName
+        return self.__parent__.getPythonPath() + '.' + str(self.packageName)
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        super(PackageBuilder, self).update()
+        matches = [subBuilder for subBuilder in self.values()
+                   if (interfaces.IFileBuilder.providedBy(subBuilder) and
+                       subBuilder.filename == '__init__.py')]
+        if matches:
+            return
+        template = self.initTemplate
+        try:
+            project = self.getProject()
+        except ValueError:
+            project = None
+        if project and self.getPythonPath() in project.setup.namespace_packages:
+            template = self.initNamespaceTemplate
+        self['__init__.py'] = base.SimpleFileBuilder(
+            u'__init__.py', template)
+
+
+class ModuleBuilder(base.BuilderContainer, base.FileBuilder):
+    zope.interface.implements(interfaces.IModuleBuilder)
+
+    moduleName = FieldProperty(interfaces.IModuleBuilder['moduleName'])
+    imports = FieldProperty(interfaces.IModuleBuilder['imports'])
+
+    def __init__(self, name, moduleName=None):
+        super(ModuleBuilder, self).__init__(name)
+        if moduleName is None:
+            moduleName = str(name)[:-3]
+        self.moduleName = moduleName
+        self.filename = str(name)
+
+    def getPythonPath(self):
+        return self.__parent__.getPythonPath() + '.' + str(self.moduleName)
+
+    def update(self):
+        self.imports = []
+        super(ModuleBuilder, self).update()
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        output = []
+        # Render comment header.
+        project = self.getProject()
+        output.append(project.commentHeader)
+        # Render module doc string.
+        output.append('"""Module Documentation"""\n')
+        # Render imports making sure none is duplicated.
+        for path in sorted(set(self.imports)):
+            module, name = tuple(path.rsplit('.', 1))
+            if module != self.getPythonPath():
+                output.append('from %s import %s\n' % (module, name))
+        output.append('\n\n')
+        # Render all sub-builders.
+        for subBuilder in self.values():
+            output.append(subBuilder.render())
+            output.append('\n\n')
+        # Return a concatenated version of all pieces.
+        return ''.join(output)
+
+
+class FieldBuilder(ModuleBuilderGetter, base.ContentBuilder):
+    zope.interface.implements(interfaces.IFieldBuilder)
+
+    fieldName = FieldProperty(interfaces.IFieldBuilder['fieldName'])
+    type = FieldProperty(interfaces.IFieldBuilder['type'])
+    attributes = FieldProperty(interfaces.IFieldBuilder['attributes'])
+    indent = FieldProperty(interfaces.IFieldBuilder['indent'])
+
+    _numberOfSpaces = 4
+
+    def __init__(self, name, type, indent=0, **attributes):
+        self.name = name
+        self.type = type
+        self.indent = indent
+        self.attributes = attributes
+
+    def update(self):
+        self.getModuleBuilder().imports.append(self.type)
+
+    def render(self):
+        indent = ' ' * (self.indent * self._numberOfSpaces)
+        output = ''
+        output += indent + '%s = %s(' %(self.name, self.type.rsplit('.')[-1])
+        if self.attributes:
+            output += '\n'
+        indent += ' ' * (self._numberOfSpaces)
+        for item in reversed(self.attributes.items()):
+            output += indent + '%s=%r,\n' %item
+        if self.attributes:
+            output += indent
+        output += ')\n'
+        return output
+
+
+class FunctionBuilder(ModuleBuilderGetter, base.ContentBuilder):
+    zope.interface.implements(interfaces.IFunctionBuilder)
+
+    fieldName = FieldProperty(interfaces.IFieldBuilder['fieldName'])
+    type = FieldProperty(interfaces.IFieldBuilder['type'])
+    attributes = FieldProperty(interfaces.IFieldBuilder['attributes'])
+    indent = FieldProperty(interfaces.IFieldBuilder['indent'])
+
+    _numberOfSpaces = 4
+
+    def __init__(self, name, args=(), kwargs=None,
+                 docstring='', indent=0, code=''):
+        self.name = name
+        self.args = args
+        self.kwargs = (kwargs and dict(kwargs)) or {}
+        self.docstring = docstring
+        self.indent = indent
+        self.code = code
+
+    def render(self):
+        # Generate the proper indentation level.
+        indent = ' ' * (self.indent * self._numberOfSpaces)
+        output = ''
+        # Render the first part of the function header.
+        output += indent+'def %s(' %str(self.name)
+        # Render the position arguments.
+        output += ', '.join([str(arg) for arg in self.args])
+        if self.args and self.kwargs:
+            output += ', '
+        # Render keyword arguments.
+        output += ', '.join(['%s=%r' %item for item in self.kwargs.items()])
+        output += '):\n'
+        # Render body of function
+        indent += self._numberOfSpaces * ' '
+        if self.docstring:
+            output += indent + '"""%s"""' %self.docstring
+        if self.code:
+            output += '\n'
+            for line in self.code.split('\n'):
+                output += indent + line + '\n'
+        if not self.code and not self.docstring:
+            output += indent + 'pass'
+        output += '\n'
+        return output
+
+
+class InterfaceBuilder(ModuleBuilderGetter,
+                       base.BuilderContainer, base.ContentBuilder):
+    zope.interface.implements(interfaces.IInterfaceBuilder)
+
+    docstring = FieldProperty(interfaces.IInterfaceBuilder['docstring'])
+    bases = FieldProperty(interfaces.IInterfaceBuilder['bases'])
+
+    def __init__(self, name):
+        super(InterfaceBuilder, self).__init__(name)
+        self.docstring = ''
+        self.bases = []
+
+    def add(self, builder):
+        if isinstance(builder, (FunctionBuilder, FieldBuilder)):
+            builder.indent = 1
+        return super(InterfaceBuilder, self).add(builder)
+
+    def getPythonPath(self):
+        return self.__parent__.getPythonPath() + '.' + str(self.name)
+
+    def update(self):
+        if len(self.bases) == 0:
+            self.bases = ['zope.interface.Interface']
+        self.getModuleBuilder().imports += self.bases
+        for builder in self.values():
+            builder.update()
+
+    def render(self):
+        bases = [path.rsplit('.', 1)[-1] for path in self.bases]
+        output = ''
+        output += 'class %s(%s):\n' %(str(self.name), ', '.join(bases))
+        output += '    """%s"""\n' %self.docstring
+        for builder in self.values():
+            output += builder.render()
+            output += '\n'
+        return output
+
+
+class ClassFromInterfaceBuilder(ModuleBuilderGetter, base.ContentBuilder):
+    zope.interface.implements(interfaces.IClassFromInterfaceBuilder)
+
+    interface = FieldProperty(
+        interfaces.IClassFromInterfaceBuilder['interface'])
+    bases = FieldProperty(
+        interfaces.IClassFromInterfaceBuilder['bases'])
+    docstring = FieldProperty(
+        interfaces.IClassFromInterfaceBuilder['docstring'])
+    implementations = FieldProperty(
+        interfaces.IClassFromInterfaceBuilder['implementations'])
+
+    def __init__(self, name, interface, bases=None):
+        super(ClassFromInterfaceBuilder, self).__init__(name)
+        self.interface = interface
+        self.bases = list(bases) if bases is not None else []
+        self.docstring = ''
+        self.implementations = {}
+
+    def _resolve(self, path):
+        pieces = path.split('.')
+        # Find package root.
+        root = self
+        while not interfaces.IPythonPathRoot.providedBy(root.__parent__):
+            root = root.__parent__
+        # Find builder
+        path = ''
+        builder = root
+        for piece in pieces:
+            if path:
+                path += '.'
+            path += piece
+            for sub in builder.values():
+                if (hasattr(sub, 'getPythonPath') and
+                    path == sub.getPythonPath()):
+                    builder = sub
+                    break
+        return builder
+
+    def addImplementation(self, name, code):
+        self.implementations[name] = code
+
+    def getPythonPath(self):
+        return self.__parent__.getPythonPath() + '.' + str(self.name)
+
+    def update(self):
+        # Determine the bases
+        if len(self.bases) == 0:
+            self.bases = ['object']
+        self.getModuleBuilder().imports += self.bases
+        # Compute the interface, if necessary
+        if isinstance(self.interface, types.StringTypes):
+            self.interface = self._resolve(self.interface)
+        # Add import for interface
+        self.__parent__.imports.append('zope.interface.implements')
+        self.__parent__.imports.append(self.interface.getPythonPath())
+        # Generate docstring if necessary
+        if not self.docstring:
+            self.docstring = "Implementation of ``%s``" % self.interface.getPythonPath()
+        # Generate fields and methods
+        self.fields = [entry for entry in self.interface.values()
+                       if isinstance(entry, FieldBuilder)]
+        self.methods = [entry for entry in self.interface.values()
+                       if isinstance(entry, FunctionBuilder)]
+        # Add imports if needed
+        if len(self.fields):
+            self.__parent__.imports.append(
+                'zope.schema.fieldproperty.FieldProperty')
+
+    def render(self):
+        bases = [path.rsplit('.', 1)[-1] for path in self.bases]
+        output = ''
+        output += 'class %s(%s):\n' %(self.name, ', '.join(bases))
+        output += '    """%s"""\n' %self.docstring
+        output += '    implements(%s)\n\n' %self.interface.name
+        for field in self.fields:
+            output += "    %s = FieldProperty(%s['%s'])\n" %(
+                field.name, self.interface.name, field.name)
+        output += '\n'
+        for method in self.methods:
+            output += '    def %s(' %method.name
+            allargs = ['self']
+            allargs += [str(arg) for arg in method.args]
+            allargs += ['%s=%r' %item for item in method.kwargs.items()]
+            output += ', '.join(allargs)
+            output += '):\n'
+            output += '        """See ``%s``."""\n' %self.interface.getPythonPath()
+            if method.name in self.implementations:
+                impl = self.implementations[method.name]
+                output += ' '*8
+                output += impl.replace('\n', '\n'+' '*8)
+            output += '\n'
+        return output


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/python.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/python.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/python.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/python.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,466 @@
+====================
+Python Code Builders
+====================
+
+The `python.py` module contains a collection of builders that help building
+Python code.
+
+  >>> from z3c.builder.core import interfaces, python
+
+This document is split up into several section, each concentrating on a
+different aspect of code generation.
+
+Package Builders
+----------------
+
+Package builders generate directories that act as Python packages by also
+adding an `__init__.py` file.
+
+  >>> pkg = python.PackageBuilder(u'project')
+  >>> pkg
+  <PackageBuilder u'project'>
+
+The name is also automatically the package name.
+
+  >>> pkg.packageName
+  'project'
+
+However, you can instantiate the builder also with a separate builder and
+package name:
+
+  >>> pkg = python.PackageBuilder(u'my.project', 'project')
+  >>> pkg
+  <PackageBuilder u'my.project'>
+
+Of course, the package builder implements the `IPackageBuilder` interface:
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IPackageBuilder, pkg)
+  True
+
+Let's now update the builder.
+
+  >>> pkg.update()
+
+When no `__init__.py` file was manually added to the package builder, the
+update procedure will do that for you:
+
+  >>> pkg.keys()
+  ['__init__.py']
+
+Let's now write out the directory:
+
+  >>> pkg.write(buildPath)
+
+  >>> ls(buildPath)
+  project/
+    __init__.py
+
+  >>> more(buildPath, 'project', '__init__.py')
+  # Make a package.
+  <BLANKLINE>
+
+We can also ask a package for its full Python path:
+
+  >>> pkg.getPythonPath()
+  'project'
+
+Let's now add a sub-package:
+
+  >>> sub = python.PackageBuilder(u'rest')
+  >>> pkg.add(sub)
+  u'rest'
+
+  >>> sub.getPythonPath()
+  'project.rest'
+
+
+Module Builders
+---------------
+
+Let's now have a look at module builders, which create Python code files.
+
+  >>> module = python.ModuleBuilder(u'code.py')
+  >>> module
+  <ModuleBuilder u'code.py'>
+
+  >>> module.moduleName
+  'code'
+
+Of course, the module builder implements the `IModuleBuilder` interface:
+
+  >>> verifyObject(interfaces.IModuleBuilder, module)
+  True
+
+Once we add the module builder to the package, we can ask for the Python path:
+
+  >>> pkg.add(module)
+  u'code.py'
+
+  >>> module.getPythonPath()
+  'project.code'
+
+We can now render the module:
+
+  >>> module.update()
+  >>> print module.render()
+  Traceback (most recent call last):
+  ...
+  ValueError: No project builder was found and the root node of the
+              project tree was reached.
+
+It failed because we need to be able to reach a project:
+
+  >>> from z3c.builder.core import project
+  >>> prj = project.ProjectBuilder(u'my.project')
+  >>> prj.update()
+  >>> pkg.__parent__ = prj
+  >>> from zope.interface import alsoProvides
+  >>> alsoProvides(prj, interfaces.IPythonPathRoot)
+  >>> module.update()
+  >>> print module.render()
+  ##############################################################################
+  #
+  # This file is part of my.project...
+  #
+  ##############################################################################
+  """Module Documentation"""
+
+We will later render the module again, once the module builder contains other
+code builders.
+
+
+Function Builder
+----------------
+
+The simplest code to generate is a function.
+
+  >>> func = python.FunctionBuilder(
+  ...     name=u'add',
+  ...     args=('x', 'y'),
+  ...     kwargs={'base': None},
+  ...     docstring='Add two numbers.',
+  ...     code='return x+y if base == None else (x+y)%base')
+  >>> func
+  <FunctionBuilder u'add'>
+
+The arguments should all be obvious. Of course, the function builder implements
+the `IFunctionBuilder` interface:
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IFunctionBuilder, func)
+  True
+
+Let's now render the function:
+
+  >>> func.update()
+  >>> print func.render()
+  def add(x, y, base=None):
+      """Add two numbers."""
+      return x+y if base == None else (x+y)%base
+
+Let's make sure that the function as generated workd:
+
+  >>> exec func.render()
+  >>> add(3, 4)
+  7
+  >>> add(3, 4, 5)
+  2
+
+Let's try a few different configurations now:
+
+- The simplest possible function:
+
+  >>> testFunc = python.FunctionBuilder(
+  ...     name=u'test')
+  >>> testFunc.update()
+  >>> print testFunc.render()
+  def test():
+      pass
+
+- Function with arguments:
+
+  >>> testFunc.args = ('x',)
+  >>> print testFunc.render()
+  def test(x):
+      pass
+
+  >>> testFunc.args = ('x', 'y')
+  >>> print testFunc.render()
+  def test(x, y):
+      pass
+
+- Function with keyword arguments:
+
+  >>> testFunc.args = ()
+
+  >>> testFunc.kwargs = {'x': 1}
+  >>> print testFunc.render()
+  def test(x=1):
+      pass
+
+  >>> testFunc.kwargs = {'x': 1, 'y': None}
+  >>> print testFunc.render()
+  def test(y=None, x=1):
+      pass
+
+- Function with docstring:
+
+  >>> testFunc.kwargs = {}
+
+  >>> testFunc.docstring = 'documentation'
+  >>> print testFunc.render()
+  def test():
+      """documentation"""
+
+- Function with code:
+
+  >>> testFunc.docstring = ''
+
+  >>> testFunc.code = 'return 1'
+  >>> print testFunc.render()
+  def test():
+      return 1
+
+There is also an `indent` attribute that allows one to place the function
+inside a class or interface. But testing that makes only sense, once we
+demonstrate the interface and class builder.
+
+
+Interface Builder
+-----------------
+
+The interface builder constructs an interface compatible with interfaces of
+the `zope.interface` package.
+
+  >>> iface = python.InterfaceBuilder(u'IProject')
+  >>> iface
+  <InterfaceBuilder u'IProject'>
+
+Of course, the interface builder implements the `IInterfaceBuilder` interface:
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IInterfaceBuilder, iface)
+  True
+
+Let's render the interface now:
+
+  >>> iface.update()
+  Traceback (most recent call last):
+  ...
+  ValueError: No module builder was found and the root node of the
+              project tree was reached.
+
+The rendering failed, because an interface builder must be added to a module
+before rendering.
+
+  >>> module.add(iface)
+  u'IProject'
+
+  >>> module.update()
+  >>> print iface.render()
+  class IProject(Interface):
+      """"""
+
+Once the module is set, we can also ask for the interface's Python path:
+
+  >>> iface.getPythonPath()
+  'project.code.IProject'
+
+Now, when rendering the module, the import for the `Interface` meta-class is
+already added.
+
+  >>> print module.render()
+  ##############################################################################
+  #
+  # This file is part of my.project...
+  #
+  ##############################################################################
+  """Module Documentation"""
+  from zope.interface import Interface
+  <BLANKLINE>
+  class IProject(Interface):
+      """"""
+
+Let's now add a function to the interface and see what happens:
+
+  >>> iface.add(python.FunctionBuilder(u'do'))
+  u'do'
+
+  >>> iface.update()
+  >>> print iface.render()
+  class IProject(Interface):
+      """"""
+      def do():
+          pass
+
+Let's now add a docstring and a "real" base interface to the interfac buider:
+
+  >>> iface.docstring = 'Documentation'
+  >>> iface.bases = ['zope.app.container.interfaces.IContainer']
+
+  >>> module.update()
+  >>> print module.render()
+  ##############################################################################
+  #
+  # This file is part of my.project...
+  #
+  ##############################################################################
+  """Module Documentation"""
+  from zope.app.container.interfaces import IContainer
+  <BLANKLINE>
+  class IProject(IContainer):
+      """Documentation"""
+      def do():
+          pass
+
+Finally, we add some fields:
+
+  >>> iface.add(python.FieldBuilder(
+  ...     name=u'state',
+  ...     type='zope.schema.Field'))
+  u'state'
+
+Now let's render the module again:
+
+  >>> module.update()
+  >>> print module.render()
+  ##############################################################################
+  #
+  # This file is part of my.project...
+  #
+  ##############################################################################
+  """Module Documentation"""
+  from zope.app.container.interfaces import IContainer
+  from zope.schema import Field
+  <BLANKLINE>
+  class IProject(IContainer):
+      """Documentation"""
+      def do():
+          pass
+  <BLANKLINE>
+      state = Field()
+
+Let's now create a field with several attributes:
+
+  >>> field = python.FieldBuilder(
+  ...     name=u'number',
+  ...     type='zope.schema.Int',
+  ...     title=u'Number',
+  ...     description=u'The number.',
+  ...     min=0,
+  ...     max=10,
+  ...     default=5)
+  >>> field.__parent__ = module
+
+  >>> field.update()
+  >>> print field.render()
+  number = Int(
+      title=u'Number',
+      description=u'The number.',
+      min=0,
+      max=10,
+      default=5,
+      )
+
+Of course, the field builder implements the `IFieldBuilder` interface:
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IFieldBuilder, field)
+  True
+
+The field builder does not attempt to validate any of the attribute names or
+values. It is assumed that the callee knows what it is doing.
+
+
+Class Generator
+---------------
+
+The `ClassFromInterfaceBuilder` builder renders a class from a given interface
+builder.
+
+  >>> cls = python.ClassFromInterfaceBuilder(
+  ...     u'Project', iface)
+  >>> cls
+  <ClassFromInterfaceBuilder u'Project'>
+
+Of course, the class builder implements the `IClassFromInterfaceBuilder`
+interface:
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IClassFromInterfaceBuilder, cls)
+  True
+
+Once the class has a module, we can also get its Python path:
+
+  >>> module.add(cls)
+  u'Project'
+  >>> cls.getPythonPath()
+  'project.code.Project'
+
+Let's now render the class:
+
+    >>> cls.update()
+    >>> print cls.render()
+    class Project(object):
+        """Implementation of ``project.code.IProject``"""
+        implements(IProject)
+    <BLANKLINE>
+        state = FieldProperty(IProject['state'])
+    <BLANKLINE>
+        def do(self):
+            """See ``project.code.IProject``."""
+
+We can also add an implementation for our function:
+
+    >>> cls.addImplementation('do', 'return 1')
+
+    >>> cls.update()
+    >>> print cls.render()
+    class Project(object):
+        """Implementation of ``project.code.IProject``"""
+        implements(IProject)
+    <BLANKLINE>
+        state = FieldProperty(IProject['state'])
+    <BLANKLINE>
+        def do(self):
+            """See ``project.code.IProject``."""
+            return 1
+
+Alternatively, we can instantiate the builder from a dotted name of the
+interface builder.
+
+  >>> cls = python.ClassFromInterfaceBuilder(
+  ...     u'Project', 'project.code.IProject')
+
+  >>> del module['Project']
+  >>> module.add(cls)
+  u'Project'
+
+The path is not immediately converted to an interface builder. You have to
+call update for this to happen:
+
+  >>> cls.interface
+  'project.code.IProject'
+
+  >>> cls.update()
+
+  >>> cls.interface
+  <InterfaceBuilder u'IProject'>
+
+Let's just render the class one more time:
+
+    >>> cls.docstring = 'Simple IProject implementation.'
+
+    >>> cls.update()
+    >>> print cls.render()
+    class Project(object):
+        """Simple IProject implementation."""
+        implements(IProject)
+    <BLANKLINE>
+        state = FieldProperty(IProject['state'])
+    <BLANKLINE>
+        def do(self):
+            """See ``project.code.IProject``."""
+
+That's it.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/python.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/setup.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/setup.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/setup.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,130 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Representation of the setup.py file.
+
+$Id$
+"""
+import types
+import pprint
+import zope.interface
+from rwproperty import getproperty
+from zope.schema.fieldproperty import FieldProperty
+from zope.container.sample import SampleContainer
+from zope.container.contained import Contained
+from zope.location.location import locate
+
+from z3c.builder.core import base, buildout, interfaces
+
+class SetupBuilder(base.FileBuilder):
+    zope.interface.implements(interfaces.ISetupBuilder)
+
+    version = FieldProperty(interfaces.ISetupBuilder['version'])
+    license = FieldProperty(interfaces.ISetupBuilder['license'])
+    author = FieldProperty(interfaces.ISetupBuilder['author'])
+    author_email = FieldProperty(interfaces.ISetupBuilder['author_email'])
+    description = FieldProperty(interfaces.ISetupBuilder['description'])
+    keywords = FieldProperty(interfaces.ISetupBuilder['keywords'])
+    url = FieldProperty(interfaces.ISetupBuilder['url'])
+    classifiers = FieldProperty(
+        interfaces.ISetupBuilder['classifiers'])
+    namespace_packages = FieldProperty(
+        interfaces.ISetupBuilder['namespace_packages'])
+    install_requires = FieldProperty(
+        interfaces.ISetupBuilder['install_requires'])
+    extras_requires = FieldProperty(
+        interfaces.ISetupBuilder['extras_require'])
+    entry_points = FieldProperty(
+        interfaces.ISetupBuilder['entry_points'])
+
+    def __init__(self):
+        super(SetupBuilder, self).__init__(u'setup.py')
+        self.keywords = []
+        self.namespace_packages = []
+        self.install_requires = []
+        self.classifiers = []
+        self.extras_requires = {}
+        self.entry_points = {}
+
+    def addExtrasRequires(self, name, requirements):
+        """See interfaces.ISetupBuilder"""
+        self.extras_requires.setdefault(name, [])
+        self.extras_requires[name] = list(
+            set(self.extras_requires[name]).union(requirements))
+
+    def removeExtrasRequires(self, name):
+        """See interfaces.ISetupBuilder"""
+        del self.extras_requires[name]
+
+    def addEntryPoints(self, name, entries):
+        """See interfaces.ISetupBuilder"""
+        self.entry_points.setdefault(name, [])
+        self.entry_points[name] = list(
+            set(self.entry_points[name]).union(entries))
+
+    def removeEntryPoints(self, name):
+        """See interfaces.ISetupBuilder"""
+        del self.entry_points[name]
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        project = self.getProject()
+        if not self.url:
+            self.url = u'http://pypi.python.org/pypi/%s' % project.name
+        # Update the namespace packages.
+        if not self.namespace_packages:
+            pieces = project.name.split('.')[:-1]
+            pieces.reverse()
+            ns = []
+            while pieces:
+                ns.append(pieces.pop())
+                self.namespace_packages.append('.'.join(ns))
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        template = open(base.getTemplatePath('setup.py'), 'r').read()
+        project = self.getProject()
+        data = dict(
+            commentHeader=project.commentHeader.strip(),
+            name=project.name,
+            version=self.version,
+            license=self.license,
+            author=self.author,
+            author_email=self.author_email,
+            description=self.description,
+            url=self.url,
+            keywords=' '.join(self.keywords),
+            namespacePackages='',
+            )
+        if self.namespace_packages:
+            data['namespacePackages'] = ','.join(
+                map(repr, self.namespace_packages))
+
+        requirementsStr = ''
+        for requirement in self.install_requires:
+            requirementsStr += '\n        %r,' % requirement
+        data['install_requires'] = requirementsStr
+
+        data['extras_require'] = pprint.pformat(
+            self.extras_requires, width=1)
+
+        data['entry_points'] = pprint.pformat(
+            self.entry_points, width=1)
+
+        data['classifiers'] = pprint.pformat(
+            self.classifiers, width=1)
+
+        return template % data
+
+    def __repr__(self):
+        return '<%s for %r>' %(self.__class__.__name__, self.getProject().name)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/setup.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/setup.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/setup.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/setup.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,221 @@
+=================
+The Setup Builder
+=================
+
+This builder creates a Python project's or package's `setup.py` file. This
+file contains build meta data necessary to make the package a proper egg.
+
+  >>> from z3c.builder.core import interfaces, setup
+  >>> builder = setup.SetupBuilder()
+
+This object provides the ``ISetupBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.ISetupBuilder, builder)
+  True
+
+Like most builders, this builder also expects to be able to reach its project
+builder:
+
+  >>> from z3c.builder.core import project
+  >>> builder.__parent__ = project.ProjectBuilder(u'z3c.myproject')
+  >>> builder
+  <SetupBuilder for u'z3c.myproject'>
+
+Let's now render the file to see what it does out of the box:
+
+  >>> builder.update()
+  >>> builder.__parent__.update()
+  >>> print builder.render()
+  ##############################################################################
+  #
+  # This file is part of z3c.myproject. ...
+  #
+  ##############################################################################
+  """Setup"""
+  from setuptools import setup, find_packages
+  <BLANKLINE>
+  setup (
+      name = 'z3c.myproject',
+      version = '0.1.0',
+      author = u"",
+      author_email = u"",
+      description = u"",
+      license = "GPLv3",
+      keywords = u"",
+      url = "http://pypi.python.org/pypi/z3c.myproject",
+      classifiers = [],
+      packages = find_packages('src'),
+      include_package_data = True,
+      package_dir = {'':'src'},
+      namespace_packages = [u'z3c'],
+      extras_require = {},
+      install_requires = [
+          'setuptools',
+          ],
+      zip_safe = False,
+      entry_points = {},
+      )
+
+Note that the namespace packages argument is automatically populated. Let's
+now specify a little bit more data:
+
+  >>> builder.author = u'Paul and Stephan'
+  >>> builder.description = u'My Project'
+  >>> builder.keywords = [u'sample', u'python', u'project']
+  >>> builder.install_requires.append('zope.component')
+  >>> builder.addExtrasRequires(
+  ...     'test', ('zope.testing', 'zope.testbrowser'))
+
+So let's render this builder again.
+
+  >>> builder.update()
+  >>> builder.__parent__.update()
+  >>> print builder.render()
+  ##############################################################################
+  #
+  # This file is part of z3c.myproject. ...
+  #
+  ##############################################################################
+  """Setup"""
+  from setuptools import setup, find_packages
+  <BLANKLINE>
+  setup (
+      name = 'z3c.myproject',
+      version = '0.1.0',
+      author = u"Paul and Stephan",
+      author_email = u"",
+      description = u"My Project",
+      license = "GPLv3",
+      keywords = u"sample python project",
+      url = "http://pypi.python.org/pypi/z3c.myproject",
+      classifiers = [],
+      packages = find_packages('src'),
+      include_package_data = True,
+      package_dir = {'':'src'},
+      namespace_packages = [u'z3c'],
+      extras_require = {'test': ['zope.testing',
+            'zope.testbrowser']},
+      install_requires = [
+          'setuptools',
+          'zope.component',
+          ],
+      zip_safe = False,
+      entry_points = {},
+      )
+
+You can also remove an extra requires section:
+
+  >>> builder.removeExtrasRequires('test')
+
+  >>> builder.update()
+  >>> print builder.render()
+  ##############################################################################
+  #
+  # This file is part of z3c.myproject. ...
+  #
+  ##############################################################################
+  """Setup"""
+  from setuptools import setup, find_packages
+  <BLANKLINE>
+  setup (
+      name = 'z3c.myproject',
+      version = '0.1.0',
+      author = u"Paul and Stephan",
+      author_email = u"",
+      description = u"My Project",
+      license = "GPLv3",
+      keywords = u"sample python project",
+      url = "http://pypi.python.org/pypi/z3c.myproject",
+      classifiers = [],
+      packages = find_packages('src'),
+      include_package_data = True,
+      package_dir = {'':'src'},
+      namespace_packages = [u'z3c'],
+      extras_require = {},
+      install_requires = [
+          'setuptools',
+          'zope.component',
+          ],
+      zip_safe = False,
+      entry_points = {},
+      )
+
+Let's now add a console script entry point:
+
+  >>> builder.addEntryPoints(
+  ...     'console_script', ('z3c.myproject.script:main',)
+  ...     )
+
+  >>> builder.update()
+  >>> print builder.render()
+  ##############################################################################
+  #
+  # This file is part of z3c.myproject...
+  #
+  ##############################################################################
+  """Setup"""
+  from setuptools import setup, find_packages
+  <BLANKLINE>
+  setup (
+      name = 'z3c.myproject',
+      version = '0.1.0',
+      author = u"Paul and Stephan",
+      author_email = u"",
+      description = u"My Project",
+      license = "GPLv3",
+      keywords = u"sample python project",
+      url = "http://pypi.python.org/pypi/z3c.myproject",
+      classifiers = [],
+      packages = find_packages('src'),
+      include_package_data = True,
+      package_dir = {'':'src'},
+      namespace_packages = [u'z3c'],
+      extras_require = {},
+      install_requires = [
+          'setuptools',
+          'zope.component',
+          ],
+      zip_safe = False,
+      entry_points = {'console_script': ['z3c.myproject.script:main']},
+      )
+
+Let's remove the entry point again:
+
+  >>> builder.removeEntryPoints('console_script')
+
+  >>> builder.update()
+  >>> print builder.render()
+  ##############################################################################
+  #
+  # This file is part of z3c.myproject. ...
+  #
+  ##############################################################################
+  """Setup"""
+  from setuptools import setup, find_packages
+  <BLANKLINE>
+  setup (
+      name = 'z3c.myproject',
+      version = '0.1.0',
+      author = u"Paul and Stephan",
+      author_email = u"",
+      description = u"My Project",
+      license = "GPLv3",
+      keywords = u"sample python project",
+      url = "http://pypi.python.org/pypi/z3c.myproject",
+      classifiers = [],
+      packages = find_packages('src'),
+      include_package_data = True,
+      package_dir = {'':'src'},
+      namespace_packages = [u'z3c'],
+      extras_require = {},
+      install_requires = [
+          'setuptools',
+          'zope.component',
+          ],
+      zip_safe = False,
+      entry_points = {},
+      )
+
+And that's it. This simple implementation does not support setting up
+arbitrarily complex build instructions.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/setup.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/testing.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/testing.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/testing.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,102 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test Helpers
+
+$Id$
+"""
+import logging
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+from z3c.builder.core import base
+
+class TestingHandler(logging.StreamHandler):
+
+    def __init__(self):
+        logging.StreamHandler.__init__(self, sys.stdout)
+
+    def flush(self):
+        self.stream = sys.stdout
+        logging.StreamHandler.flush(self)
+
+    def emit(self, record):
+        self.stream = sys.stdout
+        logging.StreamHandler.emit(self, record)
+
+
+def formatDirListing(path):
+    result = ''
+    listing = os.listdir(path)
+    files = filter(lambda x: os.path.isfile(os.path.join(path, x)), listing)
+    files.sort()
+    dirs = filter(lambda x: os.path.isdir(os.path.join(path, x)), listing)
+    dirs.sort()
+    result += '\n'.join(files)
+    if dirs and files:
+        result += '\n'
+    for name in dirs:
+        subPath = os.path.join(path, name)
+        result += '%s/\n' % name
+        result += '  '+formatDirListing(subPath).replace('\n','\n  ')
+    return result
+
+def ls(path, *args):
+    path = os.path.join(path, *args)
+    print formatDirListing(path)
+
+def more(*args):
+    path = os.path.join(*args)
+    print open(path, 'r').read()
+
+def clear(path):
+    shutil.rmtree(path)
+    os.mkdir(path)
+
+def cmd(args, cwd):
+    outputFilename = tempfile.mktemp()
+    output = open(outputFilename, 'w')
+    cmd = subprocess.Popen(args, cwd=cwd, stdout=output, stderr=output)
+    status = cmd.wait()
+    print 'Exit Status: ' + str(status)
+    output.close()
+    return open(outputFilename, 'r').read()
+
+def buildSetUp(test):
+    fn = tempfile.mktemp()
+    test.globs.update(
+        {'buildPath': fn,
+         'cmd': cmd,
+         'more': more,
+         'ls':ls,
+         'clear': clear})
+    os.mkdir(fn)
+
+def buildTearDown(test):
+    shutil.rmtree(test.globs['buildPath'])
+
+def loggerSetUp(test, level=logging.DEBUG, stream=None):
+    test._oldLevel = base.logger.level
+    if stream is None:
+        test._handler = TestingHandler()
+    else:
+        test._handler = logging.StreamHandler(stream)
+    base.logger.setLevel(level)
+    base.logger.addHandler(test._handler)
+
+
+def loggerTearDown(test):
+    base.logger.setLevel(test._oldLevel)
+    base.logger.removeHandler(test._handler)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/testing.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/tests/__init__.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/tests/__init__.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/tests/__init__.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1 @@
+#package


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/tests/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/tests/test_doc.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/tests/test_doc.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/tests/test_doc.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,101 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test Setup.
+
+$Id$
+"""
+import os
+import re
+import shutil
+import sys
+import unittest
+import tempfile
+import logging
+import subprocess
+import tempfile
+import zope.component
+from zope.configuration import xmlconfig
+from zope.testing import renormalizing, doctest
+
+from z3c.builder.core import base, testing
+
+def fullSetUp(test):
+    testing.buildSetUp(test)
+    testing.loggerSetUp(test)
+
+def fullTearDown(test):
+    testing.buildTearDown(test)
+    testing.loggerTearDown(test)
+
+def test_suite():
+    checker = renormalizing.RENormalizing([
+       (re.compile(
+            '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{6}'),
+            '<DATETIME>'),
+       (re.compile(
+            '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'),
+            '<UUID>'),
+       ])
+
+    return unittest.TestSuite((
+
+        doctest.DocFileSuite(
+            '../README.txt',
+            setUp=fullSetUp, tearDown=fullTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../project.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../python.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../setup.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../buildout.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../zcml.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../form.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            checker=checker),
+
+        doctest.DocFileSuite(
+            '../example.txt',
+            setUp=testing.buildSetUp, tearDown=testing.buildTearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS|doctest.REPORT_NDIFF,
+            checker=checker),
+
+        ))


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/tests/test_doc.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/trove-classifiers.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/trove-classifiers.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/trove-classifiers.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,534 @@
+Development Status :: 1 - Planning
+Development Status :: 2 - Pre-Alpha
+Development Status :: 3 - Alpha
+Development Status :: 4 - Beta
+Development Status :: 5 - Production/Stable
+Development Status :: 6 - Mature
+Development Status :: 7 - Inactive
+Environment :: Console
+Environment :: Console :: Curses
+Environment :: Console :: Framebuffer
+Environment :: Console :: Newt
+Environment :: Console :: svgalib
+Environment :: Handhelds/PDA's
+Environment :: MacOS X
+Environment :: MacOS X :: Aqua
+Environment :: MacOS X :: Carbon
+Environment :: MacOS X :: Cocoa
+Environment :: No Input/Output (Daemon)
+Environment :: Other Environment
+Environment :: Plugins
+Environment :: Web Environment
+Environment :: Web Environment :: Buffet
+Environment :: Web Environment :: Mozilla
+Environment :: Web Environment :: ToscaWidgets
+Environment :: Win32 (MS Windows)
+Environment :: X11 Applications
+Environment :: X11 Applications :: Gnome
+Environment :: X11 Applications :: GTK
+Environment :: X11 Applications :: KDE
+Environment :: X11 Applications :: Qt
+Framework :: Buildout
+Framework :: Chandler
+Framework :: Django
+Framework :: IDLE
+Framework :: Paste
+Framework :: Plone
+Framework :: Pylons
+Framework :: Setuptools Plugin
+Framework :: Trac
+Framework :: TurboGears
+Framework :: TurboGears :: Applications
+Framework :: TurboGears :: Widgets
+Framework :: Twisted
+Framework :: ZODB
+Framework :: Zope2
+Framework :: Zope3
+Intended Audience :: Customer Service
+Intended Audience :: Developers
+Intended Audience :: Education
+Intended Audience :: End Users/Desktop
+Intended Audience :: Financial and Insurance Industry
+Intended Audience :: Healthcare Industry
+Intended Audience :: Information Technology
+Intended Audience :: Legal Industry
+Intended Audience :: Manufacturing
+Intended Audience :: Other Audience
+Intended Audience :: Religion
+Intended Audience :: Science/Research
+Intended Audience :: System Administrators
+Intended Audience :: Telecommunications Industry
+License :: Aladdin Free Public License (AFPL)
+License :: DFSG approved
+License :: Eiffel Forum License (EFL)
+License :: Free For Educational Use
+License :: Free For Home Use
+License :: Free for non-commercial use
+License :: Freely Distributable
+License :: Free To Use But Restricted
+License :: Freeware
+License :: Netscape Public License (NPL)
+License :: Nokia Open Source License (NOKOS)
+License :: OSI Approved
+License :: OSI Approved :: Academic Free License (AFL)
+License :: OSI Approved :: Apache Software License
+License :: OSI Approved :: Apple Public Source License
+License :: OSI Approved :: Artistic License
+License :: OSI Approved :: Attribution Assurance License
+License :: OSI Approved :: BSD License
+License :: OSI Approved :: Common Public License
+License :: OSI Approved :: Eiffel Forum License
+License :: OSI Approved :: GNU Affero General Public License v3
+License :: OSI Approved :: GNU Free Documentation License (FDL)
+License :: OSI Approved :: GNU General Public License (GPL)
+License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
+License :: OSI Approved :: IBM Public License
+License :: OSI Approved :: Intel Open Source License
+License :: OSI Approved :: Jabber Open Source License
+License :: OSI Approved :: MIT License
+License :: OSI Approved :: MITRE Collaborative Virtual Workspace License (CVW)
+License :: OSI Approved :: Motosoto License
+License :: OSI Approved :: Mozilla Public License 1.0 (MPL)
+License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)
+License :: OSI Approved :: Nethack General Public License
+License :: OSI Approved :: Nokia Open Source License
+License :: OSI Approved :: Open Group Test Suite License
+License :: OSI Approved :: Python License (CNRI Python License)
+License :: OSI Approved :: Python Software Foundation License
+License :: OSI Approved :: Qt Public License (QPL)
+License :: OSI Approved :: Ricoh Source Code Public License
+License :: OSI Approved :: Sleepycat License
+License :: OSI Approved :: Sun Industry Standards Source License (SISSL)
+License :: OSI Approved :: Sun Public License
+License :: OSI Approved :: University of Illinois/NCSA Open Source License
+License :: OSI Approved :: Vovida Software License 1.0
+License :: OSI Approved :: W3C License
+License :: OSI Approved :: X.Net License
+License :: OSI Approved :: zlib/libpng License
+License :: OSI Approved :: Zope Public License
+License :: Other/Proprietary License
+License :: Public Domain
+Natural Language :: Afrikaans
+Natural Language :: Arabic
+Natural Language :: Bengali
+Natural Language :: Bosnian
+Natural Language :: Bulgarian
+Natural Language :: Catalan
+Natural Language :: Chinese (Simplified)
+Natural Language :: Chinese (Traditional)
+Natural Language :: Croatian
+Natural Language :: Czech
+Natural Language :: Danish
+Natural Language :: Dutch
+Natural Language :: English
+Natural Language :: Esperanto
+Natural Language :: Finnish
+Natural Language :: French
+Natural Language :: German
+Natural Language :: Greek
+Natural Language :: Hebrew
+Natural Language :: Hindi
+Natural Language :: Hungarian
+Natural Language :: Icelandic
+Natural Language :: Indonesian
+Natural Language :: Italian
+Natural Language :: Japanese
+Natural Language :: Javanese
+Natural Language :: Korean
+Natural Language :: Latin
+Natural Language :: Latvian
+Natural Language :: Macedonian
+Natural Language :: Malay
+Natural Language :: Marathi
+Natural Language :: Norwegian
+Natural Language :: Panjabi
+Natural Language :: Persian
+Natural Language :: Polish
+Natural Language :: Portuguese
+Natural Language :: Portuguese (Brazilian)
+Natural Language :: Romanian
+Natural Language :: Russian
+Natural Language :: Serbian
+Natural Language :: Slovak
+Natural Language :: Slovenian
+Natural Language :: Spanish
+Natural Language :: Swedish
+Natural Language :: Tamil
+Natural Language :: Telugu
+Natural Language :: Thai
+Natural Language :: Turkish
+Natural Language :: Ukranian
+Natural Language :: Urdu
+Natural Language :: Vietnamese
+Operating System :: BeOS
+Operating System :: MacOS
+Operating System :: MacOS :: MacOS 9
+Operating System :: MacOS :: MacOS X
+Operating System :: Microsoft
+Operating System :: Microsoft :: MS-DOS
+Operating System :: Microsoft :: Windows
+Operating System :: Microsoft :: Windows :: Windows 3.1 or Earlier
+Operating System :: Microsoft :: Windows :: Windows 95/98/2000
+Operating System :: Microsoft :: Windows :: Windows CE
+Operating System :: Microsoft :: Windows :: Windows NT/2000
+Operating System :: OS/2
+Operating System :: OS Independent
+Operating System :: Other OS
+Operating System :: PalmOS
+Operating System :: PDA Systems
+Operating System :: POSIX
+Operating System :: POSIX :: AIX
+Operating System :: POSIX :: BSD
+Operating System :: POSIX :: BSD :: BSD/OS
+Operating System :: POSIX :: BSD :: FreeBSD
+Operating System :: POSIX :: BSD :: NetBSD
+Operating System :: POSIX :: BSD :: OpenBSD
+Operating System :: POSIX :: GNU Hurd
+Operating System :: POSIX :: HP-UX
+Operating System :: POSIX :: IRIX
+Operating System :: POSIX :: Linux
+Operating System :: POSIX :: Other
+Operating System :: POSIX :: SCO
+Operating System :: POSIX :: SunOS/Solaris
+Operating System :: Unix
+Programming Language :: Ada
+Programming Language :: APL
+Programming Language :: ASP
+Programming Language :: Assembly
+Programming Language :: Awk
+Programming Language :: Basic
+Programming Language :: C
+Programming Language :: C#
+Programming Language :: C++
+Programming Language :: Cold Fusion
+Programming Language :: Delphi/Kylix
+Programming Language :: Dylan
+Programming Language :: Eiffel
+Programming Language :: Emacs-Lisp
+Programming Language :: Erlang
+Programming Language :: Euler
+Programming Language :: Euphoria
+Programming Language :: Forth
+Programming Language :: Fortran
+Programming Language :: Haskell
+Programming Language :: Java
+Programming Language :: JavaScript
+Programming Language :: Lisp
+Programming Language :: Logo
+Programming Language :: ML
+Programming Language :: Modula
+Programming Language :: Objective C
+Programming Language :: Object Pascal
+Programming Language :: OCaml
+Programming Language :: Other
+Programming Language :: Other Scripting Engines
+Programming Language :: Pascal
+Programming Language :: Perl
+Programming Language :: PHP
+Programming Language :: Pike
+Programming Language :: Pliant
+Programming Language :: PL/SQL
+Programming Language :: PROGRESS
+Programming Language :: Prolog
+Programming Language :: Python
+Programming Language :: Python :: 2
+Programming Language :: Python :: 2.3
+Programming Language :: Python :: 2.4
+Programming Language :: Python :: 2.5
+Programming Language :: Python :: 2.6
+Programming Language :: Python :: 2.7
+Programming Language :: Python :: 3
+Programming Language :: Python :: 3.0
+Programming Language :: Python :: 3.1
+Programming Language :: REBOL
+Programming Language :: Rexx
+Programming Language :: Ruby
+Programming Language :: Scheme
+Programming Language :: Simula
+Programming Language :: Smalltalk
+Programming Language :: SQL
+Programming Language :: Tcl
+Programming Language :: Unix Shell
+Programming Language :: Visual Basic
+Programming Language :: XBasic
+Programming Language :: YACC
+Programming Language :: Zope
+Topic :: Adaptive Technologies
+Topic :: Artistic Software
+Topic :: Communications
+Topic :: Communications :: BBS
+Topic :: Communications :: Chat
+Topic :: Communications :: Chat :: AOL Instant Messenger
+Topic :: Communications :: Chat :: ICQ
+Topic :: Communications :: Chat :: Internet Relay Chat
+Topic :: Communications :: Chat :: Unix Talk
+Topic :: Communications :: Conferencing
+Topic :: Communications :: Email
+Topic :: Communications :: Email :: Address Book
+Topic :: Communications :: Email :: Email Clients (MUA)
+Topic :: Communications :: Email :: Filters
+Topic :: Communications :: Email :: Mailing List Servers
+Topic :: Communications :: Email :: Mail Transport Agents
+Topic :: Communications :: Email :: Post-Office
+Topic :: Communications :: Email :: Post-Office :: IMAP
+Topic :: Communications :: Email :: Post-Office :: POP3
+Topic :: Communications :: Fax
+Topic :: Communications :: FIDO
+Topic :: Communications :: File Sharing
+Topic :: Communications :: File Sharing :: Gnutella
+Topic :: Communications :: File Sharing :: Napster
+Topic :: Communications :: Ham Radio
+Topic :: Communications :: Internet Phone
+Topic :: Communications :: Telephony
+Topic :: Communications :: Usenet News
+Topic :: Database
+Topic :: Database :: Database Engines/Servers
+Topic :: Database :: Front-Ends
+Topic :: Desktop Environment
+Topic :: Desktop Environment :: File Managers
+Topic :: Desktop Environment :: Gnome
+Topic :: Desktop Environment :: GNUstep
+Topic :: Desktop Environment :: K Desktop Environment (KDE)
+Topic :: Desktop Environment :: K Desktop Environment (KDE) :: Themes
+Topic :: Desktop Environment :: PicoGUI
+Topic :: Desktop Environment :: PicoGUI :: Applications
+Topic :: Desktop Environment :: PicoGUI :: Themes
+Topic :: Desktop Environment :: Screen Savers
+Topic :: Desktop Environment :: Window Managers
+Topic :: Desktop Environment :: Window Managers :: Afterstep
+Topic :: Desktop Environment :: Window Managers :: Afterstep :: Themes
+Topic :: Desktop Environment :: Window Managers :: Applets
+Topic :: Desktop Environment :: Window Managers :: Blackbox
+Topic :: Desktop Environment :: Window Managers :: Blackbox :: Themes
+Topic :: Desktop Environment :: Window Managers :: CTWM
+Topic :: Desktop Environment :: Window Managers :: CTWM :: Themes
+Topic :: Desktop Environment :: Window Managers :: Enlightenment
+Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Epplets
+Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR15
+Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR16
+Topic :: Desktop Environment :: Window Managers :: Enlightenment :: Themes DR17
+Topic :: Desktop Environment :: Window Managers :: Fluxbox
+Topic :: Desktop Environment :: Window Managers :: Fluxbox :: Themes
+Topic :: Desktop Environment :: Window Managers :: FVWM
+Topic :: Desktop Environment :: Window Managers :: FVWM :: Themes
+Topic :: Desktop Environment :: Window Managers :: IceWM
+Topic :: Desktop Environment :: Window Managers :: IceWM :: Themes
+Topic :: Desktop Environment :: Window Managers :: MetaCity
+Topic :: Desktop Environment :: Window Managers :: MetaCity :: Themes
+Topic :: Desktop Environment :: Window Managers :: Oroborus
+Topic :: Desktop Environment :: Window Managers :: Oroborus :: Themes
+Topic :: Desktop Environment :: Window Managers :: Sawfish
+Topic :: Desktop Environment :: Window Managers :: Sawfish :: Themes 0.30
+Topic :: Desktop Environment :: Window Managers :: Sawfish :: Themes pre-0.30
+Topic :: Desktop Environment :: Window Managers :: Waimea
+Topic :: Desktop Environment :: Window Managers :: Waimea :: Themes
+Topic :: Desktop Environment :: Window Managers :: Window Maker
+Topic :: Desktop Environment :: Window Managers :: Window Maker :: Applets
+Topic :: Desktop Environment :: Window Managers :: Window Maker :: Themes
+Topic :: Desktop Environment :: Window Managers :: XFCE
+Topic :: Desktop Environment :: Window Managers :: XFCE :: Themes
+Topic :: Documentation
+Topic :: Education
+Topic :: Education :: Computer Aided Instruction (CAI)
+Topic :: Education :: Testing
+Topic :: Games/Entertainment
+Topic :: Games/Entertainment :: Arcade
+Topic :: Games/Entertainment :: Board Games
+Topic :: Games/Entertainment :: First Person Shooters
+Topic :: Games/Entertainment :: Fortune Cookies
+Topic :: Games/Entertainment :: Multi-User Dungeons (MUD)
+Topic :: Games/Entertainment :: Puzzle Games
+Topic :: Games/Entertainment :: Real Time Strategy
+Topic :: Games/Entertainment :: Role-Playing
+Topic :: Games/Entertainment :: Side-Scrolling/Arcade Games
+Topic :: Games/Entertainment :: Simulation
+Topic :: Games/Entertainment :: Turn Based Strategy
+Topic :: Home Automation
+Topic :: Internet
+Topic :: Internet :: File Transfer Protocol (FTP)
+Topic :: Internet :: Finger
+Topic :: Internet :: Log Analysis
+Topic :: Internet :: Name Service (DNS)
+Topic :: Internet :: Proxy Servers
+Topic :: Internet :: WAP
+Topic :: Internet :: WWW/HTTP
+Topic :: Internet :: WWW/HTTP :: Browsers
+Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries
+Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Message Boards
+Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary
+Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Page Counters
+Topic :: Internet :: WWW/HTTP :: HTTP Servers
+Topic :: Internet :: WWW/HTTP :: Indexing/Search
+Topic :: Internet :: WWW/HTTP :: Site Management
+Topic :: Internet :: WWW/HTTP :: Site Management :: Link Checking
+Topic :: Internet :: WWW/HTTP :: WSGI
+Topic :: Internet :: WWW/HTTP :: WSGI :: Application
+Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
+Topic :: Internet :: WWW/HTTP :: WSGI :: Server
+Topic :: Internet :: Z39.50
+Topic :: Multimedia
+Topic :: Multimedia :: Graphics
+Topic :: Multimedia :: Graphics :: 3D Modeling
+Topic :: Multimedia :: Graphics :: 3D Rendering
+Topic :: Multimedia :: Graphics :: Capture
+Topic :: Multimedia :: Graphics :: Capture :: Digital Camera
+Topic :: Multimedia :: Graphics :: Capture :: Scanners
+Topic :: Multimedia :: Graphics :: Capture :: Screen Capture
+Topic :: Multimedia :: Graphics :: Editors
+Topic :: Multimedia :: Graphics :: Editors :: Raster-Based
+Topic :: Multimedia :: Graphics :: Editors :: Vector-Based
+Topic :: Multimedia :: Graphics :: Graphics Conversion
+Topic :: Multimedia :: Graphics :: Presentation
+Topic :: Multimedia :: Graphics :: Viewers
+Topic :: Multimedia :: Sound/Audio
+Topic :: Multimedia :: Sound/Audio :: Analysis
+Topic :: Multimedia :: Sound/Audio :: Capture/Recording
+Topic :: Multimedia :: Sound/Audio :: CD Audio
+Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Playing
+Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Ripping
+Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Writing
+Topic :: Multimedia :: Sound/Audio :: Conversion
+Topic :: Multimedia :: Sound/Audio :: Editors
+Topic :: Multimedia :: Sound/Audio :: MIDI
+Topic :: Multimedia :: Sound/Audio :: Mixers
+Topic :: Multimedia :: Sound/Audio :: Players
+Topic :: Multimedia :: Sound/Audio :: Players :: MP3
+Topic :: Multimedia :: Sound/Audio :: Sound Synthesis
+Topic :: Multimedia :: Sound/Audio :: Speech
+Topic :: Multimedia :: Video
+Topic :: Multimedia :: Video :: Capture
+Topic :: Multimedia :: Video :: Conversion
+Topic :: Multimedia :: Video :: Display
+Topic :: Multimedia :: Video :: Non-Linear Editor
+Topic :: Office/Business
+Topic :: Office/Business :: Financial
+Topic :: Office/Business :: Financial :: Accounting
+Topic :: Office/Business :: Financial :: Investment
+Topic :: Office/Business :: Financial :: Point-Of-Sale
+Topic :: Office/Business :: Financial :: Spreadsheet
+Topic :: Office/Business :: Groupware
+Topic :: Office/Business :: News/Diary
+Topic :: Office/Business :: Office Suites
+Topic :: Office/Business :: Scheduling
+Topic :: Other/Nonlisted Topic
+Topic :: Printing
+Topic :: Religion
+Topic :: Scientific/Engineering
+Topic :: Scientific/Engineering :: Artificial Intelligence
+Topic :: Scientific/Engineering :: Astronomy
+Topic :: Scientific/Engineering :: Atmospheric Science
+Topic :: Scientific/Engineering :: Bio-Informatics
+Topic :: Scientific/Engineering :: Chemistry
+Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
+Topic :: Scientific/Engineering :: GIS
+Topic :: Scientific/Engineering :: Human Machine Interfaces
+Topic :: Scientific/Engineering :: Image Recognition
+Topic :: Scientific/Engineering :: Information Analysis
+Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
+Topic :: Scientific/Engineering :: Mathematics
+Topic :: Scientific/Engineering :: Medical Science Apps.
+Topic :: Scientific/Engineering :: Physics
+Topic :: Scientific/Engineering :: Visualization
+Topic :: Security
+Topic :: Security :: Cryptography
+Topic :: Sociology
+Topic :: Sociology :: Genealogy
+Topic :: Sociology :: History
+Topic :: Software Development
+Topic :: Software Development :: Assemblers
+Topic :: Software Development :: Bug Tracking
+Topic :: Software Development :: Build Tools
+Topic :: Software Development :: Code Generators
+Topic :: Software Development :: Compilers
+Topic :: Software Development :: Debuggers
+Topic :: Software Development :: Disassemblers
+Topic :: Software Development :: Documentation
+Topic :: Software Development :: Embedded Systems
+Topic :: Software Development :: Internationalization
+Topic :: Software Development :: Interpreters
+Topic :: Software Development :: Libraries
+Topic :: Software Development :: Libraries :: Application Frameworks
+Topic :: Software Development :: Libraries :: Java Libraries
+Topic :: Software Development :: Libraries :: Perl Modules
+Topic :: Software Development :: Libraries :: PHP Classes
+Topic :: Software Development :: Libraries :: Pike Modules
+Topic :: Software Development :: Libraries :: Python Modules
+Topic :: Software Development :: Libraries :: Ruby Modules
+Topic :: Software Development :: Libraries :: Tcl Extensions
+Topic :: Software Development :: Localization
+Topic :: Software Development :: Object Brokering
+Topic :: Software Development :: Object Brokering :: CORBA
+Topic :: Software Development :: Pre-processors
+Topic :: Software Development :: Quality Assurance
+Topic :: Software Development :: Testing
+Topic :: Software Development :: Testing :: Traffic Generation
+Topic :: Software Development :: User Interfaces
+Topic :: Software Development :: Version Control
+Topic :: Software Development :: Version Control :: CVS
+Topic :: Software Development :: Version Control :: RCS
+Topic :: Software Development :: Version Control :: SCCS
+Topic :: Software Development :: Widget Sets
+Topic :: System
+Topic :: System :: Archiving
+Topic :: System :: Archiving :: Backup
+Topic :: System :: Archiving :: Compression
+Topic :: System :: Archiving :: Mirroring
+Topic :: System :: Archiving :: Packaging
+Topic :: System :: Benchmark
+Topic :: System :: Boot
+Topic :: System :: Boot :: Init
+Topic :: System :: Clustering
+Topic :: System :: Console Fonts
+Topic :: System :: Distributed Computing
+Topic :: System :: Emulators
+Topic :: System :: Filesystems
+Topic :: System :: Hardware
+Topic :: System :: Hardware :: Hardware Drivers
+Topic :: System :: Hardware :: Mainframes
+Topic :: System :: Hardware :: Symmetric Multi-processing
+Topic :: System :: Installation/Setup
+Topic :: System :: Logging
+Topic :: System :: Monitoring
+Topic :: System :: Networking
+Topic :: System :: Networking :: Firewalls
+Topic :: System :: Networking :: Monitoring
+Topic :: System :: Networking :: Monitoring :: Hardware Watchdog
+Topic :: System :: Networking :: Time Synchronization
+Topic :: System :: Operating System
+Topic :: System :: Operating System Kernels
+Topic :: System :: Operating System Kernels :: BSD
+Topic :: System :: Operating System Kernels :: GNU Hurd
+Topic :: System :: Operating System Kernels :: Linux
+Topic :: System :: Power (UPS)
+Topic :: System :: Recovery Tools
+Topic :: System :: Shells
+Topic :: System :: Software Distribution
+Topic :: System :: Systems Administration
+Topic :: System :: Systems Administration :: Authentication/Directory
+Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP
+Topic :: System :: Systems Administration :: Authentication/Directory :: NIS
+Topic :: System :: System Shells
+Topic :: Terminals
+Topic :: Terminals :: Serial
+Topic :: Terminals :: Telnet
+Topic :: Terminals :: Terminal Emulators/X Terminals
+Topic :: Text Editors
+Topic :: Text Editors :: Documentation
+Topic :: Text Editors :: Emacs
+Topic :: Text Editors :: Integrated Development Environments (IDE)
+Topic :: Text Editors :: Text Processing
+Topic :: Text Editors :: Word Processors
+Topic :: Text Processing
+Topic :: Text Processing :: Filters
+Topic :: Text Processing :: Fonts
+Topic :: Text Processing :: General
+Topic :: Text Processing :: Indexing
+Topic :: Text Processing :: Linguistic
+Topic :: Text Processing :: Markup
+Topic :: Text Processing :: Markup :: HTML
+Topic :: Text Processing :: Markup :: LaTeX
+Topic :: Text Processing :: Markup :: SGML
+Topic :: Text Processing :: Markup :: VRML
+Topic :: Text Processing :: Markup :: XML
+Topic :: Utilities
\ No newline at end of file


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/trove-classifiers.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: z3c.builder.core/trunk/src/z3c/builder/core/zcml.py
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/zcml.py	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/zcml.py	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,123 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Representation of ZCML Configuration files.
+
+$Id$
+"""
+import zope.interface
+from zope.schema.fieldproperty import FieldProperty
+from z3c.builder.core import base, interfaces
+
+ZOPE_NS = 'http://namespaces.zope.org/zope'
+BROWSER_NS = 'http://namespaces.zope.org/browser'
+ZCML_NS = 'http://namespaces.zope.org/zcml'
+Z3C_NS = 'http://namespaces.zope.org/z3c'
+
+
+class ZCMLDirectiveBuilder(base.BuilderContainer, base.ContentBuilder):
+    zope.interface.implements(interfaces.IZCMLDirectiveBuilder)
+
+    namespace = FieldProperty(interfaces.IZCMLDirectiveBuilder['namespace'])
+    #name = FieldProperty(interfaces.IZCMLDirectiveBuilder['name'])
+    attributes = FieldProperty(interfaces.IZCMLDirectiveBuilder['attributes'])
+    indent = FieldProperty(interfaces.IZCMLDirectiveBuilder['indent'])
+
+    _indentSpaces = 2
+    _indentAttributeSpaces = 4
+
+    def __init__(self, namespace, name, attributes=None, indent=0):
+        super(ZCMLDirectiveBuilder, self).__init__(unicode(name))
+        self.namespace = namespace
+        if not attributes:
+            attributes = {}
+        self.attributes = attributes
+        self.indent = indent
+
+    def getZCMLBuilder(self):
+        """See interfaces.IZCMLDirectiveBuilder"""
+        builder = self
+        while not interfaces.IZCMLFileBuilder.providedBy(builder):
+            builder = builder.__parent__
+        return builder
+
+    def add(self, builder):
+        """See interfaces.IBuilderContainer"""
+        name = base.getUUID()
+        self[name] = builder
+        return name
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        zcml = self.getZCMLBuilder()
+        if self.namespace is not None and self.namespace not in zcml.namespaces:
+            zcml.namespaces.append(self.namespace)
+        for builder in self.values():
+            builder.indent = self.indent + 1
+            builder.update()
+
+    def render(self):
+        """See interfaces.IContentBuilder"""
+        output = ''
+        prefix = ''
+        if self.namespace:
+            prefix = self.namespace.rsplit('/')[-1] + ':'
+        # Write XML node
+        indent = ' ' * self._indentSpaces * self.indent
+        attrIndent = indent + ' '*self._indentAttributeSpaces
+        output += indent + '<%s%s' %(prefix, self.name)
+        if self.attributes:
+            for name, attr in reversed(self.attributes.items()):
+                output += '\n' + attrIndent + '%s="%s"' %(name, attr)
+            output += '\n' + attrIndent
+        if not len(self):
+            output += '/>\n'
+            return output
+        output += '>\n'
+        # Write all sub-builders.
+        for builder in self.values():
+            output += builder.render()
+            output += '\n'
+        # Close XML node.
+        output += indent + '</%s%s>\n' %(prefix, self.name)
+        # Return result.
+        return output
+
+
+class ZCMLFileBuilder(ZCMLDirectiveBuilder, base.FileBuilder):
+    zope.interface.implements(interfaces.IZCMLFileBuilder)
+
+    i18n_domain = FieldProperty(interfaces.IZCMLFileBuilder['i18n_domain'])
+    namespaces = FieldProperty(interfaces.IZCMLFileBuilder['namespaces'])
+
+    def __init__(self, name):
+        ZCMLDirectiveBuilder.__init__(self, None, 'configure')
+        base.FileBuilder.__init__(self, self.name, str(name))
+
+    def update(self):
+        """See interfaces.IBaseBuilder"""
+        self.namespaces = []
+        if not self.i18n_domain:
+            project = self.getProject()
+            self.i18n_domain = project.name
+        super(ZCMLFileBuilder, self).update()
+        # Create list of attributes
+        self.attributes = {}
+        if self.i18n_domain:
+            self.attributes['i18n_domain'] = self.i18n_domain
+        for namespace in self.namespaces:
+            name = namespace.rsplit('/', 1)[-1]
+            self.attributes['xmlns:'+name] = namespace
+
+    def __repr__(self):
+        return '<%s %r>' %(self.__class__.__name__, self.filename)


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/zcml.py
___________________________________________________________________
Added: svn:keywords
   + Id

Added: z3c.builder.core/trunk/src/z3c/builder/core/zcml.txt
===================================================================
--- z3c.builder.core/trunk/src/z3c/builder/core/zcml.txt	                        (rev 0)
+++ z3c.builder.core/trunk/src/z3c/builder/core/zcml.txt	2009-03-27 08:50:42 UTC (rev 98391)
@@ -0,0 +1,84 @@
+==========================
+ZCML Configuration Builder
+==========================
+
+This builder creates ZCML configuration files and its directives. The builder
+is not repsonsible for validating that it creates valid directives as this
+would require the availability of all packages providing ZCML directives.
+
+  >>> from z3c.builder.core import interfaces, zcml
+  >>> builder = zcml.ZCMLFileBuilder(u'configure.zcml')
+  >>> builder
+  <ZCMLFileBuilder 'configure.zcml'>
+
+This object provides the ``IZCMLFileBuilder`` interface.
+
+  >>> from zope.interface.verify import verifyObject
+  >>> verifyObject(interfaces.IZCMLFileBuilder, builder)
+  True
+
+Let's now render the builder:
+
+  >>> builder.update()
+  Traceback (most recent call last):
+  ...
+  ValueError: No project builder was found and the root node of the
+              project tree was reached.
+
+The project is needed so that the i18n domain can be looked up.
+
+  >>> from z3c.builder.core import project
+  >>> builder.__parent__ = project.ProjectBuilder(u'z3c.myproject')
+
+  >>> builder.update()
+  >>> print builder.render()
+  <configure
+      i18n_domain="z3c.myproject"
+      />
+
+Let's now add a directive:
+
+  >>> builder.add(zcml.ZCMLDirectiveBuilder(
+  ...     None,
+  ...     'include',
+  ...     {'file': 'content.zcml'}
+  ...     ))
+  'f726bcc8-1d3d-4f71-a241-53999e1aa734'
+
+  >>> builder.update()
+  >>> print builder.render()
+  <configure
+      i18n_domain="z3c.myproject"
+      >
+    <include
+        file="content.zcml"
+        />
+  <BLANKLINE>
+  </configure>
+
+Let's now add a directive with a namespace:
+
+  >>> builder.add(zcml.ZCMLDirectiveBuilder(
+  ...     'http://namespaces.zope.org/zope',
+  ...     'adapter',
+  ...     {'factory': 'z3c.project.code.MyAdapter'}
+  ...     ))
+  '739f00eb-5235-49c5-959e-340583586a5f'
+
+  >>> builder.update()
+  >>> print builder.render()
+  <configure
+      xmlns:zope="http://namespaces.zope.org/zope"
+      i18n_domain="z3c.myproject"
+      >
+    <include
+        file="content.zcml"
+        />
+  <BLANKLINE>
+    <zope:adapter
+        factory="z3c.project.code.MyAdapter"
+        />
+  <BLANKLINE>
+  </configure>
+
+And that's it.


Property changes on: z3c.builder.core/trunk/src/z3c/builder/core/zcml.txt
___________________________________________________________________
Added: svn:eol-style
   + native



More information about the Checkins mailing list