Package: nti.recipes.zcml
Supported optionsThe recipe supports installing multiple different sets
of ZCML slugs in multiple different output directories.
These sets are specified in grouped options, whereXis the common prefix shared by all options in the group.X_zcmlA list of zcml entires. Required.format:zcml := package ":" filename
package := dottedname | dottedname "-" ( include_name )Thefilenameis the fully specified file, such asbrowser.zcml, whereas theinclude_nameis a relative
portion mising the.zcmlextension, defaulting toconfigure(it was originally validated against a strict list
of possibilities, but that is no longer the case). If the filename
is not given, theinclude_nameis used.NoteEven if you just want to specifyX_features, you
must still have an entry namedX_zcml. It may be
empty in that case.X_locationA directory name relative to the etc-directory
to put the generated slugs in. Required.X_fileA convenient shortuct if all or most of the zcml entries would
have the sameinclude_name. Set this option to make it the
default instead of configure. Optional.X_featuresIf this optional directive is provided, it is a space and newline
separated list of ZCML features that should be provided when the
output directory is processed. These are provided in the first
file.There are two global options:deploymentThe name of azc.recipe.deploymentpart containing the
directory definitions. We will use theetc-directorydefined
in this part as the base for locations.etc-directoryIf you do not specify adeployment, then this value will
be used as the etc-directory.Example usageWe’ll start by creating a buildout that uses the recipe. We will list
three packages that we’d like to create slugs for (a*is ignored
for backwards compatibility), along with a set of features we want to
be provided:>>> write('buildout.cfg',
... """
... [buildout]
... parts = test1
...
... [test1]
... recipe = nti.recipes.zcml
... etc-directory = ${buildout:directory}/zope/etc
... package_location = package-includes
... package_features = foo bar
...                    baz
... package_zcml =
...     *
...     my.package
...     somefile:my.otherpackage
...     my.thirdpackage-meta
... """)Running the buildout gives us:>>> print(system(buildout))
Installing test1.
While:
  Installing test1.
Error: The parents of '/.../sample-buildout/zope/etc/package-includes' do not existWe need to have a valid etc directory. Let’s create one:>>> mkdir("zope")
>>> mkdir("zope", "etc")
>>> print(system(buildout))
Installing test1.We now have a package include directory:>>> ls("zope", "etc")
d  package-includesIt does contain ZCML slugs:>>> ls("zope", "etc", "package-includes")
-  000-features.zcml
-  001-my.package-configure.zcml
-  002-somefile-configure.zcml
-  003-my.thirdpackage-meta.zcmlThese files contain the usual stuff:>>> cat("zope", "etc", "package-includes", "000-features.zcml")
<configure xmlns="http://namespaces.zope.org/zope" xmlns:meta="http://namespaces.zope.org/meta">
    <meta:provides feature="foo" />
    <meta:provides feature="bar" />
    <meta:provides feature="baz" />
</configure>
>>> cat("zope", "etc", "package-includes", "001-my.package-configure.zcml")
<include package="my.package" file="configure.zcml" />
>>> cat("zope", "etc", "package-includes", "002-somefile-configure.zcml")
<include package="somefile" file="my.otherpackage" />
>>> cat("zope", "etc", "package-includes", "003-my.thirdpackage-meta.zcml")
<include package="my.thirdpackage" file="meta.zcml" />Error and Corner CasesNow we will discuss how various corner cases and errors are handled.No ZCML and No FeaturesIf you do not specify any ZCML or features, no files are generated
(note that we’re using a new part name, causing the old part to be
uninstalled):>>> write('buildout.cfg',
... """
... [buildout]
... parts = zcml
...
... [zcml]
... recipe = nti.recipes.zcml
... etc-directory = ${buildout:directory}/zope/etc
... package_location = empty-includes
... package_features =
... package_zcml =
... """)

>>> print(system(buildout))
Uninstalling test1.
Installing zcml.
<BLANKLINE>No directory is created for this part, and when the old part was
uninstalled, it left behind its directory, but no files:>>> ls("zope", "etc")
d  package-includes

>>> ls("zope", "etc", "package-includes")Using a Deployment ReferenceAs mentioned above, we can use azc.recipe.deploymentsection to
find theetcdirectory (in reality, we can accept any part that
has anetc-directorysetting); this will override any locally
specifiedetc-directory. We haven’t created the directory we
specified (and we’re not usingzc.recipe.deploymentto
automatically do so) so this buildout will fail:>>> write('buildout.cfg',
... """
... [buildout]
... parts = zcml
...
... [deployment-settings]
... etc-directory = ${buildout:directory}/zope/deployment-etc
...
... [zcml]
... recipe = nti.recipes.zcml
... deployment = deployment-settings
... etc-directory = ${buildout:directory}/zope/etc
... package_location = empty-includes
... package_features = foo
... package_zcml =
... """)

>>> print(system(buildout))
Uninstalling zcml.
Installing zcml.
While:
  Installing zcml.
Error: The parents of '/.../zope/deployment-etc/empty-includes' do not exist
<BLANKLINE>Malformed Package NamesAn error is raised if the package name is malformed (although at the
moment only the most egregious violations are detected):>>> write('buildout.cfg',
... """
... [buildout]
... parts = zcml
...
... [zcml]
... recipe = nti.recipes.zcml
... etc-directory = ${buildout:directory}/zope/etc
... package_location = empty-includes
... package_zcml = $not_valid
... """)

>>> print(system(buildout))
Installing zcml.
While:
  Installing zcml.
Error: Invalid package name: '$not_valid' parsed as '$not_valid'
<BLANKLINE>Specifying Filenames TwiceWe can specify both theinclude_nameand thefilenamefor a
single entry:>>> write('buildout.cfg',
... """
... [buildout]
... parts = zcml
...
... [zcml]
... recipe = nti.recipes.zcml
... etc-directory = ${buildout:directory}/zope/etc
... package_location = package-includes
... package_zcml = my.package-foo:filename.zcml
... """)

>>> print(system(buildout))
Installing zcml.


>>> ls("zope", "etc", "package-includes")
-  001-my.package-foo.zcml

>>> cat("zope", "etc", "package-includes", "001-my.package-foo.zcml")
<include package="my.package" file="filename.zcml" />Changes1.0.0 (2017-09-18)Initial public release.