summaryrefslogtreecommitdiff
path: root/repoze/bfg/zcml.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-06-29 02:49:30 +0000
committerChris McDonough <chrism@agendaless.com>2009-06-29 02:49:30 +0000
commit2869fc2f7f8fa9a4230d66859f232fe2e764103f (patch)
treef947f4ac308595f115966b47eaea2594697c00c3 /repoze/bfg/zcml.py
parente1622d3f023e1fe5c6a580668ec3f5ecab9c0a37 (diff)
downloadpyramid-2869fc2f7f8fa9a4230d66859f232fe2e764103f.tar.gz
pyramid-2869fc2f7f8fa9a4230d66859f232fe2e764103f.tar.bz2
pyramid-2869fc2f7f8fa9a4230d66859f232fe2e764103f.zip
Merge pkg_resource_overrides branch.
Diffstat (limited to 'repoze/bfg/zcml.py')
-rw-r--r--repoze/bfg/zcml.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py
index 786301c45..38db4ead7 100644
--- a/repoze/bfg/zcml.py
+++ b/repoze/bfg/zcml.py
@@ -1,5 +1,6 @@
import inspect
import types
+import pkg_resources
from zope.configuration import xmlconfig
@@ -27,6 +28,10 @@ from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IUnauthorizedAppFactory
from repoze.bfg.interfaces import ILogger
from repoze.bfg.interfaces import IRequestFactories
+from repoze.bfg.interfaces import IPackageOverrides
+
+from repoze.bfg.resource import OverrideProvider
+from repoze.bfg.resource import PackageOverrides
from repoze.bfg.request import DEFAULT_REQUEST_FACTORIES
from repoze.bfg.request import named_request_factories
@@ -155,6 +160,69 @@ def scan(_context, package, martian=martian):
martian.grok_dotted_name(package.__name__, grokker=module_grokker,
context=_context, exclude_filter=exclude)
+class IResourceDirective(Interface):
+ """
+ Directive for specifying that one package may override resources from
+ another package.
+ """
+ to_override = TextLine(
+ title=u"Override spec",
+ description=u'The spec of the resource to override.',
+ required=True)
+ override_with = TextLine(
+ title=u"With spec",
+ description=u"The spec of the resource providing the override.",
+ required=True)
+
+def _override(package, path, override_package, override_prefix,
+ PackageOverrides=PackageOverrides, pkg_resources=pkg_resources):
+ # PackageOverrides and pkg_resources kw args for tests
+ sm = getSiteManager()
+ override = queryUtility(IPackageOverrides, name=package)
+ if override is None:
+ override = PackageOverrides(package)
+ sm.registerUtility(override, IPackageOverrides, name=package)
+ # register_loader_type will be called too many times if there
+ # is more than one overridden package; that's OK, as our
+ # mutation is idempotent
+ pkg_resources.register_loader_type(type(None), OverrideProvider)
+ override.insert(path, override_package, override_prefix)
+
+def resource(context, to_override, override_with):
+ if to_override == override_with:
+ raise ConfigurationError('You cannot override a resource with itself')
+
+ if to_override.endswith('/'):
+ if not override_with.endswith('/'):
+ raise ConfigurationError(
+ 'A directory cannot be overridden with a file (put a slash '
+ 'at the end of override_with if necessary)')
+
+ if override_with.endswith('/'):
+ if not to_override.endswith('/'):
+ raise ConfigurationError(
+ 'A file cannot be overridden with a directory (put a slash '
+ 'at the end of to_override if necessary)')
+
+ package = to_override
+ path = ''
+ if ':' in to_override:
+ package, path = to_override.split(':', 1)
+
+ override_package = override_with
+ override_prefix = ''
+ if ':' in override_with:
+ override_package, override_prefix = override_with.split(':', 1)
+
+ package = context.resolve(package).__name__
+ override_package = context.resolve(package).__name__
+
+ context.action(
+ discriminator = None,
+ callable = _override,
+ args = (package, path, override_package, override_prefix),
+ )
+
class IRouteDirective(Interface):
""" The interface for the ``route`` ZCML directive
"""