[Zope-CVS] CVS: Packages/zpkgtools/zpkgtools - app.py:1.27
include.py:1.27
Fred L. Drake, Jr.
fred at zope.com
Mon Apr 19 10:34:01 EDT 2004
Update of /cvs-repository/Packages/zpkgtools/zpkgtools
In directory cvs.zope.org:/tmp/cvs-serv23204/zpkgtools
Modified Files:
app.py include.py
Log Message:
- rename INCLUDE.cfg to PACKAGE.cfg, since it now deals with more
aspects of package construction
- allow the PACKAGE.cfg file to include specifications for
constructing both the component itself and a distribution containing
the component as the primary resource; this allows a more
conventional distribution to be presented to an end user
(the distribution portion of this is still not used in the zpkg script)
=== Packages/zpkgtools/zpkgtools/app.py 1.26 => 1.27 ===
--- Packages/zpkgtools/zpkgtools/app.py:1.26 Fri Apr 16 14:42:05 2004
+++ Packages/zpkgtools/zpkgtools/app.py Mon Apr 19 10:33:30 2004
@@ -229,14 +229,7 @@
"""
destination = os.path.join(self.destination, name)
self.ip.add_manifest(destination)
- spec = include.Specification(source)
- include_path = os.path.join(source, "INCLUDE.cfg")
- if os.path.isfile(include_path):
- f = open(include_path)
- try:
- spec.load(f, include_path)
- finally:
- f.close()
+ spec, dist = include.load(source)
if type == "package":
self.add_package_component(name, destination, spec)
=== Packages/zpkgtools/zpkgtools/include.py 1.26 => 1.27 ===
--- Packages/zpkgtools/zpkgtools/include.py:1.26 Fri Apr 16 17:54:33 2004
+++ Packages/zpkgtools/zpkgtools/include.py Mon Apr 19 10:33:31 2004
@@ -34,6 +34,7 @@
from zpkgtools import Error
+from zpkgtools import cfgparser
from zpkgtools import cvsloader
from zpkgtools import publication
@@ -42,16 +43,41 @@
EXCLUDE_NAMES = ["CVS", ".cvsignore", "RCS", "SCCS", ".svn"]
EXCLUDE_PATTERNS = ["*.py[cdo]", "*.s[ol]", ".#*", "*~"]
+# Name of the configuration file:
+PACKAGE_CONF = "PACKAGE.cfg"
+
class InclusionError(Error):
pass
-class InclusionSpecificationError(ValueError, InclusionError):
- def __init__(self, message, filename, lineno):
+class InclusionSpecificationError(cfgparser.ConfigurationError, InclusionError):
+ def __init__(self, message, filename=None, lineno=None):
+ InclusionError.__init__(self, message)
+ cfgparser.ConfigurationError.__init__(self, message)
self.filename = filename
self.lineno = lineno
- ValueError.__init__(self, message)
+
+
+def load(sourcedir):
+ """Return the specifications for populating the distribution and
+ collection directories.
+
+ If there is not specification file, return empty specifications.
+ """
+ package_conf = os.path.join(sourcedir, PACKAGE_CONF)
+ schema = SpecificationSchema(sourcedir, 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()
+ config.collection.excludes[package_conf] = package_conf
+ else:
+ config = schema.getConfiguration()
+ return config.collection, config.distribution
def filter_names(names):
@@ -67,33 +93,88 @@
return names
-def normalize_path(path, type, filename, lineno):
+def normalize_path(path, type):
if ":" in path:
scheme, rest = urllib.splittype(path)
if len(scheme) == 1:
# looks like a drive letter for Windows; scream,
# 'cause that's not allowable:
raise InclusionSpecificationError(
- "drive letters are not allowed in inclusions: %r"
- % path,
- filename, lineno)
+ "drive letters are not allowed in inclusions: %r" % path)
np = posixpath.normpath(path)
if posixpath.isabs(np) or np[:1] == ".":
raise InclusionSpecificationError(
"%s path must not be absolute or refer to a location"
" not contained in the source directory"
- % path,
- filename, lineno)
+ % path)
return np.replace("/", os.sep)
-def normalize_path_or_url(path, type, filename, lineno):
+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, filename, lineno)
+ return normalize_path(path, type)
+
+
+class SpecificationSchema(cfgparser.Schema):
+ """Specialized schema that handles populating a pair of Specifications.
+ """
+
+ def __init__(self, source, filename):
+ self.filename = filename
+ self.source = source
+
+ def getConfiguration(self):
+ conf = cfgparser.SectionValue(None, None, None)
+ conf.collection = self.collection = Specification(self.source)
+ conf.distribution = self.distribution = Specification(self.source)
+ 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
+ raise cfgparser.ConfigurationError("unknown section type: %s"
+ % typename)
+
+ def endSection(self, parent, typename, name, child):
+ pass
+
+ def createSection(self, name, typename, typedef):
+ raise NotImplementedError(
+ "createSection() should not be called for SpecificationSchema")
+
+ def finishSection(self, section):
+ return section
+
+ def addValue(self, section, dest, src):
+ if not isinstance(section, Specification):
+ raise cfgparser.ConfigurationError(
+ "all inclusion lines must be in a <collection> or"
+ " <distribution> section")
+ dest = normalize_path(dest, "destination")
+ src = normalize_path_or_url(src, "source")
+ if src == "-":
+ if section is self.distribution:
+ raise InclusionSpecificationError(
+ "cannot exclude files from the distribution root",
+ self.filename)
+ path = os.path.join(self.source, dest)
+ expansions = filter_names(glob.glob(path))
+ if not expansions:
+ raise InclusionSpecificationError(
+ "exclusion %r doesn't match any files" % dest,
+ self.filename)
+ for fn in expansions:
+ section.excludes[fn] = fn
+ else:
+ section.includes[dest] = src
class Specification:
@@ -111,7 +192,7 @@
"""
# XXX Needing to pass the source directory to the constructor is a
- # bit of a hack, and is only needed to support exclusions. A
+ # bit of a hack, ... A
# better approach may be to have "raw" and "cooked" versions of
# the specification object; the raw version would only have the
# information loaded from a specification file, and the cooked
@@ -132,47 +213,6 @@
self.excludes = {}
self.includes = {}
self.source = source
-
- def load(self, f, filename):
- """Load the specification data from a stream.
-
- :Parameters:
- - `f`: An open stream to read from.
-
- - `filename`: A name to associate with the stream. This is
- only used for reporting information in exceptions.
-
- :Exceptions:
- - `InclusionSpecificationError`: Raised for any error in the
- input specification.
-
- """
- lineno = 0
- for line in f:
- lineno += 1
- line = line.strip()
- if line[:1] in ("", "#"):
- continue
- parts = line.split(None, 1)
- if len(parts) != 2:
- raise InclusionSpecificationError(
- "inclusion specifications require"
- " both target and source parts",
- filename, lineno)
- dest, src = parts
- dest = normalize_path(dest, "destination", filename, lineno)
- src = normalize_path_or_url(src, "source", filename, lineno)
- if src == "-":
- path = os.path.join(self.source, dest)
- expansions = filter_names(glob.glob(path))
- if not expansions:
- raise InclusionSpecificationError(
- "exclusion %r doesn't match any files" % dest,
- filename, lineno)
- for fn in expansions:
- self.excludes[fn] = fn
- else:
- self.includes[dest] = src
class InclusionProcessor:
More information about the Zope-CVS
mailing list