[Zope-CVS] CVS: Packages/zpkgtools/zpkgtools - svnloader.py:1.11

Fred L. Drake, Jr. fred at zope.com
Fri May 7 15:34:00 EDT 2004


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

Modified Files:
	svnloader.py 
Log Message:


- new function: fromPath(); return a parsed URL object for working
  files from Subversion


=== Packages/zpkgtools/zpkgtools/svnloader.py 1.10 => 1.11 ===
--- Packages/zpkgtools/zpkgtools/svnloader.py:1.10	Fri May  7 01:08:17 2004
+++ Packages/zpkgtools/zpkgtools/svnloader.py	Fri May  7 15:33:29 2004
@@ -22,6 +22,8 @@
 import sys
 import urllib
 import urlparse
+import xml.sax
+import xml.sax.handler
 
 from zpkgtools import LoadingError
 from zpkgtools import runlog
@@ -110,7 +112,7 @@
     """
     def __init__(self, prefix, tail, tag=None):
         self.prefix = prefix
-        self.tail = tail
+        self.tail = tail or ""
         self.tag = tag or None
 
     def getUrl(self):
@@ -185,6 +187,82 @@
         return TaglessSubversionUrl(url)
     else:
         return SubversionUrl(*parts)
+
+
+def fromPath(path):
+    """Return a parsed Subversion URL from a path.
+
+    :param path: Path to a file or directory.
+
+    """
+    path = os.path.realpath(path)
+    if os.path.isdir(path):
+        dirname = path
+        basename = ""
+    elif os.path.isfile(path):
+        dirname, basename = os.path.split(path)
+    else:
+        # doesn't exist, or at least isn't a normal directory or file
+        return None
+    svndir = os.path.join(dirname, ".svn")
+    entriesfile = os.path.join(svndir, "entries")
+    try:
+        f = open(entriesfile, "rb")
+    except IOError:
+        # not under Subversion control
+        return None
+    h = EntriesHandler()
+    p = xml.sax.make_parser()
+    p.setFeature(xml.sax.handler.feature_namespaces, True)
+    p.setContentHandler(h)
+    s = xml.sax.xmlreader.InputSource(
+        "file://" + urllib.pathname2url(entriesfile))
+    s.setByteStream(f)
+    p.parse(s)
+    if basename in h.entries:
+        return parse(h.entries[basename])
+    else:
+        return None
+
+
+class EntriesHandler(xml.sax.ContentHandler):
+    """SAX ContentHandler used to extract Subversion URLs from a checkout."""
+
+    SVN_ENTRY = ("svn:", "entry")
+
+    KIND_ATTR = (None, "kind")
+    NAME_ATTR = (None, "name")
+    URL_ATTR = (None, "url")
+
+    def startDocument(self):
+        self.entries = {}
+
+    def startElementNS(self, name, qname, attrs):
+        if name == self.SVN_ENTRY:
+            fn = attrs.getValue(self.NAME_ATTR)
+            names = attrs.getNames()
+            if self.URL_ATTR in names:
+                url = attrs.getValue(self.URL_ATTR)
+            else:
+                url = None
+            if (self.KIND_ATTR in names
+                and attrs.getValue(self.KIND_ATTR) == "dir"
+                and fn):
+                fn = posixpath.join(fn, "")
+            self.entries[fn] = url
+
+    def endDocument(self):
+        base = self.entries.get("")
+        if base is None:
+            # no entry for the directory itself!
+            raise ValueError("missing URL for containing directory!")
+        # make sure the entry for the directory ends in a trailing
+        # slash so the search for the tagging convention succeeds
+        # wherever possible
+        self.entries[""] = posixpath.join(base, "")
+        for fn, url in self.entries.items():
+            if not url:
+                self.entries[fn] = posixpath.join(base, fn)
 
 
 def split_on_tag(url):




More information about the Zope-CVS mailing list