[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