hgext/convert/monotone.py
changeset 6307 6840668e3bf6
parent 6306 2f9de4aaea9e
child 6332 950e72fc7cf3
--- a/hgext/convert/monotone.py	Sat Feb 02 19:14:59 2008 +0100
+++ b/hgext/convert/monotone.py	Sun Feb 03 16:14:05 2008 +0100
@@ -1,131 +1,107 @@
 # monotone support for the convert extension
 
-import os
-import re
-import time
+import os, re, time
 from mercurial import util
+from common import NoRepo, commit, converter_source, checktool, commandline
+from mercurial.i18n import _
 
-from common import NoRepo, commit, converter_source, checktool
-
-class monotone_source(converter_source):
+class monotone_source(converter_source, commandline):
     def __init__(self, ui, path=None, rev=None):
         converter_source.__init__(self, ui, path, rev)
-        
+        commandline.__init__(self, ui, 'mtn')
+
         self.ui = ui
         self.path = path
 
-         
         # regular expressions for parsing monotone output
-        
         space    = r'\s*'
         name     = r'\s+"((?:[^"]|\\")*)"\s*'
         value    = name
         revision = r'\s+\[(\w+)\]\s*'
         lines    = r'(?:.|\n)+'
-        
-        self.dir_re      = re.compile(space + "dir"      + name)
-        self.file_re     = re.compile(space + "file"     + name + "content" + revision)
+
+        self.dir_re      = re.compile(space + "dir" + name)
+        self.file_re     = re.compile(space + "file" + name + "content" + revision)
         self.add_file_re = re.compile(space + "add_file" + name + "content" + revision)
-        self.patch_re    = re.compile(space + "patch"    + name + "from" + revision + "to" + revision)
-        self.rename_re   = re.compile(space + "rename"   + name + "to" + name)
-        self.tag_re      = re.compile(space + "tag"      + name + "revision" + revision)
+        self.patch_re    = re.compile(space + "patch" + name + "from" + revision + "to" + revision)
+        self.rename_re   = re.compile(space + "rename" + name + "to" + name)
+        self.tag_re      = re.compile(space + "tag" + name + "revision" + revision)
         self.cert_re     = re.compile(lines + space + "name" + name + "value" + value)
 
         attr = space + "file" + lines + space + "attr" + space
         self.attr_execute_re = re.compile(attr  + '"mtn:execute"' + space + '"true"')
 
         # cached data
-        
         self.manifest_rev = None
         self.manifest = None
-        self.files = None   
-        self.dirs  = None     
-        
-        norepo = NoRepo("%s does not look like a monotone repo" % path)
+        self.files = None
+        self.dirs  = None
+
+        norepo = NoRepo (_("%s does not look like a monotone repo") % path)
         if not os.path.exists(path):
             raise norepo
-        
+
         checktool('mtn')
-        
-        # test if there are are any revisions
+
+        # test if there are any revisions
         self.rev = None
-        try :
+        try:
             self.getheads()
-        except :
-            raise norepo        
-
+        except:
+            raise norepo
         self.rev = rev
 
-    
-    def mtncmd(self, arg):
-        cmdline = "mtn -d %s automate %s" % (util.shellquote(self.path), arg)
-        self.ui.debug(cmdline, '\n')
-        p = util.popen(cmdline)
-        result = p.read()
-        if p.close():
-            raise IOError()
-        return result
-    
+    def mtnrun(self, *args, **kwargs):
+        kwargs['d'] = self.path
+        return self.run0('automate', *args, **kwargs)
+
     def mtnloadmanifest(self, rev):
         if self.manifest_rev == rev:
             return
+        self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
         self.manifest_rev = rev
-        self.manifest = self.mtncmd("get_manifest_of %s" % rev).split("\n\n")
-        
-        manifest = self.manifest
-        files = {}
-        dirs = {}
+        self.files = {}
+        self.dirs = {}
 
-        for e in manifest:
+        for e in self.manifest:
             m = self.file_re.match(e)
-            if m:                
+            if m:
                 attr = ""
                 name = m.group(1)
                 node = m.group(2)
                 if self.attr_execute_re.match(e):
                     attr += "x"
-                files[name] = (node, attr)
+                self.files[name] = (node, attr)
             m = self.dir_re.match(e)
             if m:
-                dirs[m.group(1)] = True
-        
-        self.files = files
-        self.dirs = dirs
+                self.dirs[m.group(1)] = True
 
     def mtnisfile(self, name, rev):
         # a non-file could be a directory or a deleted or renamed file
         self.mtnloadmanifest(rev)
-        try :
+        try:
             self.files[name]
             return True
         except KeyError:
             return False
-            
+
     def mtnisdir(self, name, rev):
         self.mtnloadmanifest(rev)
-        try :
+        try:
             self.dirs[name]
             return True
         except KeyError:
             return False
-    
+
     def mtngetcerts(self, rev):
         certs = {"author":"<missing>", "date":"<missing>",
             "changelog":"<missing>", "branch":"<missing>"}
-        cert_list = self.mtncmd("certs %s" % rev).split("\n\n")
+        cert_list = self.mtnrun("certs", rev).split("\n\n")
         for e in cert_list:
             m = self.cert_re.match(e)
             if m:
                 certs[m.group(1)] = m.group(2)
         return certs
-        
-    def mtngetparents(self, rev):
-        parents = self.mtncmd("parents %s" % rev).strip("\n").split("\n")
-        p = []
-        for x in parents:
-            if len(x) >= 40: # blank revs have been seen otherwise
-                p.append(x)
-        return p
 
     def mtnrenamefiles(self, files, fromdir, todir):
         renamed = {}
@@ -135,17 +111,18 @@
                 renamed[tofile] = (fromdir + suffix).lstrip("/")
         return renamed
 
-    
+
     # implement the converter_source interface:
-    
+
     def getheads(self):
-        if not self.rev or self.rev == "":
-            return self.mtncmd("leaves").splitlines()
+        if not self.rev:
+            return self.mtnrun("leaves").splitlines()
         else:
             return [self.rev]
 
     def getchanges(self, rev):
-        revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
+        #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
+        revision = self.mtnrun("get_revision", rev).split("\n\n")
         files = {}
         copies = {}
         for e in revision:
@@ -170,39 +147,41 @@
                 if self.mtnisdir(toname, rev):
                     renamed = self.mtnrenamefiles(self.files, fromname, toname)
                     for tofile, fromfile in renamed.items():
-                        self.ui.debug (("copying file in renamed dir from '%s' to '%s'" % (fromfile, tofile)), "\n")
+                        self.ui.debug (_("copying file in renamed dir from '%s' to '%s'") % (fromfile, tofile), '\n')
                         files[tofile] = rev
                     for fromfile in renamed.values():
                         files[fromfile] = rev
+        return (files.items(), copies)
 
-        return (files.items(), copies)
-        
     def getmode(self, name, rev):
         self.mtnloadmanifest(rev)
-        try :
+        try:
             node, attr = self.files[name]
             return attr
         except KeyError:
             return ""
-        
+
     def getfile(self, name, rev):
         if not self.mtnisfile(name, rev):
             raise IOError() # file was deleted or renamed
-        return self.mtncmd("get_file_of %s -r %s" % (util.shellquote(name), rev))
-    
-    def getcommit(self, rev):        
+        try:
+            return self.mtnrun("get_file_of", name, r=rev)
+        except:
+            raise IOError() # file was deleted or renamed
+
+    def getcommit(self, rev):
         certs   = self.mtngetcerts(rev)
         return commit(
             author=certs["author"],
             date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
             desc=certs["changelog"],
             rev=rev,
-            parents=self.mtngetparents(rev),
+            parents=self.mtnrun("parents", rev).splitlines(),
             branch=certs["branch"])
 
     def gettags(self):
         tags = {}
-        for e in self.mtncmd("tags").split("\n\n"):
+        for e in self.mtnrun("tags").split("\n\n"):
             m = self.tag_re.match(e)
             if m:
                 tags[m.group(1)] = m.group(2)