Ok, I've rewritten svn_entryparser to Do The Right Thing for both
types of entries files. Just do this, and magic happens.
fp = open("file")
entryparser = svn_entryparser()
entryparser.parser_file(fp)
The next project is to make it do this if you pass pointers to a
berkely db as well. :-) Patch attached.
Also, could someone please look at some of the code I've written and
let me know if I'm remotely on the right track? Thanks.
Finally, could someone explain what the heck the output of "svn
import" actually represents? I complained about this in
<20010417104031.A20583@uchicago.edu>. I'd like to parse that output
into trees too, so that the entire current regression suite can be
handled by my current tree stuff, but I really don't get the format.
Thanks
Index: svn_entry.py
===================================================================
RCS file: /cvs/subversion/subversion/tests/clients/cmdline/svn_entry.py,v
retrieving revision 1.4
diff -u -r1.4 svn_entry.py
--- svn_entry.py 2001/04/12 18:11:02 1.4
+++ svn_entry.py 2001/04/20 02:51:01
@@ -26,12 +26,13 @@
# kind, revision, ancestor. Other optional keys *might* be
# present, such as prop-time, text-time, add, delete, conflict.
-import xml.parsers.expat # you may need to install this package
+import xml.parsers.expat # you may need to install this package
+import copy # for deepcopy
class svn_entry:
"An object that represents an entry from an 'entries' file."
- def __init__(self, attributes): # constructor
+ def __init__(self, attributes={}): # constructor
self.atts = attributes
def prettyprint(self):
@@ -50,6 +51,23 @@
self.parser = xml.parsers.expat.ParserCreate()
self.parser.StartElementHandler = self.handle_start_tag
+ def is_svn_entries(self, file):
+ "Determine if FILE is a CVS or an SVN entries file."
+
+ # read the first line, and strip off whitespace
+ first_line = file.readline().strip()
+
+ # go back to the beginning, so that parsing will work properly
+ file.seek(0)
+
+ # we assume the the XML declaration is on the first line. Since we
+ # are writing the files, this should be a safe assumption.
+ if first_line.find("xml") != -1:
+ return 1
+ # We assume that the first line is not blank - should be a safe assumption
+ elif (first_line[0] == '/') or (first_line[0] == 'D'):
+ return 0
+
def handle_start_tag(self, name, attrs):
"Expat callback that receives a new open-tag."
@@ -71,14 +89,73 @@
self.entry_dict[attrs['name']] = entry # store the new entry
+ def svn_parse_file(self, file):
+ self.parser.ParseFile(file)
+
+ def cvs_parse_file(self, file):
+ "Parse the CVS 'Entries' file FILE into a dictionary."
+
+ # Create a parent entry to represent the current directory
+ # This directory isn't in the Entries file, and isn't really under
+ # CVS's control, but SVN has an entry for it, and we want to be
+ # compatible
+ parent = svn_entry({})
+ parent.atts['name'] = "" # for consistency with subversion
+ # this is arbitary, since it isn't versioned by CVS
+ parent.atts['revision'] = "1"
+ # FIXME This is wrong. How can we get this info? Do we want to
+ # fix this here, or when we create the tree? Doing it here
+ # requires info not in the Entries file
+ parent.atts['ancestor'] = "anni"
+ parent.atts['kind'] = "dir"
+ self.entry_dict[parent.atts['name']] = parent
+
+ lines = file.readlines()
+ for l in lines:
+ entry = svn_entry()
+ if l[0] == 'D': # Directories begin with D
+ if len(l) == 1:
+ # If a directory contains no subdirectories, the last line
+ # of the entries file is a single 'D'
+ continue
+ else:
+ entry.atts['kind'] = 'dir'
+ l = l[1:]
+ else:
+ entry.atts['kind'] = 'file'
+ props = l.split("/")
+ if l[0] == '\n': # skip empty entries
+ continue
+ entry.atts['name'] = props[1]
+ entry.atts['revision'] = props[2]
+ entry.atts['text-time'] = props[3]
+ entry.atts['ancestor'] = parent.atts['ancestor'] + '/' \
+ + entry.atts['name']
+
+ self.entry_dict[entry.atts['name']] = copy.deepcopy(entry) # store the new entry
+
+ def parse_file(self, file):
+ if self.is_svn_entries(file):
+ self.svn_parse_file(file)
+ else:
+ self.cvs_parse_file(file)
+
+ def prettyprint(self):
+ "Pretty-print the entire set of entries"
+ for i in self.entry_dict.values():
+ i.prettyprint()
+
+
# The main exported routine
def get_entries(path):
- "Parse the entries file at PATH and return a list of svn_entry objects."
+ """Parse the entries file at PATH and return a dictionary of entry
+ objects. This can be passed either a CVS or an SVN entries file,
+ and it will do the right thing."""
- entryparser = svn_entryparser() # make a parser instance
+ entryparser = svn_entryparser()
fp = open(path, 'r')
- entryparser.parser.ParseFile(fp)
+ entryparser.parse_file(fp)
fp.close()
return entryparser.entry_dict
sam th --- sam_at_uchicago.edu --- http://www.abisource.com/~sam/
OpenPGP Key: CABD33FC --- http://samth.dyndns.org/key
DeCSS: http://samth.dyndns.org/decss
- application/pgp-signature attachment: stored
Received on Sat Oct 21 14:36:29 2006