Skip to content

Commit

Permalink
Merge pull request #13 from zopefoundation/maurits/debug-log
Browse files Browse the repository at this point in the history
Env var Z3C_AUTOINCLUDE_DEBUG: log included packages
  • Loading branch information
mauritsvanrees committed Mar 8, 2020
2 parents 8602105 + e040f7c commit 91be705
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Breaking changes:

New features:

- When environment variable ``Z3C_AUTOINCLUDE_DEBUG`` is set,
log which packages are being automatically included.
Do this in a form that you can copy to a ``configure.zcml`` file.

- Add support for Python 3.8.

Bug fixes:
Expand Down
17 changes: 15 additions & 2 deletions src/z3c/autoinclude/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

DEP_KEY = 'Z3C_AUTOINCLUDE_DEPENDENCIES_DISABLED'
PLUGIN_KEY = 'Z3C_AUTOINCLUDE_PLUGINS_DISABLED'
DEBUG_KEY = 'Z3C_AUTOINCLUDE_DEBUG'


def dependencies_disabled():
Expand All @@ -13,7 +14,7 @@ def disable_dependencies():


def enable_dependencies():
del os.environ[DEP_KEY]
os.environ.pop(DEP_KEY, None)


def plugins_disabled():
Expand All @@ -25,4 +26,16 @@ def disable_plugins():


def enable_plugins():
del os.environ[PLUGIN_KEY]
os.environ.pop(PLUGIN_KEY, None)


def debug_enabled():
return DEBUG_KEY in os.environ


def disable_debug():
os.environ.pop(DEBUG_KEY, None)


def enable_debug():
os.environ[DEBUG_KEY] = 'True'
71 changes: 71 additions & 0 deletions src/z3c/autoinclude/api.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
=============
API functions
=============

The ``api.py`` module has some helpful functions.


Plugins
=======

We can disable and enable autoincluding the plugins::

>>> from z3c.autoinclude import api
>>> api.plugins_disabled()
False
>>> api.disable_plugins()
>>> api.plugins_disabled()
True
>>> api.disable_plugins() # called twice to see if this breaks
>>> api.plugins_disabled()
True
>>> api.enable_plugins()
>>> api.plugins_disabled()
False
>>> api.enable_plugins() # called twice to see if this breaks
>>> api.plugins_disabled()
False


Dependencies
============

We can disable and enable autoincluding the dependencies::

>>> from z3c.autoinclude import api
>>> api.dependencies_disabled()
False
>>> api.disable_dependencies()
>>> api.dependencies_disabled()
True
>>> api.disable_dependencies() # called twice to see if this breaks
>>> api.dependencies_disabled()
True
>>> api.enable_dependencies()
>>> api.dependencies_disabled()
False
>>> api.enable_dependencies() # called twice to see if this breaks
>>> api.dependencies_disabled()
False


Debug
=====

We can disable and enable the debug report of autoincluded packages::

>>> from z3c.autoinclude import api
>>> api.debug_enabled()
False
>>> api.enable_debug()
>>> api.debug_enabled()
True
>>> api.enable_debug() # called twice to see if this breaks
>>> api.debug_enabled()
True
>>> api.disable_debug()
>>> api.debug_enabled()
False
>>> api.disable_debug() # called twice to see if this breaks
>>> api.debug_enabled()
False
11 changes: 11 additions & 0 deletions src/z3c/autoinclude/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from pkg_resources import resource_exists
from pkg_resources import get_provider
from pkg_resources import get_distribution
from z3c.autoinclude.api import debug_enabled
from z3c.autoinclude.utils import DistributionManager
from z3c.autoinclude.utils import ZCMLInfo
from z3c.autoinclude.utils import create_report


logger = logging.getLogger("z3c.autoinclude")
Expand Down Expand Up @@ -42,6 +44,15 @@ def includableInfo(self, zcml_to_look_for):
)
if os.path.isfile(candidate_path):
result[candidate].append(dotted_name)

if debug_enabled():
report = create_report(result)
if "overrides.zcml" in zcml_to_look_for:
report.insert(0, "includeDependenciesOverrides found in zcml of %s." % self.context.project_name)
else:
report.insert(0, "includeDependencies found in zcml of %s." % self.context.project_name)
logger.info("\n".join(report))

return result


Expand Down
15 changes: 15 additions & 0 deletions src/z3c/autoinclude/plugin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import logging
import os
from pkg_resources import iter_entry_points
from pkg_resources import resource_filename
from z3c.autoinclude.api import debug_enabled
from z3c.autoinclude.utils import create_report
from z3c.autoinclude.utils import DistributionManager
from z3c.autoinclude.utils import ZCMLInfo


logger = logging.getLogger("z3c.autoinclude")


class PluginFinder(object):
def __init__(self, platform_dottedname):
self.dottedname = platform_dottedname
Expand All @@ -18,6 +24,15 @@ def includableInfo(self, zcml_to_look_for):
groups = zcml_to_include(plugin_dottedname, zcml_to_look_for)
for zcml_group in groups:
includable_info[zcml_group].append(plugin_dottedname)

if debug_enabled():
report = create_report(includable_info)
if "overrides.zcml" in zcml_to_look_for:
report.insert(0, "includePluginsOverrides found in zcml of %s." % self.dottedname)
else:
report.insert(0, "includePlugins found in zcml of %s." % self.dottedname)
logger.info("\n".join(report))

return includable_info


Expand Down
11 changes: 9 additions & 2 deletions src/z3c/autoinclude/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,14 @@ def test_suite():

from pprint import pprint

suite = doctest.DocFileSuite(
simple_suite = doctest.DocFileSuite(
'../api.txt',
globs={'pprint': pprint},
checker=IgnoreCaseChecker(),
optionflags=doctest.ELLIPSIS,
)

advanced_suite = doctest.DocFileSuite(
'../utils.txt',
'../dependency.txt',
'../plugin.txt',
Expand All @@ -129,7 +136,7 @@ def test_suite():
optionflags=doctest.ELLIPSIS,
)

return unittest.TestSuite((suite,))
return unittest.TestSuite((simple_suite, advanced_suite))


if __name__ == '__main__':
Expand Down
32 changes: 32 additions & 0 deletions src/z3c/autoinclude/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ def __init__(self, zcml_to_look_for):
for zcml_group in zcml_to_look_for:
self[zcml_group] = []

def __bool__(self):
return any(self.values())

# For Python 2:
__nonzero__ = __bool__


def subpackageDottedNames(package_path, ns_dottedname=None):
# we do not look for subpackages in zipped eggs
Expand Down Expand Up @@ -206,3 +212,29 @@ def find_packages(where='.', exclude=()):

out = [item for item in out if not fnmatchcase(item, pat)]
return out


def create_report(info):
"""Create a report with a list of auto included zcml."""
if not info:
# Return a comment. Maybe someone wants to automatically include this
# in a zcml file, so make it a proper xml comment.
return ["<!-- No zcml files found to include. -->"]
report = []
# Try to report meta.zcml first.
filenames = list(info)
meta = "meta.zcml"
if meta in filenames:
filenames.remove(meta)
filenames.insert(0, meta)
for filename in filenames:
dotted_names = info[filename]
for dotted_name in dotted_names:
if filename == "overrides.zcml":
line = ' <includeOverrides package="%s" file="%s" />' % (dotted_name, filename)
elif filename == "configure.zcml":
line = ' <include package="%s" />'% dotted_name
else:
line = ' <include package="%s" file="%s" />'% (dotted_name, filename)
report.append(line)
return report
51 changes: 51 additions & 0 deletions src/z3c/autoinclude/utils.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,54 @@ package contained within it::
>>> import F.G
>>> distributionForPackage(F.G) # doctest: +IGNORECASE
SiblingPackage 0.0 (...SiblingPackage-0.0...egg)

We have a helper class ZCMLInfo which is a dictionary which automatically gets keys.
Perhaps a defaultdict would work too now, but let's not change the class at this time.

>>> from z3c.autoinclude.utils import ZCMLInfo
>>> info = ZCMLInfo(['meta.zcml', 'configure.zcml'])
>>> sorted(info.keys())
['configure.zcml', 'meta.zcml']
>>> list(info.values())
[[], []]

When no values are filled in, the boolean should be False.

>>> bool(info)
False

We can create a report of the auto included zcml.

>>> from z3c.autoinclude.utils import create_report
>>> create_report(info)
['<!-- No zcml files found to include. -->']

We add information:

>>> info['configure.zcml'].append('sample_package')
>>> bool(info)
True
>>> create_report(info)
[' <include package="sample_package" />']
>>> info['configure.zcml'].append('package2')
>>> info['meta.zcml'].append('meta_package')
>>> report = create_report(info)
>>> len(report)
3
>>> report[0]
' <include package="meta_package" file="meta.zcml" />'
>>> report[1]
' <include package="sample_package" />'
>>> report[2]
' <include package="package2" />'

We can only add known filenames:

>>> info['overrides.zcml'].append('overrides_package')
Traceback (most recent call last):
...
KeyError: 'overrides.zcml'
>>> overrides = ZCMLInfo(['overrides.zcml'])
>>> overrides['overrides.zcml'].append('overrides_package')
>>> create_report(overrides)
[' <includeOverrides package="overrides_package" file="overrides.zcml" />']

0 comments on commit 91be705

Please sign in to comment.