[Zope-CVS] SVN: zpkgtools/branches/fdrake-zconfig-branch/ snapshot:
almost there, but not all the tests are passing
Fred L. Drake, Jr.
fdrake at gmail.com
Tue Aug 30 01:08:17 EDT 2005
Log message for revision 38153:
snapshot: almost there, but not all the tests are passing
Changed:
_U zpkgtools/branches/fdrake-zconfig-branch/
U zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/cfgparser.py
U zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.py
A zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.xml
D zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/tests/test_cfgparser.py
U zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/urlutils.py
U zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.py
A zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.xml
U zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.py
A zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.xml
U zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/locationmap.py
U zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/tests/test_include.py
-=-
Property changes on: zpkgtools/branches/fdrake-zconfig-branch
___________________________________________________________________
Name: svn:externals
+ ZConfig svn://svn.zope.org/repos/main/ZConfig/trunk
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/cfgparser.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/cfgparser.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/cfgparser.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -1,360 +1,154 @@
-##############################################################################
-#
-# Copyright (c) 2004 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.
-#
-##############################################################################
-"""Extra-lite parser for a `ZConfig`_-like configuration syntax.
+"""Configuration parsing based on ZConfig instead of the bastard parser.
-There is no support for external schemas; schemas are simpler and must
-be specified using Python data structures.
-
-There is no support for any %-directives, but dollar signs in values
-must be doubled to ensure compatibility with `ZConfig`_.
-
-.. _ZConfig: http://www.zope.org/Members/fdrake/zconfig/
-
"""
+__docformat__ = "reStructuredText"
-import re
+import os
+import sys
+import ZConfig.cfgparser
+import ZConfig.cmdline
+import ZConfig.datatypes
+import ZConfig.loader
-class ConfigurationError(Exception):
- """Exception raised for errors in a configuration file.
+from ZConfig import ConfigurationError
- :ivar url: URL of the resource being read when the error was
- detected.
- :ivar lineno: Line number within the resource at which the
- error was detected.
+# This is new:
- """
+def cachedSchemaLoader(filename="schema.xml", package=None):
+ if package is None:
+ frame = sys._getframe(1)
+ __path__ = _get_path_from_frame(frame)
+ elif package == "":
+ __path__ = sys.path
+ else:
+ __import__(package)
+ __path__ = sys.modules[package].__path__
- def __init__(self, message, url=None, lineno=None):
- """Initialize the ConfigurationError instance.
+ cache = []
+ def loadSchemaCache():
+ if cache:
+ return cache[0]
+ for p in __path__:
+ path = os.path.join(p, filename)
+ if os.path.isfile(path):
+ schema = loadSchema(path)
+ cache.append(schema)
+ return schema
+ raise ValueError("could not locate schema %r for package %r (path=%r)"
+ % (filename, package, __path__))
- :param message: Text of the error message.
+ return loadSchemaCache
- :param url: URL of the resource being read when the error was
- detected.
+def _get_path_from_frame(frame):
+ globs = frame.f_globals
+ if "__path__" in globs:
+ return globs["__path__"]
+ path = globs.get("__file__")
+ module = globs.get("__name__")
+ if (path and module):
+ dir, fn = os.path.split(path)
+ fnbase, ext = os.path.splitext(fn)
+ if "." in module and fnbase == "__init__":
+ package = module[:module.rindex(".")]
+ return sys.modules[package].__path__
+ if "." in module:
+ # the module is likely still being imported for the first
+ # time; just drop the module name and check the package
+ package = module[:module.rindex(".")]
+ return sys.modules[package].__path__
+ return sys.path
- :param lineno: Line number within the resource at which the
- error was detected.
- """
- Exception.__init__(self, message)
- self.url = url
- self.lineno = lineno
- def __str__(self):
- s = Exception.__str__(self)
- if self.url:
- s = "%s\n(%s" % (s, self.url)
- if self.lineno is not None:
- s = "%s, line %s" % (s, self.lineno)
- s += ")"
- return s
+def loadSchema(url):
+ return SchemaLoader().loadURL(url)
-class Schema:
- """Schema definition that can be used by the Parser class to
- construct a configuration.
+def loadSchemaFile(file, url=None):
+ return SchemaLoader().loadFile(file, url)
- The definition is defined as a set of *type definitions*. Each
- type definition is a triple containing a dictionary, a list, and a
- function (or `None`). The dictionary maps the names of the keys
- allowed in the section to conversion functions for the values (or
- None if no conversion is required). The list names the section
- types which can occur in the section. The function is used to
- convert a `SectionValue` representing the collected values to the
- actual value of the section itself; if `None` is used, no
- conversion is performed.
+def loadConfig(schema, url, overrides=()):
+ return _get_config_loader(schema, overrides).loadURL(url)
- """
+def loadConfigFile(schema, file, url=None, overrides=()):
+ return _get_config_loader(schema, overrides).loadFile(file, url)
- def __init__(self, toplevel, typedefs=None):
- """Initialize a schema definition based on type definitions.
- :param toplevel: Type definition that represents the otherwise
- anonymous top-level section of a configuration.
+def _get_config_loader(schema, overrides):
+ if overrides:
+ loader = ExtendedConfigLoader(schema)
+ for opt in overrides:
+ loader.addOption(opt)
+ else:
+ loader = ConfigLoader(schema)
+ return loader
- :param typedefs: Mapping from typenames (which must be given
- as lower-case strings) to type definitions. Only section
- types specified in `typedefs` can be used anywhere in
- configurations described by the schema.
- """
- self._toplevel = toplevel
- if typedefs is None:
- typedefs = {}
- self._typedefs = typedefs
+# These classes override enough to get case-sensitive behavior by default;
- def getConfiguration(self):
- """Return a configuration object for the top-level section.
+class Parser(ZConfig.cfgparser.ZConfigParser):
+ """ZConfig-parser that doesn't lower-case section types and names."""
- :return: New configuration object.
+ def _normalize_case(self, string):
+ return string
- The attributes of the configuration object represent values
- that have not been specified in a configuration file; these
- will be filled in during parsing.
- """
- return self.createSection(None, None, self._toplevel)
- def startSection(self, parent, typename, name):
- # make sure typename is defined:
- typedef = self._typedefs.get(typename)
- if typedef is None:
- raise ConfigurationError("unknown section type: %s" % typename)
- # make sure typename is allowed:
- x, sects, x = parent.getSectionDefinition()
- if typename not in sects:
- parent_type = parent.getSectionType()
- if parent_type:
- msg = ("%r sections not allowed in %r sections"
- % (typename, parent_type))
- else:
- msg = "%r sections not allowed" % typename
- raise ConfigurationError(msg)
- return self.createSection(name, typename, typedef)
+class BasicKeyConversion(ZConfig.datatypes.BasicKeyConversion):
+ """Alternate basic-key type that does no case-normalizing."""
- def createSection(self, name, typename, typedef):
- child = SectionValue(name, typename, typedef)
- keys, sects, x = typedef
- # initialize the defaults:
- for name in keys:
- name = name.lower().replace("-", "_")
- setattr(child, name, [])
- for name in sects:
- name = name.lower().replace("-", "_")
- setattr(child, name, [])
- return child
+ def __call__(self, value):
+ value = str(value)
+ return ZConfig.datatypes.RegularExpressionConversion.__call__(
+ self, value)
- def finishSection(self, section):
- x, x, datatype = section.getSectionDefinition()
- if datatype is not None:
- typename = section.getSectionType()
- try:
- section = datatype(section)
- except ValueError, e:
- raise ConfigurationError(
- "could not convert %r section value: %s"
- % (typename, e))
- return section
- def endSection(self, parent, typename, name, child):
- value = self.finishSection(child)
- getattr(parent, typename).append(value)
+def SchemaLoader(registry=None):
+ if registry is None:
+ registry = ZConfig.datatypes.Registry()
+ registry._stock["basic-key"] = BasicKeyConversion()
+ return ZConfig.loader.SchemaLoader(registry)
- def addValue(self, section, key, value):
- keys, x, x = section.getSectionDefinition()
- keyname = key.lower()
- if keyname not in keys:
- typename = section.getSectionType()
- if typename:
- msg = "key %r not defined in %r sections" % (key, typename)
- else:
- msg = "key %r not defined" % key
- raise ConfigurationError(msg)
- datatype = keys[keyname]
- if datatype is not None:
- try:
- value = datatype(value)
- except ValueError, e:
- raise ConfigurationError("could not convert value: %s" % e)
- attrname = keyname.replace("-", "_")
- getattr(section, attrname).append(value)
+class ConfigLoaderMixin:
-# These regular expressions should match the corresponding definitions
-# in ZConfig.cfgparser since this needs to be a format that could be
-# read by ZConfig with an appropriate schema definition.
-#
-_name_re = r"[^\s()]+"
-_keyvalue_rx = re.compile(r"(?P<key>%s)\s*(?P<value>[^\s].*)?$"
- % _name_re)
-_section_start_rx = re.compile(r"(?P<type>%s)"
- r"(?:\s+(?P<name>%s))?"
- r"$"
- % (_name_re, _name_re))
+ def _parse_resource(self, matcher, resource, defines=None):
+ parser = Parser(resource, self, defines)
+ parser.parse(matcher)
-_nulljoin = "".join
+class ConfigLoader(ConfigLoaderMixin, ZConfig.loader.ConfigLoader):
+ pass
-class Parser:
- """Parser for ZConfig-like configuration files."""
- def __init__(self, file, url, schema):
- self.schema = schema
- self.file = file
- self.url = url
- self.lineno = 0
- self.stack = [] # [(type, name, prevmatcher), ...]
+class ExtendedConfigLoader(ConfigLoaderMixin,
+ ZConfig.cmdline.ExtendedConfigLoader):
- def nextline(self):
- line = self.file.readline()
- if line:
- self.lineno += 1
- return False, line.strip()
+ def cook(self):
+ if self.clopts:
+ return OptionBag(self.schema, self.schema, self.clopts)
else:
- return True, None
+ return None
- def load(self):
- section = self.schema.getConfiguration()
- self.parse(section)
- try:
- return self.schema.finishSection(section)
- except ConfigurationError, e:
- e.lineno = self.lineno
- e.url = self.url
- raise
- def parse(self, section):
- done, line = self.nextline()
- while not done:
- if line[:1] in ("", "#"):
- # blank line or comment
- pass
+class OptionBag(ZConfig.cmdline.OptionBag):
- elif line[:2] == "</":
- # section end
- if line[-1] != ">":
- self.error("malformed section end")
- section = self.end_section(section, line[2:-1])
-
- elif line[0] == "<":
- # section start
- if line[-1] != ">":
- self.error("malformed section start")
- section = self.start_section(section, line[1:-1])
-
- elif line[0] == "%":
- self.error("ZConfig-style directives are not supported")
-
+ def get_section_info(self, type, name):
+ L = [] # what pertains to the child section
+ R = [] # what we keep
+ for item in self.sectitems:
+ optpath, val, pos = item
+ s = optpath[0]
+ bk = self.basic_key(s, pos)
+ if name and s == name:
+ L.append((optpath[1:], val, pos))
+ elif bk == type:
+ L.append((optpath[1:], val, pos))
else:
- self.handle_key_value(section, line)
-
- done, line = self.nextline()
-
- if self.stack:
- self.error("unclosed sections not allowed")
-
- def start_section(self, section, rest):
- isempty = rest[-1:] == "/"
- if isempty:
- text = rest[:-1].rstrip()
+ R.append(item)
+ if L:
+ self.sectitems[:] = R
+ return OptionBag(self.schema, self.schema.gettype(type), L)
else:
- text = rest.rstrip()
- # parse section start stuff here
- m = _section_start_rx.match(text)
- if not m:
- self.error("malformed section header")
- type, name = m.group('type', 'name')
- type = type.lower()
- #
- # XXX Argh! Converting section names to lower-case was a
- # mistake in ZConfig, but we have to honor case here for
- # <extension> sections. We need to add some way to control
- # the "nametype" of sections in ZConfig anyway.
- #
- # if name:
- # name = name.lower()
- #
- try:
- newsect = self.schema.startSection(section, type, name)
- except ConfigurationError, e:
- e.lineno = self.lineno
- e.url = self.url
- raise
- if isempty:
- try:
- self.schema.endSection(section, type, name, newsect)
- except ConfigurationError, e:
- e.lineno = self.lineno
- e.url = self.url
- raise
- return section
- else:
- self.stack.append((type, name, section))
- return newsect
-
- def end_section(self, section, rest):
- if not self.stack:
- self.error("unexpected section end")
- type = rest.rstrip().lower()
- opentype, name, prevsection = self.stack.pop()
- if type != opentype:
- self.error("unbalanced section end")
- try:
- self.schema.endSection(prevsection, type, name, section)
- except ConfigurationError, e:
- e.lineno = self.lineno
- e.url = self.url
- raise
- return prevsection
-
- def handle_key_value(self, section, rest):
- m = _keyvalue_rx.match(rest)
- if not m:
- self.error("malformed configuration data")
- key, value = m.group('key', 'value')
- if value:
- value = self.replace(value)
- else:
- value = ''
- try:
- self.schema.addValue(section, key, value)
- except ConfigurationError, e:
- e.lineno = self.lineno
- e.url = self.url
- raise
-
- def replace(self, text):
- parts = []
- rest = text
- while "$" in rest:
- i = rest.index("$")
- if i:
- parts.append(rest[:i])
- rest = rest[i+1:]
- if not rest:
- self.error("text cannot end with a bare '$'")
- if rest[0] == "$":
- parts.append("$")
- rest = rest[1:]
- else:
- self.error("unsupported substitution syntax")
- parts.append(rest)
- return _nulljoin(parts)
-
- def error(self, message):
- raise ConfigurationError(message, self.url, self.lineno)
-
-
-class SectionValue:
- """Generic bag-of-values object for a section."""
-
- def __init__(self, name, typename, typedef):
- self._name = name
- self._typename = typename
- self._typedef = typedef
-
- def getSectionName(self):
- """Return the name of the section, or `None`."""
- return self._name
-
- def getSectionType(self):
- """Return the name of the section type."""
- return self._typename
-
- def getSectionDefinition(self):
- """Return the data structure that represents the type of this
- section value.
- """
- return self._typedef
+ return None
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -55,7 +55,7 @@
:Groups:
- `Public interface`: loadCollectionInfo loadPackageInfo
- `Helper functions`: create_extension expand_globs read_package_info
- - `Datatype functions`: cpp_definition cpp_names path_ref extension
+ - `Datatype functions`: cpp_definition cpp_names path_ref
"""
@@ -74,7 +74,9 @@
PACKAGE_CONF = "SETUP.cfg"
+get_schema = cfgparser.cachedSchemaLoader("package.xml")
+
class Header(object):
"""Information about a header file and the package that provides it."""
@@ -103,7 +105,7 @@
"""
pkginfo = read_package_info(directory, reldir)
pkginfo.extensions = [create_extension(ext, pkgname, reldir)
- for ext in pkginfo.extension]
+ for ext in pkginfo.extensions]
pkginfo.package_headers = [Header(pkgname, path)
for path in pkginfo.header]
return pkginfo
@@ -123,7 +125,7 @@
"""
pkginfo = read_package_info(directory, reldir)
pkginfo.extensions = [create_extension(ext, None, reldir)
- for ext in pkginfo.extension]
+ for ext in pkginfo.extensions]
pkginfo.package_headers = [Header(None, path)
for path in pkginfo.header]
return pkginfo
@@ -154,10 +156,11 @@
url = "<no file>"
f = StringIO("")
try:
- p = cfgparser.Parser(f, url, PackageSchema(directory, reldir))
- pkginfo = p.load()
+ pkginfo, _ = cfgparser.loadConfigFile(get_schema(), f, url)
finally:
f.close()
+ for name, data_files in pkginfo.data_files:
+ data_files[:] = expand_globs(directory, reldir, data_files)
pkginfo.documentation = expand_globs(directory, reldir,
pkginfo.documentation)
pkginfo.header = expand_globs(directory, reldir, pkginfo.header)
@@ -243,9 +246,9 @@
"""
kwargs = {}
if pkgname:
- kwargs["name"] = "%s.%s" % (pkgname, section.name)
+ kwargs["name"] = "%s.%s" % (pkgname, section.getSectionName())
else:
- kwargs["name"] = section.name
+ kwargs["name"] = section.getSectionName()
kwargs["sources"] = [posixpath.join(reldir, fn)
for fn in section.source]
if section.define:
@@ -385,22 +388,12 @@
_cpp_ident_match = re.compile("[A-Za-z_][A-Za-z_0-9]*$").match
-def extension(section):
- """Transform `section`, checking several fields for valid values.
+def empty_string(s):
+ if s:
+ raise ValueError("data-file specifications may not have values")
+ return s
- :param section: Configuration section.
- :return: Modified section.
- """
- section.name = section.getSectionName()
- if not section.name:
- raise ValueError("extensions must be named")
- if not section.source:
- raise ValueError("at least one extension source file must be listed")
- if len(section.language) > 1:
- raise ValueError("language can only be specified once")
- return section
-
def path_ref(s):
"""Datatype for a local path reference.
@@ -456,80 +449,6 @@
return p
-class PackageSchema(cfgparser.Schema):
- """Schema implementation with a <data-files> section type.
-
- The <data-files> sections have keys that are glob-expanded (based
- on information passed to the constructor) and combined into a
- single ``data_files`` member on the resulting package information
- object. The value of the ``data_files`` attribute is suitable for
- passing to the `distutils.core.setup()` function.
-
- """
-
- def __init__(self, directory, reldir):
- cfgparser.Schema.__init__(
- self,
- ({"script": path_ref,
- "documentation": path_ref,
- "header": path_ref},
- ["extension"], None),
- {"extension": ({"source": path_ref, "depends-on": path_ref,
- "define" : cpp_definition, "undefine": cpp_names,
- "language": str,
- },
- (), extension),
- }
- )
- self.__cf = None
- self.__datafiles = None
- self.__directory = directory
- self.__reldir = reldir
-
- def getConfiguration(self):
- assert self.__cf is None
- self.__cf = cfgparser.Schema.getConfiguration(self)
- self.__cf.data_files = []
- return self.__cf
-
- def startSection(self, parent, typename, name):
- if self.__datafiles is not None:
- raise cfgparser.ConfigurationError(
- "can't nest another section inside <data-files> section")
- if typename == "data-files":
- if not name:
- raise cfgparser.ConfigurationError(
- "<data-files> section must have a name")
- normname = posixpath.normpath(name)
- for target, files in self.__cf.data_files:
- if target == normname:
- raise cfgparser.ConfigurationError(
- "can't have two sections of the same name:"
- " <data-files %s>" % name)
- self.__datafiles = []
- self.__cf.data_files.append((normname, self.__datafiles))
- # The return value is passed around, but that's it
- return ()
- else:
- return cfgparser.Schema.startSection(self, parent, typename, name)
-
- def endSection(self, parent, typename, name, child):
- if self.__datafiles is None:
- cfgparser.Schema.endSection(self, parent, typename, name, child)
- else:
- # mutate self.__datafiles since the reference from
- # self.__cf.data_files is what's actually used
- self.__datafiles[:] = expand_globs(self.__directory,
- self.__reldir,
- self.__datafiles)
- self.__datafiles = None
-
- def addValue(self, section, key, value):
- if self.__datafiles is not None:
- if value:
- raise cfgparser.ConfigurationError(
- "each entry in a <data-files> section must be"
- " a single glob pattern")
- self.__datafiles.append(key)
- else:
- cfgparser.Schema.addValue(self, section, key, value)
+def data_file_section(section):
+ name = posixpath.normpath(section.getSectionName())
+ return name, section.files.keys()
Added: zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.xml
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.xml 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.xml 2005-08-30 05:08:16 UTC (rev 38153)
@@ -0,0 +1,36 @@
+<schema prefix="zpkgsetup">
+ <description>
+ Schema for zpkg SETUP.cfg files, used to provide distutils
+ metadata for individual packages.
+ </description>
+
+ <sectiontype name="extension">
+ <key name="language" datatype="basic-key"/>
+ <multikey name="define" datatype=".package.cpp_definition"/>
+ <multikey name="undefine" datatype=".package.cpp_names"/>
+ <multikey name="source" datatype=".package.path_ref" required="yes"/>
+ <multikey name="depends-on" datatype=".package.path_ref"/>
+ </sectiontype>
+
+ <sectiontype name="data-files"
+ keytype=".package.path_ref"
+ datatype=".package.data_file_section">
+ <key name="+" attribute="files" datatype=".package.empty_string"/>
+ </sectiontype>
+
+ <multisection name="+" attribute="extensions" type="extension"/>
+ <multisection name="+" attribute="data_files" type="data-files"/>
+
+ <multikey name="documentation"
+ datatype=".package.path_ref">
+ </multikey>
+
+ <multikey name="header"
+ datatype=".package.path_ref">
+ </multikey>
+
+ <multikey name="script"
+ datatype=".package.path_ref">
+ </multikey>
+
+</schema>
Property changes on: zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/package.xml
___________________________________________________________________
Name: svn:eol-style
+ native
Deleted: zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/tests/test_cfgparser.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/tests/test_cfgparser.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/tests/test_cfgparser.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -1,162 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 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 zpkgtools.cfgparser."""
-
-import unittest
-
-from StringIO import StringIO
-
-from zpkgsetup import cfgparser
-
-
-class SimpleSection:
-
- finished = False
- ending_parent = None
- ending_typename = None
- ending_name = None
-
- def __init__(self, parent=None, typename=None, name=None):
- self.parent = parent
- self.typename = typename
- self.name = name
-
-
-class AnythingGoesSchema:
-
- def getConfiguration(self):
- return SimpleSection()
-
- def startSection(self, parent, typename, name):
- return SimpleSection(parent, typename, name)
-
- def finishSection(self, section):
- section.finished = True
- return section
-
- def endSection(self, parent, typename, name, child):
- child.ending_parent = parent
- child.ending_typename = typename
- child.ending_name = name
- if not hasattr(parent, typename):
- setattr(parent, typename, [])
- getattr(parent, typename).append(child)
- self.finishSection(child)
-
- def addValue(self, section, key, value):
- key = key.lower().replace("-", "_")
- if not hasattr(section, key):
- setattr(section, key, [])
- getattr(section, key).append(value)
-
-
-class ParserTestCase(unittest.TestCase):
-
- schema = AnythingGoesSchema()
-
- def createParser(self, text=""):
- sio = StringIO(text)
- self.parser = cfgparser.Parser(sio, "<some-url>", self.schema)
- return self.parser
-
- def test_replace(self):
- # "legal" values are those that are legal in ZConfig
- eq = self.assertEqual
- raises = self.assertRaises
- replace = self.createParser().replace
-
- # some legal values that don't have '$':
- eq(replace(""), "")
- eq(replace(" foo bar "), " foo bar ")
- eq(replace("x"), "x")
-
- # legal, supported values with '$':
- eq(replace("$$"), "$")
- eq(replace("$$$$"), "$$")
- eq(replace("$$xyz$$"), "$xyz$")
-
- # legal, unsupported values (all have '$'):
- raises(cfgparser.ConfigurationError, replace, "$foo")
- raises(cfgparser.ConfigurationError, replace, "${foo-bar}")
-
- # illegal values:
- raises(cfgparser.ConfigurationError, replace, "$")
- raises(cfgparser.ConfigurationError, replace, "foo$")
-
- def test_schema_use(self):
- eq = self.assertEqual
- p = self.createParser("""
- # This is a comment.
-
- key value 1
- key value 2
- <section/>
- <section foo/>
- <section>
- key value 3
- </section>
- <section splat>
- <inner>
- key value 5
- </inner>
- key value 4
- </section>
- """)
- cf = p.load()
- self.check_section(cf, None, None, None, key=["value 1", "value 2"])
- s1, s2, s3, s4 = cf.section
- self.check_section(s1, cf, None, "section")
- self.check_section(s2, cf, "foo", "section")
- self.check_section(s3, cf, None, "section", key=["value 3"])
- self.check_section(s4, cf, "splat", "section", key=["value 4"])
- inner, = s4.inner
- self.check_section(inner, s4, None, "inner", key=["value 5"])
-
- def check_section(self, section, parent, name, typename, **attrs):
- self.assert_(section.finished)
- self.assert_(section.parent is parent)
- self.assert_(section.parent is section.ending_parent)
- self.assertEqual(section.name, name)
- self.assertEqual(section.name, section.ending_name)
- self.assertEqual(section.typename, typename)
- self.assertEqual(section.typename, section.ending_typename)
- for name, value in attrs.iteritems():
- v = getattr(section, name)
- self.assertEqual(v, value)
-
-
-class SchemaTestCase(unittest.TestCase):
-
- top_level_converted = False
-
- def setUp(self):
- self.schema = cfgparser.Schema(
- ({}, [], self.top_level_conversion))
-
- def top_level_conversion(self, section):
- self.top_level_converted = True
- return section
-
- def test_getConfiguration(self):
- cf = self.schema.getConfiguration()
- self.failIf(self.top_level_converted)
-
-
-def test_suite():
- suite = unittest.makeSuite(ParserTestCase)
- suite.addTest(unittest.makeSuite(SchemaTestCase))
- return suite
-
-if __name__ == "__main__":
- unittest.main(defaultTest="test_suite")
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/urlutils.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/urlutils.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgsetup/urlutils.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -17,8 +17,15 @@
import posixpath
import urllib
+import urlparse
+# svn: and svn+ssh: weren't handled properly by urlparse before Python
+# 2.4.2 and 2.5; this makes all versions handled them correctly:
+#
+if "svn" not in urlparse.uses_netloc:
+ urlparse.uses_netloc.extend(["svn", "svn+ssh"])
+
def file_url(path):
return "file://" + pathname2url(path)
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -32,16 +32,8 @@
from zpkgtools import locationmap
-TRUE_STRINGS =("yes", "true", "on")
-FALSE_STRINGS = ("no", "false", "off")
+get_schema = cfgparser.cachedSchemaLoader("config.xml")
-def boolean(string):
- s = string.lower()
- if s in FALSE_STRINGS:
- return False
- if s in TRUE_STRINGS:
- return True
- raise ValueError("unknown boolean value: %r" % string)
def non_empty_string(string):
if not string:
@@ -49,44 +41,10 @@
return string
-class Schema(cfgparser.Schema, object):
+def resource_map(value):
+ return value.map
- def __init__(self, filename, locations):
- # We can use the base schema for the top-level definitions,
- # except for the <resources> section.
- super(Schema, self).__init__(
- ({"resource-map": non_empty_string,
- "include-support-code": boolean,
- "collect-dependencies": boolean,
- "build-application": boolean,
- "default-collection": non_empty_string,
- }, ["resources"], None))
- self.base = urlutils.file_url(filename)
- self.filename = filename
- self.locations = locations
- def startSection(self, parent, typename, name):
- if typename != "resources":
- raise cfgparser.ConfigurationError(
- "only <resources> sections are allowed")
- if isinstance(parent, locationmap.MapLoader):
- raise cfgparser.ConfigurationError(
- "<resources> sections may not be nested")
- return locationmap.MapLoader(self.base, self.filename, self.locations)
-
- def addValue(self, section, key, value):
- if isinstance(section, locationmap.MapLoader):
- section.add(key, value)
- else:
- super(Schema, self).addValue(section, key, value)
-
- def finishSection(self, section):
- if isinstance(section, locationmap.MapLoader):
- return section.mapping
- return super(Schema, self).finishSection(section)
-
-
-
class Configuration:
"""Configuration settings for **zpkg**.
@@ -146,37 +104,27 @@
basedir = os.path.abspath(basedir)
else:
basedir = os.getcwd()
- p = cfgparser.Parser(f, path, Schema(os.path.abspath(path),
- self.locations))
- cf = p.load()
- base = urlutils.file_url(basedir) + "/"
- for value in cf.resource_map:
- value = urlparse.urljoin(base, value)
+ schema = get_schema()
+ url = urlutils.file_url(os.path.abspath(path))
+ cf, _ = cfgparser.loadConfigFile(schema, f, url)
+ # deal with embedded resource maps:
+ for map in cf.resource_maps:
+ for key, value in map.iteritems():
+ value = urlparse.urljoin(url, value)
+ if key.endswith(".*"):
+ wildcard = key[:-2]
+ if not self.locations._have_wildcard(wildcard):
+ self.locations._add_wildcard(wildcard, value)
+ elif key not in self.locations:
+ self.locations[key] = value
+ self.application = cf.build_application
+ self.collect_dependencies = cf.collect_dependencies
+ self.default_collection = cf.default_collection
+ self.include_support_code = cf.include_support_code
+ self.resource_maps = cf.resource_maps
+ for value in cf.location_maps:
+ value = urlparse.urljoin(url, value)
self.location_maps.append(value)
- # include-support-code
- if len(cf.include_support_code) > 1:
- raise cfgparser.ConfigurationError(
- "include-support-code can be specified at most once")
- if cf.include_support_code:
- self.include_support_code = cf.include_support_code[0]
- # collect-dependencies
- if len(cf.collect_dependencies) > 1:
- raise cfgparser.ConfigurationError(
- "collect-dependencies can be specified at most once")
- if cf.collect_dependencies:
- self.collect_dependencies = cf.collect_dependencies[0]
- # build-application
- if len(cf.build_application) > 1:
- raise cfgparser.ConfigurationError(
- "build-application can be specified at most once")
- if cf.build_application:
- self.application = cf.build_application[0]
- # default-collection
- if len(cf.default_collection) > 1:
- raise cfgparser.ConfigurationError(
- "default-collection can be specified at most once")
- if cf.default_collection:
- self.default_collection = cf.default_collection[0]
def defaultConfigurationPath():
Added: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.xml
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.xml 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.xml 2005-08-30 05:08:16 UTC (rev 38153)
@@ -0,0 +1,59 @@
+<schema prefix="zpkgtools">
+ <description>
+ Schema for zpkg configuration files.
+ </description>
+
+ <sectiontype name="resources"
+ datatype=".config.resource_map"
+ keytype=".locationmap.resource_name"
+ >
+ <key name="+"
+ attribute="map"
+ type=".config.non_empty_string"
+ />
+ </sectiontype>
+
+ <multisection type="resources"
+ attribute="resource_maps"
+ >
+ <description>
+ Embedded resource maps.
+ </description>
+ </multisection>
+
+ <multikey name="resource-map"
+ attribute="location_maps"
+ required="no"
+ datatype=".config.non_empty_string"
+ >
+ <description>
+ Each 'resource-map' is a URL reference to a resource map in an
+ external resource. Relative references are resolved relative to
+ the resource in which they're embedded.
+ </description>
+ </multikey>
+
+ <key name="build-application"
+ datatype="boolean"
+ required="no"
+ default="no"
+ />
+
+ <key name="collect-dependencies"
+ datatype="boolean"
+ required="no"
+ default="no"
+ />
+
+ <key name="default-collection"
+ datatype=".config.non_empty_string"
+ required="no"
+ />
+
+ <key name="include-support-code"
+ datatype="boolean"
+ required="no"
+ default="yes"
+ />
+
+</schema>
Property changes on: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/config.xml
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -27,6 +27,7 @@
from zpkgsetup import cfgparser
from zpkgsetup import loggingapi as logging
+from zpkgsetup import package
from zpkgsetup import publication
from zpkgsetup import setup
from zpkgsetup import urlutils
@@ -41,6 +42,84 @@
PACKAGE_CONF = "PACKAGE.cfg"
+get_schema = cfgparser.cachedSchemaLoader("include.xml")
+
+
+def collection_path_ref(value):
+ if value == "-":
+ return value
+ if value:
+ return normalize_path(value, "destination")
+ else:
+ return None
+
+def distribution_path_ref(value):
+ if value == "-":
+ raise ValueError("exclusion not allowed in <distribution>")
+ if value:
+ return normalize_path(value, "destination")
+ else:
+ return None
+
+def load_path_ref(value):
+ if value == "-":
+ raise ValueError("exclusion not allowed in <load>")
+ if not value:
+ raise ValueError("source must be specified in <load>")
+ return normalize_path_or_url(value, "source")
+
+def workspace_path_ref(value):
+ return normalize_path(value, "workspace file")
+
+
+def collection_section(section):
+ excludes = []
+ includes = {}
+ for (k, vs) in section.mapping.iteritems():
+ for v in vs:
+ if v == "-":
+ if len(vs) != 1:
+ raise ValueError("too many exclusions specified for %s"
+ % k)
+ excludes.append(k)
+ continue
+ if v:
+ includes[k] = v
+ else:
+ L = includes.setdefault(None, [])
+ L.append(k)
+ if excludes and includes:
+ raise ValueError(
+ "includes and excludes cannot be mixed in <collection>")
+ section.excludes = excludes
+ section.includes = includes
+ return section
+
+def distribution_section(section):
+ includes = {}
+ for (k, v) in section.mapping.iteritems():
+ if v:
+ includes[v] = k
+ else:
+ L = includes.setdefault(None, [])
+ L.append(k)
+ section.excludes = {}
+ section.includes = includes
+ return section
+
+def load_section(section):
+ includes = {}
+ for (k, v) in section.mapping.iteritems():
+ if v:
+ includes[v] = k
+ else:
+ L = includes.setdefault(None, [])
+ L.append(k)
+ section.excludes = {}
+ section.includes = includes
+ return section
+
+
class InclusionError(Error):
"""Raised to indicate errors processing inclusions."""
@@ -74,26 +153,37 @@
If there is not specification file, return empty specifications.
"""
package_conf = os.path.join(sourcedir, PACKAGE_CONF)
- schema = SpecificationSchema(sourcedir, package_conf)
+ url = urlutils.file_url(os.path.abspath(package_conf))
if os.path.isfile(package_conf):
- f = open(package_conf, "rU")
- try:
- parser = cfgparser.Parser(f, package_conf, schema)
- config = parser.load()
- finally:
- f.close()
- if config.collection.excludes:
- # XXX should make sure PACKAGE_CONF isn't already excluded
- config.collection.excludes.append(PACKAGE_CONF)
- elif not config.collection.includes:
- # Nothing included or excluded; simply exclude PACKAGE_CONF:
- config.collection.excludes.append(PACKAGE_CONF)
+ cf, _ = cfgparser.loadConfig(get_schema(), package_conf)
+ config = PackageConstruction(sourcedir, package_conf)
+ if cf.collection is not None:
+ if cf.collection.excludes:
+ # XXX should make sure PACKAGE_CONF isn't already excluded
+ cf.collection.excludes.append(PACKAGE_CONF)
+ elif not cf.collection.includes:
+ # Nothing included or excluded; simply exclude PACKAGE_CONF:
+ cf.collection.excludes.append(PACKAGE_CONF)
+ config.collection.excludes = cf.collection.excludes
+ config.collection.includes = cf.collection.includes
+ if cf.distribution is not None:
+ config.distribution.includes = cf.distribution.includes
+ if cf.loads is not None:
+ config.loads.includes = cf.loads.includes
else:
- config = schema.getConfiguration()
+ config = PackageConstruction(sourcedir, None)
return config
-def normalize_path(path, type, group):
+class PackageConstruction(object):
+
+ def __init__(self, source, filename):
+ self.loads = Specification(source, filename, "load")
+ self.collection = Specification(source, filename, "collection")
+ self.distribution = Specification(source, filename, "distribution")
+
+
+def normalize_path(path, type):
if ":" in path:
scheme, rest = urllib.splittype(path)
if len(scheme) == 1:
@@ -116,99 +206,99 @@
return np.replace("/", os.sep)
-def normalize_path_or_url(path, type, group):
+def normalize_path_or_url(path, type):
if ":" in path:
scheme, rest = urllib.splittype(path)
if len(scheme) != 1:
# should normalize the URL, but skip that for now
return path
- return normalize_path(path, type, group)
+ return normalize_path(path, type)
-class SpecificationSchema(cfgparser.Schema):
- """Specialized schema that handles populating a set of Specifications.
- """
+##class SpecificationSchema(cfgparser.Schema):
+## """Specialized schema that handles populating a set of Specifications.
+## """
- def __init__(self, source, filename):
- self.filename = filename
- self.source = source
+## def __init__(self, source, filename):
+## self.filename = filename
+## self.source = source
- def getConfiguration(self):
- conf = cfgparser.SectionValue(None, None, None)
- conf.loads = Specification(
- self.source, self.filename, "load")
- conf.collection = Specification(
- self.source, self.filename, "collection")
- conf.distribution = Specification(
- self.source, self.filename, "distribution")
- return conf
+## def getConfiguration(self):
+## conf = cfgparser.SectionValue(None, None, None)
+## conf.loads = Specification(
+## self.source, self.filename, "load")
+## conf.collection = Specification(
+## self.source, self.filename, "collection")
+## conf.distribution = Specification(
+## self.source, self.filename, "distribution")
+## return conf
- def startSection(self, parent, typename, name):
- if not isinstance(parent, cfgparser.SectionValue):
- raise cfgparser.ConfigurationError("unexpected section")
- if typename == "collection":
- return parent.collection
- elif typename == "distribution":
- return parent.distribution
- elif typename == "load":
- return parent.loads
- raise cfgparser.ConfigurationError("unknown section type: %s"
- % typename)
+## def startSection(self, parent, typename, name):
+## if not isinstance(parent, cfgparser.SectionValue):
+## raise cfgparser.ConfigurationError("unexpected section")
+## if typename == "collection":
+## return parent.collection
+## elif typename == "distribution":
+## return parent.distribution
+## elif typename == "load":
+## return parent.loads
+## raise cfgparser.ConfigurationError("unknown section type: %s"
+## % typename)
- def endSection(self, parent, typename, name, child):
- if child.includes and child.excludes:
- # XXX not sure what the exact semantics should be of
- # allowing both inclusions and exclusions at the same
- # time; which takes precedence? what about precedence
- # when wildcards are involved?
- raise cfgparser.ConfigurationError(
- "exclusions and inclusions cannot coexist in a single section")
+## def endSection(self, parent, typename, name, child):
+## if child.includes and child.excludes:
+## # XXX not sure what the exact semantics should be of
+## # allowing both inclusions and exclusions at the same
+## # time; which takes precedence? what about precedence
+## # when wildcards are involved?
+## raise cfgparser.ConfigurationError(
+## "exclusions and inclusions cannot coexist in a single section")
- def createSection(self, name, typename, typedef):
- raise NotImplementedError(
- "createSection() should not be called for SpecificationSchema")
+## def createSection(self, name, typename, typedef):
+## raise NotImplementedError(
+## "createSection() should not be called for SpecificationSchema")
- def finishSection(self, section):
- return section
+## def finishSection(self, section):
+## return section
- def addValue(self, section, workfile, other):
- if not isinstance(section, Specification):
- raise cfgparser.ConfigurationError(
- "all inclusion lines must be in a section")
+## def addValue(self, section, workfile, other):
+## if not isinstance(section, Specification):
+## raise cfgparser.ConfigurationError(
+## "all inclusion lines must be in a section")
- if other == "-":
- # This is an exclusion.
- if section.group != "collection":
- raise cfgparser.ConfigurationError(
- "exclusions are only permitted in <collection>")
- workfile = normalize_path(workfile, "exclusion", section.group)
- section.excludes.append(workfile)
- return
+## if other == "-":
+## # This is an exclusion.
+## if section.group != "collection":
+## raise cfgparser.ConfigurationError(
+## "exclusions are only permitted in <collection>")
+## workfile = normalize_path(workfile, "exclusion", section.group)
+## section.excludes.append(workfile)
+## return
- if section.group == "load":
- if not other:
- raise cfgparser.ConfigurationError(
- "referenced file must be named explicitly"
- " in <load> section")
- # perhaps should make sure workfile and other don't refer
- # to the same file
- other = normalize_path_or_url(other, "source", section.group)
- elif other:
- # workfile and other have a backward relationship for this:
- # <destination>
- # target workfile
- # </destination>
- other = normalize_path(other, "destination", section.group)
+## if section.group == "load":
+## if not other:
+## raise cfgparser.ConfigurationError(
+## "referenced file must be named explicitly"
+## " in <load> section")
+## # perhaps should make sure workfile and other don't refer
+## # to the same file
+## other = normalize_path_or_url(other, "source", section.group)
+## elif other:
+## # workfile and other have a backward relationship for this:
+## # <destination>
+## # target workfile
+## # </destination>
+## other = normalize_path(other, "destination", section.group)
- if workfile:
- workfile = normalize_path(workfile, "workspace file",
- section.group)
+## if workfile:
+## workfile = normalize_path(workfile, "workspace file",
+## section.group)
- if other:
- section.includes[other] = workfile
- else:
- L = section.includes.setdefault(None, [])
- L.append(workfile)
+## if other:
+## section.includes[other] = workfile
+## else:
+## L = section.includes.setdefault(None, [])
+## L.append(workfile)
class Specification:
Added: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.xml
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.xml 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.xml 2005-08-30 05:08:16 UTC (rev 38153)
@@ -0,0 +1,37 @@
+<schema prefix="zpkgtools">
+
+ <sectiontype name="collection"
+ datatype=".include.collection_section"
+ keytype=".include.workspace_path_ref">
+ <multikey name="+"
+ attribute="mapping"
+ datatype=".include.collection_path_ref"
+ />
+ </sectiontype>
+
+ <sectiontype name="distribution"
+ datatype=".include.distribution_section"
+ keytype=".include.workspace_path_ref">
+ <key name="+"
+ attribute="mapping"
+ datatype=".include.distribution_path_ref"
+ />
+ </sectiontype>
+
+ <sectiontype name="load"
+ datatype=".include.load_section"
+ keytype=".include.workspace_path_ref">
+ <key name="+"
+ attribute="mapping"
+ datatype=".include.load_path_ref"
+ />
+ </sectiontype>
+
+ <section type="collection"
+ attribute="collection"/>
+ <section type="distribution"
+ attribute="distribution"/>
+ <section type="load"
+ attribute="loads"/>
+
+</schema>
Property changes on: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/include.xml
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/locationmap.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/locationmap.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/locationmap.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -150,6 +150,17 @@
self.path = path
+def resource_name(value):
+ if value.endswith(".*"):
+ if not is_module_name(value[:-2]):
+ raise ValueError("wildcard package name specified, but"
+ " prefix is not a legal package name: %r"
+ % value)
+ elif "*" in value:
+ raise ValueError("invalid wildcard specification: %r" % resource)
+ return value
+
+
class MapLoader:
def __init__(self, base, filename, mapping):
Modified: zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/tests/test_include.py
===================================================================
--- zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/tests/test_include.py 2005-08-30 05:06:48 UTC (rev 38152)
+++ zpkgtools/branches/fdrake-zconfig-branch/zpkgtools/tests/test_include.py 2005-08-30 05:08:16 UTC (rev 38153)
@@ -194,7 +194,7 @@
</collection>
""")
specs = include.load(self.source)
- self.assertRaises(include.InclusionSpecificationError,
+ self.assertRaises(cfgparser.ConfigurationError,
specs.collection.cook)
def test_omitted_destination_keeps_name(self):
@@ -234,7 +234,7 @@
</%s>
""" % (sectionname, sectionname)
self.write_file(include.PACKAGE_CONF, text)
- self.assertRaises(include.InclusionSpecificationError,
+ self.assertRaises(cfgparser.ConfigurationError,
include.load, self.source)
# These two tests are really checking internal helpers, but
@@ -251,29 +251,29 @@
self.check_normalize_urls(normalize)
def check_normalize_paths(self, normalize):
- self.assertEqual(normalize("README.txt", "t", "group"),
+ self.assertEqual(normalize("README.txt", "t"),
"README.txt")
- self.assertEqual(normalize("doc/README.txt", "t", "group"),
+ self.assertEqual(normalize("doc/README.txt", "t"),
join("doc", "README.txt"))
- self.assertEqual(normalize(".", "t", "group"),
+ self.assertEqual(normalize(".", "t"),
os.curdir)
# Ignore this because it looks like a Windows drive letter:
self.assertRaises(include.InclusionSpecificationError,
- normalize, "c:foo/bar", "t", "group")
+ normalize, "c:foo/bar", "t")
# Absolute paths are an error as well:
self.assertRaises(include.InclusionSpecificationError,
- normalize, "/absolute/path", "t", "group")
+ normalize, "/absolute/path", "t")
# Relative paths that point up the hierarchy are also disallowed:
self.assertRaises(include.InclusionSpecificationError,
- normalize, "abc/../../def.txt", "t", "group")
+ normalize, "abc/../../def.txt", "t")
self.assertRaises(include.InclusionSpecificationError,
- normalize, "../def.txt", "t", "group")
+ normalize, "../def.txt", "t")
def check_normalize_urls(self, normalize):
for url in ("http://www.example.com/index.html",
"repository:/Zope3/doc",
"cvs://cvs.zope.com/cvs-repository:/Zope3/doc:HEAD"):
- self.assertEqual(normalize(url, "t", "group"), url)
+ self.assertEqual(normalize(url, "t"), url)
def test_createDistributionTree_creates_destination(self):
os.rmdir(self.destination)
More information about the Zope-CVS
mailing list