Commit 6ff963e8 authored by Tres Seaver's avatar Tres Seaver

LP #143232: Added option to 'zope.conf' to specify an extensions directory.

o This directory is searched for 'App.Extensions' lookups.  Thanks to Rodrigo
  Senra for the patch.
parent 6dbe74b5
......@@ -100,6 +100,10 @@ Restructuring
Features Added
++++++++++++++
- LP #143232: Added option to 'zope.conf' to specify an additional directory
to be searched for 'App.Extensions' lookups. Thanks to Rodrigo Senra for
the patch.
- Integrated the Products.signalstack / z3c.deadlockdebugger packages. You can
now send a SIGUSR1 signal to a Zope process and get a stack trace of all
threads printed out on the console. This works even if all threads are stuck.
......
......@@ -106,6 +106,11 @@ def getPath(prefix, name, checkProduct=1, suffixes=('',), cfg=None):
import App.config
cfg = App.config.getConfiguration()
if prefix == "Extensions" and getattr(cfg, 'extensions', None) is not None:
found = _getPath(cfg.extensions, '', name, suffixes)
if found is not None:
return found
locations = [cfg.instancehome]
softwarehome = getattr(cfg, 'softwarehome', None)
......
......@@ -195,12 +195,29 @@ class Test_getPath(_TempdirBase, unittest.TestCase):
swext = self._makeTempExtension(name=None, dir=swdir)
swfqn = self._makeFile(swext, 'extension.py')
cfg = self._makeConfig(instancehome=instdir,
softwarehome=swdir,
)
softwarehome=swdir,
)
path = self._callFUT('Extensions', 'extension', checkProduct=0,
suffixes=('py',), cfg=cfg)
self.assertEqual(path, instfqn)
def test_w_cfg_extensions(self):
cfgdir = self._makeTempdir()
cfgfqn = self._makeFile(cfgdir, 'extension.py')
instdir = self._makeTempdir()
instext = self._makeTempExtension(name=None, dir=instdir)
instfqn = self._makeFile(instext, 'extension.py')
swdir = self._makeTempdir()
swext = self._makeTempExtension(name=None, dir=swdir)
swfqn = self._makeFile(swext, 'extension.py')
cfg = self._makeConfig(extensions=cfgdir,
instancehome=instdir,
softwarehome=swdir,
)
path = self._callFUT('Extensions', 'extension', checkProduct=0,
suffixes=('py',), cfg=cfg)
self.assertEqual(path, cfgfqn)
def test_not_found_in_instancehome(self):
import os
instdir = self._makeTempdir()
......@@ -258,6 +275,27 @@ class Test_getPath(_TempdirBase, unittest.TestCase):
suffixes=('py',), cfg=cfg)
self.assertEqual(path, subpkgfqn)
"""
Index: lib/python/App/Extensions.py
===================================================================
--- lib/python/App/Extensions.py (revision 28473)
+++ lib/python/App/Extensions.py (working copy)
@@ -87,8 +87,14 @@
r = _getPath(product_dir, os.path.join(p, prefix), n, suffixes)
if r is not None: return r
+
import App.config
cfg = App.config.getConfiguration()
+
+ if (prefix=="Extensions") and (cfg.extensions is not None):
+ r=_getPath(cfg.extensions, '', name, suffixes)
+ if r is not None: return r
+
sw=os.path.dirname(os.path.dirname(cfg.softwarehome))
for home in (cfg.instancehome, sw):
r=_getPath(home, prefix, name, suffixes)
"""
class Test_getObject(_TempdirBase, unittest.TestCase):
......
......@@ -47,7 +47,7 @@ manage_addExternalMethodForm=DTMLFile('dtml/methodAdd', globals())
def manage_addExternalMethod(self, id, title, module, function, REQUEST=None):
"""Add an external method to a folder
Un addition to the standard object-creation arguments,
In addition to the standard object-creation arguments,
'id' and title, the following arguments are defined:
function -- The name of the python function. This can be a
......@@ -56,11 +56,15 @@ def manage_addExternalMethod(self, id, title, module, function, REQUEST=None):
module -- The name of the file containing the function
definition.
The module normally resides in the 'Extensions'
directory, however, the file name may have a prefix of
The module normally resides in the 'Extensions' directory.
If the zope.conf directive 'extensions' was overriden, then
it will specify where modules should reside.
However, the file name may have a prefix of
'product.', indicating that it should be found in a product
directory.
For example, if the module is: 'ACMEWidgets.foo', then an
attempt will first be made to use the file
'lib/python/Products/ACMEWidgets/Extensions/foo.py'. If this
......@@ -84,7 +88,8 @@ class ExternalMethod(Item, Persistent, Explicit,
The function is defined in an external file. This file is treated
like a module, but is not a module. It is not imported directly,
but is rather read and evaluated. The file must reside in the
'Extensions' subdirectory of the Zope installation, or in an
'Extensions' subdirectory of the Zope installation, or in the directory
specified by the 'extensions' directive in zope.conf, or in an
'Extensions' subdirectory of a product directory.
Due to the way ExternalMethods are loaded, it is not *currently*
......@@ -131,7 +136,7 @@ class ExternalMethod(Item, Persistent, Explicit,
"""Change the external method
See the description of manage_addExternalMethod for a
descriotion of the arguments 'module' and 'function'.
description of the arguments 'module' and 'function'.
Note that calling 'manage_edit' causes the "module" to be
effectively reloaded. This is useful during debugging to see
......
......@@ -48,7 +48,8 @@ class ExternalMethod:
The function is defined in an external file. This file is treated
like a module, but is not a module. It is not imported directly,
but is rather read and evaluated. The file must reside in the
'Extensions' subdirectory of the Zope installation, or in an
'Extensions' subdirectory of the Zope installation, or reside in
the path specified by 'extensions' directive in zope.conf, or in an
'Extensions' subdirectory of a product directory.
Due to the way ExternalMethods are loaded, it is not *currently*
......
......@@ -343,6 +343,14 @@
<metadefault>$instancehome/Products</metadefault>
</multikey>
<key name="extensions" datatype="existing-directory">
<description>
This overrides the path to the Extensions directory.
</description>
<metadefault>$instancehome/Extensions</metadefault>
</key>
<multikey name="path" datatype="string">
<description>
This specifies additional paths directories which are inserted into
......
......@@ -91,6 +91,21 @@ instancehome $INSTANCE
# products /home/chrism/projects/myproducts
# Directive: extensions
#
# Description:
# Name of a directory that contains additional "extensions"
# (implementations of ExternalMethods or catalog brains). This
# directive The directory identified will be searched before the
# 'Extensions' directory of the 'instancehome'.
#
# Default: unset
#
# Example:
#
# extensions /home/chrism/extensions
# Directive: environment
#
# Description:
......
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