Commit d46ab020 authored by Stefan H. Holek's avatar Stefan H. Holek

Forward port packages-as-products refactoring from 2.10 branch.

parents 51aae426 cf0a8834
......@@ -633,21 +633,9 @@ def install_products(app):
install_product(app, product_dir, product_name, meta_types,
folder_permissions, raise_exc=debug_mode)
# Delayed install of products-as-packages
for module_, init_func in getattr(Products, '_packages_to_initialize', []):
try:
product = App.Product.initializeProduct(module_,
module_.__name__,
module_.__path__[0],
app)
product.package_name = module_.__name__
if init_func is not None:
newContext = ProductContext(product, app, module_)
init_func(newContext)
finally:
transaction.commit()
# Delayed install of packages-as-products
for module, init_func in getattr(Products, '_packages_to_initialize', []):
install_package(app, module, init_func, raise_exc=debug_mode)
if hasattr(Products, '_packages_to_initialize'):
del Products._packages_to_initialize
......@@ -855,6 +843,34 @@ def install_product(app, product_dir, product_name, meta_types,
if raise_exc:
raise
def install_package(app, module, init_func, raise_exc=False, log_exc=True):
"""Installs a Python package like a product."""
try:
product = App.Product.initializeProduct(module,
module.__name__,
module.__path__[0],
app)
product.package_name = module.__name__
if init_func is not None:
newContext = ProductContext(product, app, module)
init_func(newContext)
if not doInstall():
transaction.abort()
else:
transaction.get().note('Installed package %s' % module.__name__)
transaction.commit()
except:
if log_exc:
LOG.error("Couldn't install %s" % module.__name__,
exc_info=True)
transaction.abort()
if raise_exc:
raise
def install_standards(app):
# Check to see if we've already done this before
# Don't do it twice (Casey)
......
......@@ -26,7 +26,6 @@ $Id$
"""
import os, sys, time
import transaction
# Allow code to tell it is run by the test framework
os.environ['ZOPETESTCASE'] = '1'
......@@ -133,62 +132,60 @@ if not Zope2._began_startup:
# Allow test authors to install Zope products into the test environment. Note
# that installProduct() must be called at module level -- never from tests.
from OFS.Application import get_folder_permissions, get_products, install_product
from OFS.Application import get_folder_permissions, get_products
from OFS.Application import install_product, install_package
from OFS.Folder import Folder
import Products
_theApp = Zope2.app()
_installedProducts = {}
_installedPackages = {}
def hasProduct(name):
'''Checks if a product can be found along Products.__path__'''
return name in [n[1] for n in get_products()]
def installProduct(name, quiet=0, package=False):
def installProduct(name, quiet=0):
'''Installs a Zope product.'''
start = time.time()
meta_types = []
if _patched and not _installedProducts.has_key(name):
if package:
# Processing of products-as-packages can be simpler; also check
# whether this has been registered with <five:registerPackage />
# and has not been loaded.
for module_, init_func in getattr(Products, '_packages_to_initialize', []):
if module_.__name__ == name:
if not quiet: _print('Installing %s ... ' % name)
try:
product = App.Product.initializeProduct(module_,
module_.__name__,
module_.__path__[0],
_theApp)
product.package_name = module_.__name__
if init_func is not None:
newContext = App.ProductContext.ProductContext(product, app, module_)
init_func(newContext)
finally:
transaction.commit()
Globals.InitializeClass(Folder)
if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
break
for priority, product_name, index, product_dir in get_products():
if product_name == name:
if not quiet: _print('Installing %s ... ' % product_name)
# We want to fail immediately if a product throws an exception
# during install, so we set the raise_exc flag.
install_product(_theApp, product_dir, product_name, meta_types,
get_folder_permissions(), raise_exc=1)
_installedProducts[product_name] = 1
Products.meta_types = Products.meta_types + tuple(meta_types)
Globals.InitializeClass(Folder)
if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
break
else:
for priority, product_name, index, product_dir in get_products():
if product_name == name:
if not quiet: _print('Installing %s ... ' % product_name)
# We want to fail immediately if a product throws an exception
# during install, so we set the raise_exc flag.
install_product(_theApp, product_dir, product_name, meta_types,
get_folder_permissions(), raise_exc=1)
_installedProducts[product_name] = 1
Products.meta_types = Products.meta_types + tuple(meta_types)
Globals.InitializeClass(Folder)
if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
break
else:
if name != 'SomeProduct': # Ignore the skeleton tests :-P
if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
if name != 'SomeProduct': # Ignore the skeleton tests :-P
if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
def hasPackage(name):
'''Checks if a package has been registered with five:registerPackage.'''
return name in [m.__name__ for m in getattr(Products, '_registered_packages', [])]
def installPackage(name, quiet=0):
'''Installs a registered Python package like a Zope product.'''
start = time.time()
if _patched and not _installedPackages.has_key(name):
for module, init_func in getattr(Products, '_packages_to_initialize', []):
if module.__name__ == name:
if not quiet: _print('Installing %s ... ' % module.__name__)
# We want to fail immediately if a package throws an exception
# during install, so we set the raise_exc flag.
install_package(_theApp, module, init_func, raise_exc=1)
_installedPackages[module.__name__] = 1
Products._packages_to_initialize.remove((module, init_func))
if not quiet: _print('done (%.3fs)\n' % (time.time() - start))
break
else:
if not quiet: _print('Installing %s ... NOT FOUND\n' % name)
def _load_control_panel():
# Loading the Control_Panel of an existing ZODB may take
......@@ -219,6 +216,7 @@ DB = Zope2.DB
configure = Zope2.configure
def startup(): pass
Zope = Zope2
active = _patched
# ZODB sandbox factory
from ZODB.DemoStorage import DemoStorage
......
......@@ -20,6 +20,8 @@ import utils
from ZopeLite import hasProduct
from ZopeLite import installProduct
from ZopeLite import hasPackage
from ZopeLite import installPackage
from ZopeLite import _print
from ZopeTestCase import folder_name
......
......@@ -18,6 +18,8 @@
publish_module(). Thanks to Andreas Zeidler.
- Fixed doctestsuite factory to copy layers from test_class to the suite.
Thanks to Whit Morris.
- Added hasPackage and installPackage functions for dealing with "products"
registered via five:registerPackage.
0.9.8 (Zope 2.8 edition)
- Renamed 'doctest' package to 'zopedoctest' because of name-shadowing
......
def initialize(context):
print 'testpackage.initialize called'
##############################################################################
#
# Copyright (c) 2005 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.
#
##############################################################################
"""Tests for installPackage
$Id$
"""
import os, sys
if __name__ == '__main__':
execfile(os.path.join(sys.path[0], 'framework.py'))
from unittest import TestSuite
from Testing import ZopeTestCase
from Testing.ZopeTestCase import ZopeLite
from Testing.ZopeTestCase import ZopeDocTestSuite
from Products.Five import zcml
from zope.testing import cleanup
import Products
def testInstallPackage():
"""
Test if installPackage works.
>>> from Testing import ZopeTestCase
>>> from Products.Five import zcml
Register testpackage
>>> ZopeTestCase.hasPackage('testpackage')
False
>>> config = '''
... <configure
... xmlns:five="http://namespaces.zope.org/five">
... <five:registerPackage
... package="testpackage"
... initialize="testpackage.initialize"
... />
... </configure>'''
>>> zcml.load_string(config)
The package is registered now
>>> ZopeTestCase.hasPackage('testpackage')
True
But not yet installed
>>> app = self._app()
>>> 'testpackage' in app.Control_Panel.Products.objectIds()
False
Install it
>>> ZopeTestCase.installPackage('testpackage', quiet=True)
testpackage.initialize called
Now it shows up in Control_Panel
>>> app = self._app()
>>> 'testpackage' in app.Control_Panel.Products.objectIds()
True
hasPackage still returns True
>>> ZopeTestCase.hasPackage('testpackage')
True
A package is only installed once, subsequent calls to installPackage
are ignored:
>>> ZopeTestCase.installPackage('testpackage', quiet=True)
"""
class TestClass(ZopeTestCase.FunctionalTestCase):
def afterSetUp(self):
cleanup.cleanUp()
zcml._initialized = False
zcml.load_site()
self.saved = sys.path[:]
sys.path.append(ZopeTestCase.__path__[0])
def afterClear(self):
cleanup.cleanUp()
sys.path[:] = self.saved
registered = getattr(Products, '_registered_packages', None)
if registered is not None:
Products._registered_packages = [m for m in registered
if m.__name__ != 'testpackage']
to_initialize = getattr(Products, '_packages_to_initialize', None)
if to_initialize is not None:
Products._packages_to_initialize = [(m, f) for (m, f) in to_initialize
if m.__name__ != 'testpackage']
def test_suite():
if ZopeLite.active:
return TestSuite((
ZopeDocTestSuite(test_class=TestClass),
))
else:
return TestSuite()
if __name__ == '__main__':
framework()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment