[Checkins] SVN: grokproject/trunk/ Add another template set for paster support

Michael Haubenwallner michael at d2m.at
Sat Oct 25 04:52:39 EDT 2008


Log message for revision 92540:
  Add another template set for paster support
  Add option --zopectl to select 'zopectl' templates
  Make 'paster' the default template set
  

Changed:
  U   grokproject/trunk/CHANGES.txt
  U   grokproject/trunk/README.txt
  U   grokproject/trunk/TODO.txt
  U   grokproject/trunk/grokproject/main.py
  D   grokproject/trunk/grokproject/template/
  A   grokproject/trunk/grokproject/template_paste/
  A   grokproject/trunk/grokproject/template_paste/bootstrap.py
  A   grokproject/trunk/grokproject/template_paste/buildout.cfg_tmpl
  A   grokproject/trunk/grokproject/template_paste/etc/
  A   grokproject/trunk/grokproject/template_paste/etc/debug.ini_tmpl
  A   grokproject/trunk/grokproject/template_paste/etc/deploy.ini_tmpl
  A   grokproject/trunk/grokproject/template_paste/etc/site.zcml_tmpl
  A   grokproject/trunk/grokproject/template_paste/etc/zdaemon.conf
  A   grokproject/trunk/grokproject/template_paste/etc/zope.conf
  A   grokproject/trunk/grokproject/template_paste/setup.py_tmpl
  A   grokproject/trunk/grokproject/template_paste/src/
  A   grokproject/trunk/grokproject/template_paste/src/+package+/
  A   grokproject/trunk/grokproject/template_paste/src/+package+/__init__.py
  A   grokproject/trunk/grokproject/template_paste/src/+package+/app.py_tmpl
  A   grokproject/trunk/grokproject/template_paste/src/+package+/app.txt_tmpl
  A   grokproject/trunk/grokproject/template_paste/src/+package+/app_templates/
  A   grokproject/trunk/grokproject/template_paste/src/+package+/app_templates/index.pt_tmpl
  A   grokproject/trunk/grokproject/template_paste/src/+package+/configure.zcml
  A   grokproject/trunk/grokproject/template_paste/src/+package+/ftesting.zcml_tmpl
  A   grokproject/trunk/grokproject/template_paste/src/+package+/startup.py
  A   grokproject/trunk/grokproject/template_paste/src/+package+/static/
  A   grokproject/trunk/grokproject/template_paste/src/+package+/static/README.txt
  A   grokproject/trunk/grokproject/template_paste/src/+package+/tests.py_tmpl
  A   grokproject/trunk/grokproject/template_paste/versions.cfg_tmpl
  A   grokproject/trunk/grokproject/template_zopectl/
  U   grokproject/trunk/grokproject/templates.py
  U   grokproject/trunk/tests.py
  D   grokproject/trunk/tests.txt
  A   grokproject/trunk/tests_paste.txt
  A   grokproject/trunk/tests_zopectl.txt

-=-
Modified: grokproject/trunk/CHANGES.txt
===================================================================
--- grokproject/trunk/CHANGES.txt	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/CHANGES.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -7,7 +7,12 @@
 * Fixed bug: using the ``--svn-repository`` option would fail with an
   OSError.
 
+* Add another template set for paster support
 
+* Add option --zopectl to select 'zopectl' templates
+
+* Make 'paster' the default template set
+
 0.9 (2008-09-29)
 ----------------
 

Modified: grokproject/trunk/README.txt
===================================================================
--- grokproject/trunk/README.txt	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/README.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -16,11 +16,34 @@
 
 After the project area has been created successfully, you will find an
 empty Python package in the ``src`` directory in which you can place
-the code for your web application.  To start the Zope server, execute
-``bin/zopectl fg``.
+the code for your web application.  
 
+To start the application server, execute::
+
+  $ cd MammothHerd
+  $ bin/paster serve etc/deploy.ini
+  
+Start/stop it in daemon mode::
+
+  $ bin/mammothherd-ctl start
+  $ bin/mammothherd-ctl stop
+  
+Start the debugger::
+
+  $ bin/mammothherd-debug
+
 For those who know paster: ``grokproject`` is just a wrapper around a
 paster template.  So instead of running the ``grokproject`` command,
-you can also run:
+you can also run::
 
-  $ paster create -t grok MammotHerd
+  $ bin/paster create -t grok MammotHerd
+
+To create a project with the previous ``zopectl`` layout run the ``grokproject`` 
+script like::
+
+  $ grokproject --zopectl MammothHerd
+
+or::
+
+  $ paster create -t grok MammothHerd zopectl=True
+

Modified: grokproject/trunk/TODO.txt
===================================================================
--- grokproject/trunk/TODO.txt	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/TODO.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -3,6 +3,7 @@
 
 * Make a template for megrok.something
 
-* WSGI integration (add some lines to buildout.cfg)
+* Make tests run under Windows
 
-* Make tests run under Windows
+* Paster: should not need to access http://localhost:8080/@@login.html when 
+  running the debug.ini profile
\ No newline at end of file

Modified: grokproject/trunk/grokproject/main.py
===================================================================
--- grokproject/trunk/grokproject/main.py	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/grokproject/main.py	2008-10-25 08:52:37 UTC (rev 92540)
@@ -13,6 +13,8 @@
                       "hierarchy).")
     parser.add_option('-v', '--verbose', action="store_true", dest="verbose",
                       default=False, help="Be verbose.")
+    parser.add_option('--zopectl', action="store_true", dest="zopectl",
+                      default=False, help="Use zopectl.")
 
     # Options that override the interactive part of filling the templates.
     for var in GrokProject.vars:
@@ -46,6 +48,8 @@
         supplied_value = getattr(options, var.name)
         if supplied_value is not None:
             extra_args.append('%s=%s' % (var.name, supplied_value))
+    if options.zopectl:
+        extra_args.append('zopectl=True')
     exit_code = runner.run(option_args + ['-t', 'grok', project]
                            + extra_args)
     sys.exit(exit_code)

Added: grokproject/trunk/grokproject/template_paste/bootstrap.py
===================================================================
--- grokproject/trunk/grokproject/template_paste/bootstrap.py	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/bootstrap.py	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,84 @@
+##############################################################################
+#
+# Copyright (c) 2006 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: bootstrap.py 85041 2008-03-31 15:57:30Z andreasjung $
+"""
+
+import os, shutil, sys, tempfile, urllib2, logging
+
+def remove_old_logger_handlers():
+    # zc.buildout installs a new log stream on every call of
+    # main(). We remove any leftover handlers to avoid multiple output
+    # of same content (doubled lines etc.)
+    root_logger = logging.getLogger()
+    if 'zc.buildout' in root_logger.manager.loggerDict.keys():
+        logger = logging.getLogger('zc.buildout')
+        for handler in logger.handlers:
+            logger.removeHandler(handler)
+    return
+
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+    import pkg_resources
+except ImportError:
+    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
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    def quote (c):
+        return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws  = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, quote (sys.executable),
+    '-c', quote (cmd), '-mqNxd', quote (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'])
+remove_old_logger_handlers()
+shutil.rmtree(tmpeggs)
+
+# grokproject specific addition to standard bootstrap.py:
+# Install eggbasket too.  This should be verbose to give the user
+# information about what is happening, since this can take a while.
+zc.buildout.buildout.main(sys.argv[1:] + ['-v', 'install', 'eggbasket'])
+if sys.platform == 'win32':
+    print "Now you can run 'bin\buildout.exe'"
+else:
+    print "Now you can run 'bin/buildout'"

Added: grokproject/trunk/grokproject/template_paste/buildout.cfg_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/buildout.cfg_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/buildout.cfg_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,44 @@
+[buildout]
+develop = .
+parts = eggbasket app i18n test data log
+newest = ${newest}
+extends = versions.cfg
+# eggs will be installed in the default buildout location
+# (see .buildout/default.cfg in your home directory)
+# unless you specify an eggs-directory option here.
+${eggs_dir}
+versions = versions
+
+[app]
+recipe = zc.recipe.egg
+eggs = ${egg}
+       z3c.evalexception>=2.0
+       Paste
+       PasteScript
+       PasteDeploy
+interpreter = python-console
+
+[data]
+recipe = zc.recipe.filestorage
+
+[log]
+recipe = zc.recipe.filestorage
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = ${egg}
+defaults = ['--tests-pattern', '^f?tests$$', '-v']
+
+# this section named so that the i18n scripts are called bin/i18n...
+[i18n]
+recipe = z3c.recipe.i18n:i18n
+packages = ${package}
+eggs = ${package}
+domain = ${package}
+output = src/${package}/locales
+zcml =
+
+[eggbasket]
+recipe = z3c.recipe.eggbasket
+eggs = grok
+url = http://grok.zope.org/releaseinfo/grok-eggs-${grokversion}.tgz

Added: grokproject/trunk/grokproject/template_paste/etc/debug.ini_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/etc/debug.ini_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/etc/debug.ini_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,13 @@
+[filter-app:main]
+# Change the last part from 'ajax' to 'pdb' for a post-mortem debugger
+# on the console:
+use = egg:z3c.evalexception#ajax
+next = zope
+
+[app:zope]
+use = egg:${egg}
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
\ No newline at end of file

Added: grokproject/trunk/grokproject/template_paste/etc/deploy.ini_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/etc/deploy.ini_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/etc/deploy.ini_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,7 @@
+[app:main]
+use = egg:${egg}
+
+[server:main]
+use = egg:Paste#http
+host = 127.0.0.1
+port = 8080
\ No newline at end of file

Added: grokproject/trunk/grokproject/template_paste/etc/site.zcml_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/etc/site.zcml_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/etc/site.zcml_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,36 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           i18n_domain="${package}">
+
+  <include package="${package}" />
+
+    <configure i18n_domain="${package}">
+    
+      <unauthenticatedPrincipal id="zope.anybody"
+                                title="Unauthenticated User" />
+      <unauthenticatedGroup id="zope.Anybody"
+                            title="Unauthenticated Users" />
+      <authenticatedGroup id="zope.Authenticated"
+                        title="Authenticated Users" />
+      <everybodyGroup id="zope.Everybody"
+                      title="All Users" />
+      <principal id="zope.manager"
+                 title="Manager"
+                 login=${user}
+                 password_manager="Plain Text"
+                 password=${passwd}
+                 />
+
+      <!-- Replace the following directive if you do not want
+           public access -->
+      <grant permission="zope.View"
+             principal="zope.Anybody" />
+      <grant permission="zope.app.dublincore.view"
+             principal="zope.Anybody" />
+
+      <role id="zope.Manager" title="Site Manager" />
+      <role id="zope.Member" title="Site Member" />
+      <grantAll role="zope.Manager" />
+      <grant role="zope.Manager"
+             principal="zope.manager" />
+   </configure>
+</configure>
\ No newline at end of file

Added: grokproject/trunk/grokproject/template_paste/etc/zdaemon.conf
===================================================================
--- grokproject/trunk/grokproject/template_paste/etc/zdaemon.conf	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/etc/zdaemon.conf	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,8 @@
+<runner>
+  program bin/paster serve etc/deploy.ini
+  daemon on
+  transcript parts/log/zdaemon.log
+  socket-name parts/log/zdaemonsock
+  # Enable this to run the child process as a different user
+  # user zope
+</runner>
\ No newline at end of file

Added: grokproject/trunk/grokproject/template_paste/etc/zope.conf
===================================================================
--- grokproject/trunk/grokproject/template_paste/etc/zope.conf	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/etc/zope.conf	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,39 @@
+# Identify the component configuration used to define the site:
+site-definition etc/site.zcml
+
+<zodb>
+  # Standard Filestorage
+  <filestorage>
+    path parts/data/Data.fs
+  </filestorage>
+
+# Uncomment this if you want to connect to a ZEO server instead:
+#  <zeoclient>
+#    server localhost:8100
+#    storage 1
+#    # ZEO client cache, in bytes
+#    cache-size 20MB
+#    # Uncomment to have a persistent disk cache
+#    #client zeo1
+#  </zeoclient>
+</zodb>
+
+<eventlog>
+  # This sets up logging to both a file and to standard output
+  # (STDOUT).  The "path" setting can be a relative or absolute
+  # filesystem path or the tokens STDOUT or STDERR.
+
+  <logfile>
+    path parts/log/z3.log
+    formatter zope.exceptions.log.Formatter
+  </logfile>
+
+  <logfile>
+    path STDOUT
+    formatter zope.exceptions.log.Formatter
+  </logfile>
+</eventlog>
+
+# Comment this line to disable developer mode.  This should be done in
+# production
+devmode on
\ No newline at end of file

Added: grokproject/trunk/grokproject/template_paste/setup.py_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/setup.py_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/setup.py_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,34 @@
+from setuptools import setup, find_packages
+
+version = '${repr(version)|0.0}'
+
+setup(name=${repr(project)},
+      version=version,
+      description="${description|nothing}",
+      long_description="""\
+${long_description|nothing}""",
+      # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[], 
+      keywords=${repr(keywords)|empty},
+      author=${repr(author)|empty},
+      author_email=${repr(author_email)|empty},
+      url=${repr(url)|empty},
+      license=${repr(license_name)|empty},
+      package_dir={'': 'src'},
+      packages=find_packages('src'),
+      include_package_data=True,
+      zip_safe=${repr(bool(zip_safe))|False},
+      install_requires=['setuptools',
+                        'grok',
+                        'grokui.admin',
+                        'z3c.testsetup',
+                        # Add extra requirements here
+                        ],
+      entry_points = """
+      [console_scripts]
+      ${package}-debug = ${package}.startup:interactive_debug_prompt
+      ${package}-ctl = ${package}.startup:zdaemon_controller
+      [paste.app_factory]
+      main = ${package}.startup:application_factory
+      """,
+      )

Added: grokproject/trunk/grokproject/template_paste/src/+package+/__init__.py
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/__init__.py	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/__init__.py	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1 @@
+# this directory is a package

Added: grokproject/trunk/grokproject/template_paste/src/+package+/app.py_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/app.py_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/app.py_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,7 @@
+import grok
+
+class ${app_class_name}(grok.Application, grok.Container):
+    pass
+
+class Index(grok.View):
+    pass # see app_templates/index.pt

Added: grokproject/trunk/grokproject/template_paste/src/+package+/app.txt_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/app.txt_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/app.txt_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,32 @@
+Do a functional doctest test on the app.
+========================================
+
+:Test-Layer: functional
+
+Let's first create an instance of ${app_class_name} at the top level:
+
+   >>> from ${package}.app import ${app_class_name}
+   >>> root = getRootFolder()
+   >>> root['app'] = ${app_class_name}()
+
+
+Run tests in the testbrowser
+----------------------------
+
+The zope.testbrowser.browser module exposes a Browser class that
+simulates a web browser similar to Mozilla Firefox or IE.  We use that
+to test how our application behaves in a browser.  For more
+information, see http://pypi.python.org/pypi/zope.testbrowser.
+
+Create a browser and visit the instance you just created:
+
+   >>> from zope.testbrowser.testing import Browser
+   >>> browser = Browser()
+   >>> browser.open('http://localhost/app')
+
+Check some basic information about the page you visit:
+
+   >>> browser.url
+   'http://localhost/app'
+   >>> browser.headers.get('Status').upper()
+   '200 OK'

Added: grokproject/trunk/grokproject/template_paste/src/+package+/app_templates/index.pt_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/app_templates/index.pt_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/app_templates/index.pt_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,11 @@
+<html>
+<head>
+</head>
+<body>
+  <h1>Congratulations!</h1>
+
+  <p>Your Grok application is up and running.
+  Edit <code>${package}/app_templates/index.pt</code> to change
+  this page.</p>
+</body>
+</html>

Added: grokproject/trunk/grokproject/template_paste/src/+package+/configure.zcml
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/configure.zcml	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/configure.zcml	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,6 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:grok="http://namespaces.zope.org/grok">
+  <include package="grok" />
+  <includeDependencies package="." />
+  <grok:grok package="." />
+</configure>

Added: grokproject/trunk/grokproject/template_paste/src/+package+/ftesting.zcml_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/ftesting.zcml_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/ftesting.zcml_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,34 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   i18n_domain="${package}"
+   package="${package}"
+   >
+
+  <include package="${package}" />
+
+  <!-- Typical functional testing security setup -->
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>

Added: grokproject/trunk/grokproject/template_paste/src/+package+/startup.py
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/startup.py	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/startup.py	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,35 @@
+import os
+import sys
+import code
+import zdaemon.zdctl
+import zope.app.wsgi
+import zope.app.debug
+
+def application_factory(global_conf, conf='../etc/zope.conf'):
+    zope_conf = os.path.join(global_conf['here'], conf)
+    return zope.app.wsgi.getWSGIApplication(zope_conf)
+
+def interactive_debug_prompt(zope_conf='etc/zope.conf'):
+    db = zope.app.wsgi.config(zope_conf)
+    debugger = zope.app.debug.Debugger.fromDatabase(db)
+    # Invoke an interactive interpreter shell
+    banner = ("Welcome to the interactive debug prompt.\n"
+              "The 'root' variable contains the ZODB root folder.\n"
+              "The 'app' variable contains the Debugger, 'app.publish(path)' "
+              "simulates a request.")
+    code.interact(banner=banner, local={'debugger': debugger,
+                                        'app':      debugger,
+                                        'root':     debugger.root()})
+
+class ControllerCommands(zdaemon.zdctl.ZDCmd):
+
+    def do_debug(self, rest):
+        interactive_debug_prompt()
+
+    def help_debug(self):
+        print "debug -- Initialize the application, providing a debugger"
+        print "         object at an interactive Python prompt."
+
+def zdaemon_controller(zdaemon_conf='etc/zdaemon.conf'):
+    args = ['-C', zdaemon_conf] + sys.argv[1:]
+    zdaemon.zdctl.main(args, options=None, cmdclass=ControllerCommands)
\ No newline at end of file

Added: grokproject/trunk/grokproject/template_paste/src/+package+/static/README.txt
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/static/README.txt	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/static/README.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,2 @@
+Put static files here, like javascript and css.  They will be
+available as static/<filename> in views.

Added: grokproject/trunk/grokproject/template_paste/src/+package+/tests.py_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/src/+package+/tests.py_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/src/+package+/tests.py_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,12 @@
+import os.path
+import z3c.testsetup
+import ${package}
+from zope.app.testing.functional import ZCMLLayer
+
+
+ftesting_zcml = os.path.join(
+    os.path.dirname(${package}.__file__), 'ftesting.zcml')
+FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer',
+                            allow_teardown=True)
+
+test_suite = z3c.testsetup.register_all_tests('${package}')

Added: grokproject/trunk/grokproject/template_paste/versions.cfg_tmpl
===================================================================
--- grokproject/trunk/grokproject/template_paste/versions.cfg_tmpl	                        (rev 0)
+++ grokproject/trunk/grokproject/template_paste/versions.cfg_tmpl	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,16 @@
+# This file contains a list of versions of the various grok modules that
+# belong together.
+# It was downloaded from ${version_info_url}
+# when this project was created.
+
+${version_info_file_contents}
+
+# Here we pin the recipes used in the buildout.cfg
+z3c.recipe.i18n = 0.5.0
+z3c.recipe.eggbasket = 0.4.0
+zc.buildout = 1.0.6
+zc.recipe.egg = 1.1.0b1
+zc.recipe.filestorage = 1.0.1
+zc.recipe.testrunner = 1.0.0
+zc.zodbrecipes = 0.4.0
+zc.zope3recipes = 0.7.0

Copied: grokproject/trunk/grokproject/template_zopectl (from rev 92538, grokproject/trunk/grokproject/template)

Modified: grokproject/trunk/grokproject/templates.py
===================================================================
--- grokproject/trunk/grokproject/templates.py	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/grokproject/templates.py	2008-10-25 08:52:37 UTC (rev 92540)
@@ -16,7 +16,7 @@
 
 
 class GrokProject(templates.Template):
-    _template_dir = 'template'
+    _template_dir = 'template_paste'
     summary = "A grok project"
     required_templates = []
 
@@ -61,6 +61,9 @@
             # Escape values that go in site.zcml.
             vars[var_name] = xml.sax.saxutils.quoteattr(vars[var_name])
         vars['app_class_name'] = vars['project'].capitalize()
+        
+        if vars.get('zopectl','') == 'True':
+            self._template_dir = 'template_zopectl'
 
         # Handling the version.cfg file.
         print "Downloading info about versions..."

Modified: grokproject/trunk/tests.py
===================================================================
--- grokproject/trunk/tests.py	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/tests.py	2008-10-25 08:52:37 UTC (rev 92540)
@@ -78,13 +78,15 @@
     if globs is None:
         globs = globals()
 
-    flags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE |
+    flags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE) |
              doctest.REPORT_ONLY_FIRST_FAILURE)
 
     if package_dir not in sys.path:
         sys.path.append(package_dir)
 
-    docs = [os.path.join(package_dir, 'tests.txt')]
+    docs = [os.path.join(package_dir, 'tests_zopectl.txt'),
+            os.path.join(package_dir, 'tests_paste.txt'),
+            ]
 
     for test in docs:
         suite.append(doctest.DocFileSuite(test, optionflags=flags,

Deleted: grokproject/trunk/tests.txt
===================================================================
--- grokproject/trunk/tests.txt	2008-10-25 08:21:27 UTC (rev 92539)
+++ grokproject/trunk/tests.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -1,218 +0,0 @@
-Grokproject tests
-=================
-
-Go to a directory::
-
-    >>> cd(tempdir)
-
-Check that the directory does not exist::
-
-    >>> rmdir('grokexample')
-
-Create an empty eggs directory. So we make sure that we don't have to
-care for arbitrary eggs, that were installed in the user's environment
-before::
-
-    >>> tempeggs = 'grokexample-eggs'
-    >>> eggsdir = os.path.join(tempdir, tempeggs)
-    >>> rmdir(eggsdir)
-    >>> os.makedirs(eggsdir)
-
-Then use paster. Eggs are placed in our freshly created eggs directory::
-
-    >>> paster = current_dir + '/bin/paster create -t grok '
-    >>> sh(paster + 'grokexample user=a passwd=a '
-    ...    'eggs_dir=%s --no-interactive' % eggsdir)
-    /.../bin/paster create -t grok grokexample user=a passwd=a ...
-    ...
-
-Let's check the contents::
-
-    >>> package_dir = os.path.join(tempdir, 'grokexample')
-    >>> ls(package_dir)
-    .installed.cfg
-    bin
-    bootstrap.py
-    buildout.cfg
-    develop-eggs
-    parts
-    setup.py
-    src
-    versions.cfg
-
-    >>> software_dir = os.path.join(package_dir, 'src', 'grokexample')
-    >>> ls(software_dir)
-    __init__.py
-    app.py
-    app.txt
-    app_templates
-    configure.zcml
-    ftesting.zcml
-    static
-    tests.py
-
-    >>> bin_dir = os.path.join(package_dir, 'bin')
-    >>> ls(bin_dir)
-    buildout...
-    i18nextract...
-    i18nmergeall...
-    i18nstats...
-    test...
-    zopectl...
-
-The eggs dir is filled now::
-
-    >>> len(os.listdir(eggsdir)) > 100
-    True
-
-
-Using i18n scripts
-------------------
-
-We can create a POT file out of our sources using the freshly
-generated `i18nextract`::
-
-    >>> cmd = os.path.join(bin_dir, 'i18nextract')
-    >>> output = read_sh(cmd)
-    >>> print output
-    domain:...'grokexample'
-    ...
-    output: '...grokexample.pot'
-
-The .pot file contains no specific entries right now. So let's add a
-source file with translatable content::
-
-    >>> source = """
-    ... from zope.i18nmessageid import MessageFactory
-    ... _ = MessageFactory('grokexample')
-    ...
-    ... class SomeClassWithI18nableContent(object):
-    ...   title = _(u'mytitle')
-    ...   description = _(u'description')
-    ...   name = _(u'name')
-    ... """
-    >>> source_path = os.path.join(software_dir, 'translatable.py')
-    >>> open(source_path, 'w').write(source)
-
-And rerun `bin/i18nextract`::
-
-    >>> cmd = os.path.join(bin_dir, 'i18nextract')
-    >>> output = read_sh(cmd)
-
-The translatable strings now appear in the generated .pot file::
-
-    >>> pot_file = os.path.join(software_dir, 'locales', 'grokexample.pot')
-    >>> print open(pot_file, 'r').read()
-    ####...
-    #: src/grokexample/translatable.py:6
-    msgid "mytitle"
-    msgstr ""
-    <BLANKLINE>
-    #: src/grokexample/translatable.py:7
-    msgid "description"
-    msgstr ""
-    <BLANKLINE>
-    #: src/grokexample/translatable.py:8
-    msgid "name"
-    msgstr ""
-
-Let's now create a translation for that (tiny) set of messages::
-
-    >>> trans_dir_de = os.path.join(software_dir, 'locales', 'de',
-    ...                            'LC_MESSAGES')
-    >>> os.makedirs(trans_dir_de)
-
-In this directory we create a copy of the original .pot file::
-
-    >>> po_file_path = os.path.join(trans_dir_de, 'grokexample.po')
-    >>> po_file = open(pot_file, 'r').read()
-
-We modify the translation to give some more interesting results::
-
-    >>> po_file = po_file.replace('translatable.py:6\n',
-    ...                           'translatable.py:6\n#, fuzzy\n')
-    >>> po_file = po_file.replace('"mytitle"\nmsgstr ""',
-    ...                           '"mytitle"\nmsgstr "Mein Titel"')
-    >>> po_file = po_file.replace('"name"\nmsgstr ""',
-    ...                           '"name"\nmsgstr "Name"')
-    >>> open(po_file_path, 'wb').write(po_file)
-
-We can merge all translations with bin/i18nmergeall::
-
-    >>> cmd = os.path.join(bin_dir, 'i18nmergeall')
-    >>> output = read_sh(cmd).split('\n')
-    >>> print output[1]
-    Merging language "de", domain "grokexample"
-
-We can see the status of translations calling bin/i18nstats::
-
-    >>> cmd = os.path.join(bin_dir, 'i18nstats')
-    >>> output = read_sh(cmd)
-    >>> print output
-    Language    Total    Done    Not Done    Fuzzy      Done %
-    ==========================================================
-    de              3       1           1        1     33.33 %
-
-
-Using the generated `test` script
----------------------------------
-
-We can run tests::
-
-    >>> cmd = os.path.join(bin_dir, 'test')
-    >>> output = read_sh(cmd)
-    >>> print output
-    Running tests at level 1
-    Running grokexample.FunctionalLayer tests:
-      Set up grokexample.FunctionalLayer in ... seconds.
-      Running:
-    ...
-      Ran 3 tests with 0 failures and 0 errors in ... seconds.
-    Tearing down left over layers:
-      Tear down grokexample.FunctionalLayer ... not supported
-
-Using the generated `buildout` script
--------------------------------------
-
-We can call the `buildout` script of the freshly generated
-project. For this to work, we have to switch to the project directory
-first::
-
-    >>> cd(package_dir)
-    >>> cmd = os.path.join(bin_dir, 'buildout')
-    >>> output = read_sh(cmd)
-    >>> print output
-    Develop: '...'
-    Updating eggbasket.
-    Updating app.
-    Updating data.
-    Updating zopectl.
-    Updating i18n.
-    The recipe for i18n doesn't define an update method. ...
-    i18n: setting up i18n tools
-    Updating test.
-
-
-Using the generated `bootstrap` script
---------------------------------------
-
-Generated grokprojects come with their own `bootstrap.py` script, that
-makes it easier to distribute projects. As a normal Python module it
-has to be called with a Python interpreter::
-
-    >>> import sys
-    >>> cmd_arg = os.path.join(package_dir, 'bootstrap.py')
-    >>> cmd = "%s %s" % (sys.executable, cmd_arg)
-    >>> output = read_sh(cmd)
-    >>> print output
-    Develop: '...'
-    Installing 'z3c.recipe.eggbasket'.
-    ...
-    Now you can run 'bin/buildout'
-
-
-Clean up::
-
-    >>> cd(tempdir)
-    >>> rmdir('grokexample')
-    >>> rmdir(eggsdir)

Added: grokproject/trunk/tests_paste.txt
===================================================================
--- grokproject/trunk/tests_paste.txt	                        (rev 0)
+++ grokproject/trunk/tests_paste.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,230 @@
+Grokproject tests
+=================
+
+Go to a directory::
+
+    >>> cd(tempdir)
+
+Check that the directory does not exist::
+
+    >>> rmdir('grokexample')
+
+Create an empty eggs directory. So we make sure that we don't have to
+care for arbitrary eggs, that were installed in the user's environment
+before::
+
+    >>> tempeggs = 'grokexample-eggs'
+    >>> eggsdir = os.path.join(tempdir, tempeggs)
+    >>> rmdir(eggsdir)
+    >>> os.makedirs(eggsdir)
+
+Then use paster. Eggs are placed in our freshly created eggs directory::
+
+    >>> paster = current_dir + '/bin/paster create -t grok '
+    >>> sh(paster + 'grokexample user=a passwd=a '
+    ...    'eggs_dir=%s --no-interactive' % eggsdir)
+    /.../bin/paster create -t grok grokexample user=a passwd=a ...
+    ...
+
+Let's check the contents::
+
+    >>> package_dir = os.path.join(tempdir, 'grokexample')
+    >>> ls(package_dir)
+    .installed.cfg
+    bin
+    bootstrap.py
+    buildout.cfg
+    develop-eggs
+    etc
+    parts
+    setup.py
+    src
+    versions.cfg
+
+    >>> software_dir = os.path.join(package_dir, 'src', 'grokexample')
+    >>> ls(software_dir)
+    __init__.py
+    app.py
+    app.txt
+    app_templates
+    configure.zcml
+    ftesting.zcml
+    startup.py
+    static
+    tests.py
+
+    >>> bin_dir = os.path.join(package_dir, 'bin')
+    >>> ls(bin_dir)
+    buildout...
+    grokexample-ctl...
+    grokexample-debug...
+    i18nextract...
+    i18nmergeall...
+    i18nstats...
+    paster...
+    python-console...
+    test...
+
+    >>> etc_dir = os.path.join(package_dir, 'etc')
+    >>> ls(etc_dir)
+    debug.ini
+    deploy.ini
+    site.zcml
+    zdaemon.conf
+    zope.conf
+
+The eggs dir is filled now::
+
+    >>> len(os.listdir(eggsdir)) > 100
+    True
+
+Using i18n scripts
+------------------
+
+We can create a POT file out of our sources using the freshly
+generated `i18nextract`::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nextract')
+    >>> output = read_sh(cmd)
+    >>> print output
+    domain:...'grokexample'
+    ...
+    output: '...grokexample.pot'
+
+The .pot file contains no specific entries right now. So let's add a
+source file with translatable content::
+
+    >>> source = """
+    ... from zope.i18nmessageid import MessageFactory
+    ... _ = MessageFactory('grokexample')
+    ...
+    ... class SomeClassWithI18nableContent(object):
+    ...   title = _(u'mytitle')
+    ...   description = _(u'description')
+    ...   name = _(u'name')
+    ... """
+    >>> source_path = os.path.join(software_dir, 'translatable.py')
+    >>> open(source_path, 'w').write(source)
+
+And rerun `bin/i18nextract`::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nextract')
+    >>> output = read_sh(cmd)
+
+The translatable strings now appear in the generated .pot file::
+
+    >>> pot_file = os.path.join(software_dir, 'locales', 'grokexample.pot')
+    >>> print open(pot_file, 'r').read()
+    ####...
+    #: src/grokexample/translatable.py:6
+    msgid "mytitle"
+    msgstr ""
+    <BLANKLINE>
+    #: src/grokexample/translatable.py:7
+    msgid "description"
+    msgstr ""
+    <BLANKLINE>
+    #: src/grokexample/translatable.py:8
+    msgid "name"
+    msgstr ""
+
+Let's now create a translation for that (tiny) set of messages::
+
+    >>> trans_dir_de = os.path.join(software_dir, 'locales', 'de',
+    ...                            'LC_MESSAGES')
+    >>> os.makedirs(trans_dir_de)
+
+In this directory we create a copy of the original .pot file::
+
+    >>> po_file_path = os.path.join(trans_dir_de, 'grokexample.po')
+    >>> po_file = open(pot_file, 'r').read()
+
+We modify the translation to give some more interesting results::
+
+    >>> po_file = po_file.replace('translatable.py:6\n',
+    ...                           'translatable.py:6\n#, fuzzy\n')
+    >>> po_file = po_file.replace('"mytitle"\nmsgstr ""',
+    ...                           '"mytitle"\nmsgstr "Mein Titel"')
+    >>> po_file = po_file.replace('"name"\nmsgstr ""',
+    ...                           '"name"\nmsgstr "Name"')
+    >>> open(po_file_path, 'wb').write(po_file)
+
+We can merge all translations with bin/i18nmergeall::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nmergeall')
+    >>> output = read_sh(cmd).split('\n')
+    >>> print output[1]
+    Merging language "de", domain "grokexample"
+
+We can see the status of translations calling bin/i18nstats::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nstats')
+    >>> output = read_sh(cmd)
+    >>> print output
+    Language    Total    Done    Not Done    Fuzzy      Done %
+    ==========================================================
+    de              3       1           1        1     33.33 %
+
+
+Using the generated `test` script
+---------------------------------
+
+We can run tests::
+
+    >>> cmd = os.path.join(bin_dir, 'test')
+    >>> output = read_sh(cmd)
+    >>> print output
+    Running tests at level 1
+    Running grokexample.FunctionalLayer tests:
+      Set up grokexample.FunctionalLayer in ... seconds.
+      Running:
+    ...
+      Ran 3 tests with 0 failures and 0 errors in ... seconds.
+    Tearing down left over layers:
+      Tear down grokexample.FunctionalLayer ... not supported
+
+Using the generated `buildout` script
+-------------------------------------
+
+We can call the `buildout` script of the freshly generated
+project. For this to work, we have to switch to the project directory
+first::
+
+    >>> cd(package_dir)
+    >>> cmd = os.path.join(bin_dir, 'buildout')
+    >>> output = read_sh(cmd)
+    >>> print output
+    Develop: '...'
+    Updating eggbasket.
+    Updating app.
+    Updating i18n.
+    The recipe for i18n doesn't define an update method. Using its install method.
+    i18n: setting up i18n tools
+    Updating test.
+    Updating data.
+    Updating log.
+
+
+Using the generated `bootstrap` script
+--------------------------------------
+
+Generated grokprojects come with their own `bootstrap.py` script, that
+makes it easier to distribute projects. As a normal Python module it
+has to be called with a Python interpreter::
+
+    >>> import sys
+    >>> cmd_arg = os.path.join(package_dir, 'bootstrap.py')
+    >>> cmd = "%s %s" % (sys.executable, cmd_arg)
+    >>> output = read_sh(cmd)
+    >>> print output
+    Develop: '...'
+    Installing 'z3c.recipe.eggbasket'.
+    ...
+    Now you can run 'bin/buildout'
+
+
+Clean up::
+
+    >>> cd(tempdir)
+    >>> rmdir('grokexample')
+    >>> rmdir(eggsdir)

Copied: grokproject/trunk/tests_zopectl.txt (from rev 92538, grokproject/trunk/tests.txt)
===================================================================
--- grokproject/trunk/tests_zopectl.txt	                        (rev 0)
+++ grokproject/trunk/tests_zopectl.txt	2008-10-25 08:52:37 UTC (rev 92540)
@@ -0,0 +1,218 @@
+Grokproject tests
+=================
+
+Go to a directory::
+
+    >>> cd(tempdir)
+
+Check that the directory does not exist::
+
+    >>> rmdir('grokexample')
+
+Create an empty eggs directory. So we make sure that we don't have to
+care for arbitrary eggs, that were installed in the user's environment
+before::
+
+    >>> tempeggs = 'grokexample-eggs'
+    >>> eggsdir = os.path.join(tempdir, tempeggs)
+    >>> rmdir(eggsdir)
+    >>> os.makedirs(eggsdir)
+
+Then use paster. Eggs are placed in our freshly created eggs directory::
+
+    >>> paster = current_dir + '/bin/paster create -t grok '
+    >>> sh(paster + 'grokexample user=a passwd=a zopectl=True '
+    ...    'eggs_dir=%s --no-interactive' % eggsdir)
+    /.../bin/paster create -t grok grokexample user=a passwd=a zopectl=True ...
+    ...
+
+Let's check the contents::
+
+    >>> package_dir = os.path.join(tempdir, 'grokexample')
+    >>> ls(package_dir)
+    .installed.cfg
+    bin
+    bootstrap.py
+    buildout.cfg
+    develop-eggs
+    parts
+    setup.py
+    src
+    versions.cfg
+
+    >>> software_dir = os.path.join(package_dir, 'src', 'grokexample')
+    >>> ls(software_dir)
+    __init__.py
+    app.py
+    app.txt
+    app_templates
+    configure.zcml
+    ftesting.zcml
+    static
+    tests.py
+
+    >>> bin_dir = os.path.join(package_dir, 'bin')
+    >>> ls(bin_dir)
+    buildout...
+    i18nextract...
+    i18nmergeall...
+    i18nstats...
+    test...
+    zopectl...
+
+The eggs dir is filled now::
+
+    >>> len(os.listdir(eggsdir)) > 100
+    True
+
+
+Using i18n scripts
+------------------
+
+We can create a POT file out of our sources using the freshly
+generated `i18nextract`::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nextract')
+    >>> output = read_sh(cmd)
+    >>> print output
+    domain:...'grokexample'
+    ...
+    output: '...grokexample.pot'
+
+The .pot file contains no specific entries right now. So let's add a
+source file with translatable content::
+
+    >>> source = """
+    ... from zope.i18nmessageid import MessageFactory
+    ... _ = MessageFactory('grokexample')
+    ...
+    ... class SomeClassWithI18nableContent(object):
+    ...   title = _(u'mytitle')
+    ...   description = _(u'description')
+    ...   name = _(u'name')
+    ... """
+    >>> source_path = os.path.join(software_dir, 'translatable.py')
+    >>> open(source_path, 'w').write(source)
+
+And rerun `bin/i18nextract`::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nextract')
+    >>> output = read_sh(cmd)
+
+The translatable strings now appear in the generated .pot file::
+
+    >>> pot_file = os.path.join(software_dir, 'locales', 'grokexample.pot')
+    >>> print open(pot_file, 'r').read()
+    ####...
+    #: src/grokexample/translatable.py:6
+    msgid "mytitle"
+    msgstr ""
+    <BLANKLINE>
+    #: src/grokexample/translatable.py:7
+    msgid "description"
+    msgstr ""
+    <BLANKLINE>
+    #: src/grokexample/translatable.py:8
+    msgid "name"
+    msgstr ""
+
+Let's now create a translation for that (tiny) set of messages::
+
+    >>> trans_dir_de = os.path.join(software_dir, 'locales', 'de',
+    ...                            'LC_MESSAGES')
+    >>> os.makedirs(trans_dir_de)
+
+In this directory we create a copy of the original .pot file::
+
+    >>> po_file_path = os.path.join(trans_dir_de, 'grokexample.po')
+    >>> po_file = open(pot_file, 'r').read()
+
+We modify the translation to give some more interesting results::
+
+    >>> po_file = po_file.replace('translatable.py:6\n',
+    ...                           'translatable.py:6\n#, fuzzy\n')
+    >>> po_file = po_file.replace('"mytitle"\nmsgstr ""',
+    ...                           '"mytitle"\nmsgstr "Mein Titel"')
+    >>> po_file = po_file.replace('"name"\nmsgstr ""',
+    ...                           '"name"\nmsgstr "Name"')
+    >>> open(po_file_path, 'wb').write(po_file)
+
+We can merge all translations with bin/i18nmergeall::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nmergeall')
+    >>> output = read_sh(cmd).split('\n')
+    >>> print output[1]
+    Merging language "de", domain "grokexample"
+
+We can see the status of translations calling bin/i18nstats::
+
+    >>> cmd = os.path.join(bin_dir, 'i18nstats')
+    >>> output = read_sh(cmd)
+    >>> print output
+    Language    Total    Done    Not Done    Fuzzy      Done %
+    ==========================================================
+    de              3       1           1        1     33.33 %
+
+
+Using the generated `test` script
+---------------------------------
+
+We can run tests::
+
+    >>> cmd = os.path.join(bin_dir, 'test')
+    >>> output = read_sh(cmd)
+    >>> print output
+    Running tests at level 1
+    Running grokexample.FunctionalLayer tests:
+      Set up grokexample.FunctionalLayer in ... seconds.
+      Running:
+    ...
+      Ran 3 tests with 0 failures and 0 errors in ... seconds.
+    Tearing down left over layers:
+      Tear down grokexample.FunctionalLayer ... not supported
+
+Using the generated `buildout` script
+-------------------------------------
+
+We can call the `buildout` script of the freshly generated
+project. For this to work, we have to switch to the project directory
+first::
+
+    >>> cd(package_dir)
+    >>> cmd = os.path.join(bin_dir, 'buildout')
+    >>> output = read_sh(cmd)
+    >>> print output
+    Develop: '...'
+    Updating eggbasket.
+    Updating app.
+    Updating data.
+    Updating zopectl.
+    Updating i18n.
+    The recipe for i18n doesn't define an update method. ...
+    i18n: setting up i18n tools
+    Updating test.
+
+
+Using the generated `bootstrap` script
+--------------------------------------
+
+Generated grokprojects come with their own `bootstrap.py` script, that
+makes it easier to distribute projects. As a normal Python module it
+has to be called with a Python interpreter::
+
+    >>> import sys
+    >>> cmd_arg = os.path.join(package_dir, 'bootstrap.py')
+    >>> cmd = "%s %s" % (sys.executable, cmd_arg)
+    >>> output = read_sh(cmd)
+    >>> print output
+    Develop: '...'
+    Installing 'z3c.recipe.eggbasket'.
+    ...
+    Now you can run 'bin/buildout'
+
+
+Clean up::
+
+    >>> cd(tempdir)
+    >>> rmdir('grokexample')
+    >>> rmdir(eggsdir)



More information about the Checkins mailing list