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 _______________________________________________ zpkg mailing list -- zpkg@zope.org http://mail.zope.org/mailman/listinfo/zpkg