[zpkg] SVN: zpkgtools/trunk/ Merge philikon-toplevel-modules branch.
Philipp von Weitershausen
philikon at philikon.de
Tue Nov 29 11:12:14 EST 2005
Log message for revision 40410:
Merge philikon-toplevel-modules branch.
Changed:
U zpkgtools/trunk/test.py
U zpkgtools/trunk/zpkgsetup/loggingapi.py
A zpkgtools/trunk/zpkgsetup/module.xml
U zpkgtools/trunk/zpkgsetup/package.py
U zpkgtools/trunk/zpkgsetup/setup.py
A zpkgtools/trunk/zpkgsetup/tests/input2/
U zpkgtools/trunk/zpkgsetup/tests/test_publication.py
U zpkgtools/trunk/zpkgsetup/tests/test_setup.py
U zpkgtools/trunk/zpkgtools/app.py
U zpkgtools/trunk/zpkgtools/tests/input/README.txt
U zpkgtools/trunk/zpkgtools/tests/input/collection-1/DEPENDENCIES.cfg
A zpkgtools/trunk/zpkgtools/tests/input/module.conf
A zpkgtools/trunk/zpkgtools/tests/input/module.py
U zpkgtools/trunk/zpkgtools/tests/input/packages.map
U zpkgtools/trunk/zpkgtools/tests/test_app.py
-=-
Modified: zpkgtools/trunk/test.py
===================================================================
--- zpkgtools/trunk/test.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/test.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -14,18 +14,18 @@
##############################################################################
"""Convenience test script for Jim.
-$Id: test.py,v 1.1 2004/06/11 02:15:49 fdrake Exp $
+$Id$
"""
import os.path
import sys
try:
- from zope.app.testing.test import process_args
+ from zope.testing import testrunner
except ImportError:
if sys.argv[1:]:
# We got args, but we're not about to support them here.
print >>sys.stderr, \
- "arguments only supported when zope.app.tests is available"
+ "arguments only supported when zope.testing is available"
sys.exit(2)
def test_suite():
@@ -41,5 +41,5 @@
# 1. search for tests in starting in this directory
# 2. there are only unit tests, not functional tests
here = os.path.dirname(os.path.realpath(__file__))
- sys.argv[1:1] = ["-l", here, "-u"]
- process_args()
+ defaults = ['--tests-pattern', '^tests$', "--test-path", here, '-v']
+ result = testrunner.run(defaults)
Modified: zpkgtools/trunk/zpkgsetup/loggingapi.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/loggingapi.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgsetup/loggingapi.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -19,7 +19,7 @@
This isn't sufficient to support building packages with Python 2.2.
-$Id: loggingapi.py,v 1.1 2004/06/11 19:24:35 fdrake Exp $
+$Id$
"""
try:
Copied: zpkgtools/trunk/zpkgsetup/module.xml (from rev 40409, zpkgtools/branches/philikon-toplevel-modules/zpkgsetup/module.xml)
Modified: zpkgtools/trunk/zpkgsetup/package.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/package.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgsetup/package.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -67,6 +67,7 @@
PACKAGE_CONF = "SETUP.cfg"
+MODULE_CONF = "MODULE.cfg"
get_schema = cfgparser.cachedSchemaLoader("package.xml")
@@ -124,6 +125,14 @@
for path in pkginfo.header]
return pkginfo
+def read_module_info(directory):
+ module_schema = cfgparser.cachedSchemaLoader("module.xml")
+ module_cfg = os.path.join(directory, MODULE_CONF)
+ f = file(module_cfg)
+ url = urlutils.file_url(urllib.pathname2url(module_cfg))
+ pkginfo, _ = cfgparser.loadConfigFile(module_schema(), f, url)
+ f.close()
+ return pkginfo
def read_package_info(directory, reldir=None):
"""Read the package information file from a specified directory.
Modified: zpkgtools/trunk/zpkgsetup/setup.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/setup.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgsetup/setup.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -67,6 +67,7 @@
self.package_data = {}
self.package_dir = {}
self.package_headers = []
+ self.py_modules = []
self.ext_modules = []
self.scripts = []
self.platforms = None
@@ -82,6 +83,10 @@
pkgdir = os.path.join(self._working_dir, self._pkgname)
self.scan(self._pkgname, pkgdir, self._pkgname)
depsdir = os.path.join(self._working_dir, "Dependencies")
+ modsdir = os.path.join(self._working_dir, "Modules")
+ if os.path.isdir(modsdir):
+ # we do the following so that top-level modules can be installed
+ self.package_dir[""] = 'Modules'
if os.path.isdir(depsdir):
depnames = os.listdir(depsdir)
suffix = "-%s-%s" % (self._pkgname, self.version)
@@ -97,9 +102,22 @@
print >>sys.stderr, \
"unexpected file in Dependencies/: %r" % name
continue
+
depname = name[:-len(suffix)]
+ reldir = posixpath.join("Dependencies", name, depname)
pkgdir = os.path.join(depdir, depname)
- reldir = posixpath.join("Dependencies", name, depname)
+
+ # quick hack to see if we're dealing with a top-level
+ # module or not. If we are, slightly adjust the
+ # dependency name etc. according to the value supplied
+ # in SETUP.cfg.
+ if os.path.exists(os.path.join(depdir, package.MODULE_CONF)):
+ pkginfo = package.read_module_info(depdir)
+ if pkginfo.module:
+ depname = pkginfo.module[:-3]
+ reldir = "Modules"
+ pkgdir = os.path.join(modsdir, depname)
+
self.scan(depname, pkgdir, reldir)
def setup(self):
@@ -163,7 +181,6 @@
#
parts = root.split("/")
local_root = os.path.join(*parts)
- self.package_dir[""] = root
if os.path.isfile(os.path.join(local_root, package.PACKAGE_CONF)):
# There's a SETUP.cfg at the top level; load it:
pkginfo = package.loadCollectionInfo(
@@ -186,12 +203,18 @@
self.scan_package(pkgname, local_full_path, relative_path)
def scan(self, name, directory, reldir):
+ module_py = directory + '.py'
init_py = os.path.join(directory, "__init__.py")
- if os.path.isfile(init_py):
+ if os.path.isfile(module_py):
+ self.scan_module(name, module_py, reldir)
+ elif os.path.isfile(init_py):
self.scan_package(name, directory, reldir)
else:
self.scan_collection(name, directory, reldir)
+ def scan_module(self, name, filename, reldir):
+ self.py_modules.append(name)
+
def scan_collection(self, name, directory, reldir):
# load the collection metadata
pkginfo = package.loadCollectionInfo(directory, reldir)
Copied: zpkgtools/trunk/zpkgsetup/tests/input2 (from rev 40409, zpkgtools/branches/philikon-toplevel-modules/zpkgsetup/tests/input2)
Modified: zpkgtools/trunk/zpkgsetup/tests/test_publication.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/tests/test_publication.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgsetup/tests/test_publication.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -13,7 +13,7 @@
##############################################################################
"""Tests for zpkgtools.publication
-$Id: test_publication.py,v 1.1 2004/06/14 20:46:41 fdrake Exp $
+$Id$
"""
import unittest
Modified: zpkgtools/trunk/zpkgsetup/tests/test_setup.py
===================================================================
--- zpkgtools/trunk/zpkgsetup/tests/test_setup.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgsetup/tests/test_setup.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -69,8 +69,17 @@
#
#context.packages.sort()
#self.assertEqual(context.packages, ["package", "package2"])
-
+ def test_modules(self):
+ input2 = os.path.join(os.path.dirname(__file__), "input2")
+ context = setup.SetupContext("collection", "0.0.0",
+ os.path.join(input2, "setup.py"))
+ context.initialize()
+ self.assertEqual(context.py_modules, ['module'])
+ self.assertEqual(context.package_dir[''], 'Modules')
def test_suite():
return unittest.makeSuite(SetupContextTestCase)
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: zpkgtools/trunk/zpkgtools/app.py
===================================================================
--- zpkgtools/trunk/zpkgtools/app.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgtools/app.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -211,7 +211,11 @@
def get_component(self, resource, location):
try:
- return Component(resource, location, self.ip)
+ source = self.ip.loader.load(location)
+ if os.path.isfile(source):
+ return ModuleComponent(resource, location, source, self.ip)
+ else:
+ return PackageComponent(resource, location, source, self.ip)
except zpkgtools.Error, e:
self.error(str(e), rc=1)
@@ -384,8 +388,11 @@
raise
-class Component:
- def __init__(self, name, url, ip):
+class PackageComponent:
+ """Regular Python package or non-code component.
+ """
+
+ def __init__(self, name, url, source, ip):
self.name = name
self.url = url
self.ip = ip
@@ -393,7 +400,7 @@
self.destination = None
self.pkginfo = None
self.pubinfo = None
- self.source = self.ip.loader.load(self.url)
+ self.source = source
specs = include.load(self.source)
if specs.loads:
source = self.ip.loader.load_mutable_copy(self.url)
@@ -465,7 +472,7 @@
return self.pubinfo
def is_python_package(self):
- """Return True iff this component represents a Python package."""
+ """Return True if this component represents a Python package."""
if self.destination:
dir = os.path.join(self.destination, self.name)
else:
@@ -473,7 +480,7 @@
return os.path.isfile(os.path.join(dir, "__init__.py"))
def has_packaging_data(self):
- """Return True iff this component contains packaging metadata."""
+ """Return True if this component contains packaging metadata."""
# Should PUBLICATION.cfg count toword this?
dir = self.source
for fn in (package.PACKAGE_CONF,
@@ -544,6 +551,93 @@
f.close()
+class ModuleComponent:
+ """Component representing a top-level module
+ """
+
+ def __init__(self, name, url, source, ip):
+ self.name = name
+ self.url = url
+ self.ip = ip
+ self.dependencies = None
+ self.destination = None
+ self.pkginfo = None
+ self.pubinfo = None
+ self.source = source
+ self.filename = os.path.basename(source)
+ specs = include.load(self.source)
+ specs.collection.cook()
+ specs.distribution.cook()
+ self.collection = specs.collection
+ self.distribution = specs.distribution
+ #
+ # Check that this package is valid:
+ #
+ if not self.is_python_package():
+ raise zpkgtools.Error(
+ "%r is an invalid distribution component: all components must"
+ " either be a Python package or provide a %s file"
+ % (name, package.PACKAGE_CONF))
+
+ def get_dependencies(self):
+ """Get the direct dependencies of this component.
+
+ :return: A set of the dependencies.
+ :rtype: `sets.Set`
+
+ We simply rule that top-level modules have no dependencies.
+ At least we have no way of knowing.
+ """
+ self.dependencies = sets.Set()
+ return self.dependencies
+
+ def get_package_info(self):
+ return self.pkginfo
+
+ def get_publication_info(self):
+ return self.pubinfo
+
+ def is_python_package(self):
+ """Return True if this component represents a Python package."""
+ if self.destination:
+ filename = os.path.join(self.destination, self.filename)
+ else:
+ filename = self.source
+ return os.path.isfile(filename)
+
+ def has_packaging_data(self):
+ """Return True if this component contains packaging metadata.
+
+ For top-level modules, we simply rule that the have no
+ packaging metadata. They just want to be installed, basta."""
+ return False
+
+ def write_package(self, destination):
+ self.destination = destination
+ if not os.path.exists(destination):
+ os.mkdir(destination)
+ self.ip.addIncludes(destination, self.distribution)
+ self.write_module_cfg()
+ module_dest = os.path.join(destination, '..', '..', 'Modules')
+ if not os.path.exists(module_dest):
+ os.mkdir(module_dest)
+ self.ip.copy_file(self.source, module_dest)
+
+ def write_module_cfg(self):
+ module_cfg = os.path.join(self.destination, 'MODULE.cfg')
+ self.ip.add_output(module_cfg)
+ f = file(module_cfg, 'w')
+ print >>f, "module %s" % self.filename
+ f.close()
+
+ def write_setup_cfg(self):
+ pass
+
+ def write_setup_py(self, filename="setup.py", version=None, pathparts=[],
+ distclass=None):
+ pass
+
+
SETUP_HEADER = """\
#! /usr/bin/env python
#
Modified: zpkgtools/trunk/zpkgtools/tests/input/README.txt
===================================================================
--- zpkgtools/trunk/zpkgtools/tests/input/README.txt 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgtools/tests/input/README.txt 2005-11-29 16:12:14 UTC (rev 40410)
@@ -4,8 +4,9 @@
This directory contains a bunch of sample input trees to use with zpkg
and the tests. This is not a package itself, though it contains
-(top-level) packages (as well as non-package directories). The sample
-resources are quite minimal; they don't represent *useful* resources.
+(top-level) packages and modules (as well as non-package directories).
+The sample resources are quite minimal; they don't represent *useful*
+resources.
Making this directory not be a package itself allows zpkg to actually
be able to package itself without losing test data.
Modified: zpkgtools/trunk/zpkgtools/tests/input/collection-1/DEPENDENCIES.cfg
===================================================================
--- zpkgtools/trunk/zpkgtools/tests/input/collection-1/DEPENDENCIES.cfg 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgtools/tests/input/collection-1/DEPENDENCIES.cfg 2005-11-29 16:12:14 UTC (rev 40410)
@@ -1,2 +1,3 @@
package
+module
collection:collection-2
Copied: zpkgtools/trunk/zpkgtools/tests/input/module.conf (from rev 40409, zpkgtools/branches/philikon-toplevel-modules/zpkgtools/tests/input/module.conf)
Copied: zpkgtools/trunk/zpkgtools/tests/input/module.py (from rev 40409, zpkgtools/branches/philikon-toplevel-modules/zpkgtools/tests/input/module.py)
Modified: zpkgtools/trunk/zpkgtools/tests/input/packages.map
===================================================================
--- zpkgtools/trunk/zpkgtools/tests/input/packages.map 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgtools/tests/input/packages.map 2005-11-29 16:12:14 UTC (rev 40410)
@@ -4,3 +4,4 @@
collection-2 collection-2/
package package/
+module module.py
\ No newline at end of file
Modified: zpkgtools/trunk/zpkgtools/tests/test_app.py
===================================================================
--- zpkgtools/trunk/zpkgtools/tests/test_app.py 2005-11-29 15:43:35 UTC (rev 40409)
+++ zpkgtools/trunk/zpkgtools/tests/test_app.py 2005-11-29 16:12:14 UTC (rev 40410)
@@ -18,6 +18,7 @@
import sys
import unittest
import urllib
+import re
from StringIO import StringIO
@@ -291,7 +292,7 @@
sys.stderr = old_stderr
-class ComponentTestCase(unittest.TestCase):
+class PackageComponentTestCase(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp(prefix="test-app-")
@@ -309,25 +310,30 @@
def test_validation_of_package_without_setup_cfg(self):
self.write_app_file("__init__.py", "# make this a package\n")
#
- c = app.Component("mypkg", self.mypkg_url, self.ip)
+ source = self.ip.loader.load(self.mypkg_url)
+ c = app.PackageComponent("mypkg", self.mypkg_url, source, self.ip)
self.assert_(c.is_python_package())
def test_validation_of_package_with_setup_cfg(self):
self.write_app_file("SETUP.cfg", "# this is a simple package\n")
self.write_app_file("__init__.py", "# make this a package\n")
#
- c = app.Component("mypkg", self.mypkg_url, self.ip)
+ source = self.ip.loader.load(self.mypkg_url)
+ c = app.PackageComponent("mypkg", self.mypkg_url, source, self.ip)
self.assert_(c.is_python_package())
def test_validation_of_nonpackage_with_setup_cfg(self):
self.write_app_file("SETUP.cfg", "# this is a simple package\n")
#
- c = app.Component("mypkg", self.mypkg_url, self.ip)
+ source = self.ip.loader.load(self.mypkg_url)
+ c = app.PackageComponent("mypkg", self.mypkg_url, source, self.ip)
self.assert_(not c.is_python_package())
def test_non_validation_of_nonpackage_without_setup_cfg(self):
+ source = self.ip.loader.load(self.mypkg_url)
self.assertRaises(zpkgtools.Error,
- app.Component, "mypkg", self.mypkg_url, self.ip)
+ app.PackageComponent,
+ "mypkg", self.mypkg_url, source, self.ip)
def test_component_metadata_is_copied_by_default(self):
self.write_app_file(publication.PUBLICATION_CONF,
@@ -338,7 +344,8 @@
self.write_app_file(package.PACKAGE_CONF,
"# nothing to specify\n")
#
- c = app.Component("mypkg", self.mypkg_url, self.ip)
+ source = self.ip.loader.load(self.mypkg_url)
+ c = app.PackageComponent("mypkg", self.mypkg_url, source, self.ip)
dest = tempfile.mkdtemp(prefix="test-app-dest-")
try:
c.write_package(dest)
@@ -367,7 +374,8 @@
self.write_app_file("README",
"some text\n")
#
- c = app.Component("mypkg", self.mypkg_url, self.ip)
+ source = self.ip.loader.load(self.mypkg_url)
+ c = app.PackageComponent("mypkg", self.mypkg_url, source, self.ip)
dest = tempfile.mkdtemp(prefix="test-app-dest-")
try:
c.write_package(dest)
@@ -644,7 +652,35 @@
finally:
os.chdir(orig_pwd)
+ def test_toplevel_module_as_a_dependency(self):
+ # Test that a top-level module which is loaded as a dependency
+ # (we don't really support top-level modules as the primary
+ # collection) is properly set up.
+ config = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "input", "module.conf")
+ package_map = self.createPackageMap()
+ app = self.createApplication(
+ ["-C", config, "-t", "-m", package_map])
+ app.run()
+ # test that the module file is copied to the right location
+ modules_dir = os.path.join(app.destination, "Modules")
+ self.assert_(os.path.exists(modules_dir))
+ module_py = os.path.join(app.destination, "Modules", 'module.py')
+ self.assert_(os.path.exists(module_py))
+ orig_module_py = os.path.join(os.path.dirname(__file__), "input",
+ "module.py")
+ self.assertEqual(file(module_py).read(), file(orig_module_py).read())
+
+ # test that MODULE.cfg exists and points to the module file
+ depdir = os.path.join(app.destination, "Dependencies",
+ "module-collection-1-0.0.0")
+ self.assert_(os.path.exists(depdir))
+ module_cfg = os.path.join(depdir, "MODULE.cfg")
+ self.assert_(os.path.exists(module_cfg))
+ self.assert_(re.match(r"module(\s+)module.py", file(module_cfg).read()))
+ shutil.rmtree(app.destination)
+
class DelayedCleanupBuilderApplication(app.BuilderApplication):
def cleanup(self):
@@ -669,7 +705,7 @@
def test_suite():
suite = unittest.makeSuite(CommandLineTestCase)
- suite.addTest(unittest.makeSuite(ComponentTestCase))
+ suite.addTest(unittest.makeSuite(PackageComponentTestCase))
suite.addTest(unittest.makeSuite(BuilderApplicationTestCase))
return suite
More information about the zpkg
mailing list