[Zope-CVS] CVS: Packages/zpkgtools/zpkgtools - loader.py:1.1 app.py:1.32 cvsloader.py:1.15 locationmap.py:1.9

Fred L. Drake, Jr. fred at zope.com
Mon Apr 19 23:37:55 EDT 2004


Update of /cvs-repository/Packages/zpkgtools/zpkgtools
In directory cvs.zope.org:/tmp/cvs-serv17007/zpkgtools

Modified Files:
	app.py cvsloader.py locationmap.py 
Added Files:
	loader.py 
Log Message:
move general loader behavior out of the cvsloader module, so that only
provides a helper for actually loading from CVS


=== Added File Packages/zpkgtools/zpkgtools/loader.py ===
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""
"""

import os
import posixpath
import shutil
import tempfile
import urllib
import urllib2
import urlparse

from zpkgtools import cvsloader


def open(url, mode="r"):
    if mode[:1] != "r" or "+" in mode:
        raise ValueError("external resources must be opened in read-only mode")
    loader = Loader()
    path = loader.load(url)
    if os.path.isfile(path):
        return FileProxy(path, mode, loader, url)
    # Only files and directories come from CVS, so no need to check
    # for magical directory entries here:
    loader.cleanup()
    raise IOError(errno.EISDIR, "Is a directory", url)


class Loader:

    def __init__(self, tag=None):
        self.tag = tag or None
        self.workdirs = {}  # URL -> (directory, path, temporary)
        self.cvsloader = None

    def add_working_dir(self, url, directory, path, temporary):
        self.workdirs[url] = (directory, path, temporary)

    def cleanup(self):
        """Remove all checkouts that are present."""
        while self.workdirs:
            url, (directory, path, temporary) = self.workdirs.popitem()
            if temporary:
                if directory:
                    shutil.rmtree(directory)
                else:
                    os.unlink(path)

    def load(self, url):
        if ":" in url:
            type, rest = urllib.splittype(url)
            methodname = "load_" + type
            method = getattr(self, methodname, None)
            if method is None:
                method = self.unknown_load
        else:
            method = self.file_load
        return method(url)

    def load_file(self, url):
        parts = urlparse.urlsplit(url)
        path = urllib.url2pathname(parts[2])
        if not os.path.exists(path):
            raise IOError(errno.ENOENT, "no such file or directory", path)
        self.add_working_dir(url, None, path, False)
        return path

    def load_cvs(self, url):
        if self.cvsloader is None:
            self.cvsloader = cvsloader.CvsLoader()
        parsed_url = cvsloader.parse(url)
        if not parsed_url.tag:
            parsed_url.tag = self.tag
            url = parsed_url.getUrl()
        # If we've already loaded this, use that copy.  This doesn't
        # consider fetching something with a different path that's
        # represented by a previous load():
        if url in self.workdirs:
            return self.workdirs[url][1]

        tmp = tempfile.mkdtemp(prefix="loader-")
        path = self.cvsloader.load(parsed_url, tmp)
        self.add_working_dir(url, tmp, path, True)
        return path

    def load_repository(self, url):
        raise ValueError("repository: URLs must be joined with the"
                         " appropriate cvs: base URL")

    def unknown_load(self, url):
        parts = urlparse.urlparse(url)
        filename = posixpath.basename(parts[2])
        f = urllib2.urlopen(url)
        fd, tmp = tempfile.mkstemp(prefix="loader-")
        try:
            os.fwrite(fd, f.read())
        except:
            os.close(fd)
            os.unlink(tmp)
            raise
        else:
            os.close(fd)
        self.add_working_dir(url, None, tmp, True)
        return tmp


class FileProxy(object):

    def __init__(self, path, mode, loader, url=None):
        self.name = url or path
        self._file = file(path, mode)
        self._cleanup = loader.cleanup

    def __getattr__(self, name):
        return getattr(self._file, name)

    def close(self):
        if not self._file.closed:
            self._file.close()
            self._cleanup()
            self._cleanup = None

    # We shouldn't ever actually need to deal with softspace since
    # we're read-only, but... real files still behave this way, so we
    # emulate it.

    def _get_softspace(self):
        return self._file.softspace

    def _set_softspace(self, value):
        self._file.softspace = value

    softspace = property(_get_softspace, _set_softspace)


=== Packages/zpkgtools/zpkgtools/app.py 1.31 => 1.32 ===
--- Packages/zpkgtools/zpkgtools/app.py:1.31	Mon Apr 19 13:16:37 2004
+++ Packages/zpkgtools/zpkgtools/app.py	Mon Apr 19 23:37:23 2004
@@ -27,6 +27,7 @@
 from zpkgtools import cvsloader
 from zpkgtools import dependencies
 from zpkgtools import include
+from zpkgtools import loader
 from zpkgtools import locationmap
 from zpkgtools import package
 from zpkgtools import publication
@@ -48,9 +49,9 @@
         self.tmpdir = tempfile.mkdtemp(prefix=options.program + "-")
         tempfile.tempdir = self.tmpdir
         if options.revision_tag:
-            self.loader = cvsloader.CvsLoader(tag=options.revision_tag)
+            self.loader = loader.Loader(tag=options.revision_tag)
         else:
-            self.loader = cvsloader.CvsLoader()
+            self.loader = loader.Loader()
         cf = config.Configuration()
         cf.location_maps.extend(options.location_maps)
         path = options.configfile
@@ -399,7 +400,7 @@
         old_loader = self.loader
         if self.options.revision_tag:
             # we really don't want the tagged version of the support code
-            self.loader = cvsloader.CvsLoader()
+            self.loader = loader.Loader()
         self.include_support_package(
             "zpkgtools", ("cvs://cvs.zope.org/cvs-repository"
                           ":Packages/zpkgtools/zpkgtools"))


=== Packages/zpkgtools/zpkgtools/cvsloader.py 1.14 => 1.15 ===
--- Packages/zpkgtools/zpkgtools/cvsloader.py:1.14	Fri Apr  2 13:56:51 2004
+++ Packages/zpkgtools/zpkgtools/cvsloader.py	Mon Apr 19 23:37:23 2004
@@ -204,99 +204,30 @@
         return url
 
 
-def open(url, mode="r"):
-    if mode[:1] != "r" or "+" in mode:
-        raise ValueError("CVS resources can only be opened in read-only mode")
-    loader = CvsLoader()
-    path = loader.load(url)
-    if os.path.isfile(path):
-        return FileProxy(path, mode, loader, url)
-    # Only files and directories come from CVS, so no need to check
-    # for magical directory entries here:
-    loader.cleanup()
-    raise IOError(errno.EISDIR, "Is a directory", url)
-
-
 class CvsLoader:
 
-    def __init__(self, tag=None):
-        self.tag = tag or None
-        self.workdirs = {}  # URL -> (directory, path)
-
-    def cleanup(self):
-        """Remove all checkouts that are present."""
-        while self.workdirs:
-            url, (directory, path) = self.workdirs.popitem()
-            if directory:
-                shutil.rmtree(directory)
-
-    def load(self, url):
+    def load(self, cvsurl, workdir):
         """Load resource from URL into a temporary location.
 
         Returns the location of the resource once loaded.
         """
-        key = url
-        try:
-            url = parse(url)
-        except ValueError:
-            # XXX Hack to make this support file: URLs to ease
-            # testing with filesystem-based resources.  There
-            # really should be some sort of dispatch mechanism,
-            # but we won't do that right now.
-            parts = urlparse.urlparse(url)
-            if parts[0] == "file" and not parts[1]:
-                fn = urllib.url2pathname(parts[2])
-                if os.path.exists(fn):
-                    return fn
-                raise ValueError(
-                    "file: URL refers to non-existant resource")
-            raise TypeError(
-                "load() requires a cvs or repository URL; received %r"
-                % url)
-        if isinstance(url, RepositoryUrl):
-            raise ValueError("repository: URLs must be joined with the"
-                             " appropriate cvs: base URL")
-        elif isinstance(url, CvsUrl):
-            cvsurl = copy.copy(url)
-            key = cvsurl.getUrl()
-        else:
-            raise TypeError("load() requires a cvs: URL")
-        if not cvsurl.tag:
-            cvsurl.tag = self.tag
-            key = cvsurl.getUrl()
-        # If we've already loaded this, use that copy.  This doesn't
-        # consider fetching something with a different path that's
-        # represent by a previous load():
-        if key in self.workdirs:
-            return self.workdirs[key][1]
 
-        workdir = tempfile.mkdtemp(prefix="cvsloader-")
         cvsroot = cvsurl.getCvsRoot()
         tag = cvsurl.tag or "HEAD"
         path = cvsurl.path or "."
 
         rc = self.runCvsExport(cvsroot, workdir, tag, path)
         if rc:
-            # Some error occurred: we haven't figured out what, and
-            # don't really care; details went to standard error.
-            # Assume there's nothing to be gained from the temporary
-            # directory and toss it.
-            shutil.rmtree(workdir)
             raise CvsLoadingError(cvsurl, rc)
 
         if path == ".":
-            self.workdirs[key] = (workdir, workdir)
             return workdir
         elif self.isFileResource(cvsurl):
             basename = posixpath.basename(path)
-            path = os.path.join(workdir, basename, basename)
-            self.workdirs[key] = (workdir, path)
-            return path
+            return os.path.join(workdir, basename, basename)
         else:
             basename = posixpath.basename(path)
-            path = os.path.join(workdir, basename)
-            self.workdirs[key] = (workdir, path)
-            return path
+            return os.path.join(workdir, basename)
 
     def runCvsExport(self, cvsroot, workdir, tag, path):
         # cvs -f -Q -z6 -d CVSROOT export -kk -d WORKDIR -r TAG PATH
@@ -354,32 +285,3 @@
     def openCvsRLog(self, cvsroot, path):
         return os.popen(
             "cvs -f -q -d '%s' rlog -R -l '%s'" % (cvsroot, path), "r")
-
-
-class FileProxy(object):
-
-    def __init__(self, path, mode, loader, url=None):
-        self.name = url or path
-        self._file = file(path, mode)
-        self._cleanup = loader.cleanup
-
-    def __getattr__(self, name):
-        return getattr(self._file, name)
-
-    def close(self):
-        if not self._file.closed:
-            self._file.close()
-            self._cleanup()
-            self._cleanup = None
-
-    # We shouldn't ever actually need to deal with softspace since
-    # we're read-only, but... real files still behave this way, so we
-    # emulate it.
-
-    def _get_softspace(self):
-        return self._file.softspace
-
-    def _set_softspace(self, value):
-        self._file.softspace = value
-
-    softspace = property(_get_softspace, _set_softspace)


=== Packages/zpkgtools/zpkgtools/locationmap.py 1.8 => 1.9 ===
--- Packages/zpkgtools/zpkgtools/locationmap.py:1.8	Mon Mar 29 11:50:58 2004
+++ Packages/zpkgtools/zpkgtools/locationmap.py	Mon Apr 19 23:37:23 2004
@@ -24,6 +24,7 @@
 import UserDict
 
 from zpkgtools import cvsloader
+from zpkgtools import loader
 
 
 _logger = logging.getLogger(__name__)
@@ -145,7 +146,7 @@
             else:
                 base = path
         else:
-            f = cvsloader.open(path, "rU")
+            f = loader.open(path, "rU")
             cvsurl.path = posixpath.dirname(cvsurl.path)
             base = cvsurl.getUrl()
     try:




More information about the Zope-CVS mailing list