hgext/convert/monotone.py
changeset 13760 ed97955e0c04
parent 11134 33010ff1fd6f
child 13761 aeb41f0048e7
equal deleted inserted replaced
13759:49b818fd26d8 13760:ed97955e0c04
    17         converter_source.__init__(self, ui, path, rev)
    17         converter_source.__init__(self, ui, path, rev)
    18         commandline.__init__(self, ui, 'mtn')
    18         commandline.__init__(self, ui, 'mtn')
    19 
    19 
    20         self.ui = ui
    20         self.ui = ui
    21         self.path = path
    21         self.path = path
       
    22         self.automatestdio = False
    22 
    23 
    23         norepo = NoRepo(_("%s does not look like a monotone repository")
    24         norepo = NoRepo(_("%s does not look like a monotone repository")
    24                         % path)
    25                         % path)
    25         if not os.path.exists(os.path.join(path, '_MTN')):
    26         if not os.path.exists(os.path.join(path, '_MTN')):
    26             # Could be a monotone repository (SQLite db file)
    27             # Could be a monotone repository (SQLite db file)
    71         except:
    72         except:
    72             raise norepo
    73             raise norepo
    73         self.rev = rev
    74         self.rev = rev
    74 
    75 
    75     def mtnrun(self, *args, **kwargs):
    76     def mtnrun(self, *args, **kwargs):
       
    77         if self.automatestdio:
       
    78             return self.mtnrunstdio(*args, **kwargs)
       
    79         else:
       
    80             return self.mtnrunsingle(*args, **kwargs)
       
    81 
       
    82     def mtnrunsingle(self, *args, **kwargs):
    76         kwargs['d'] = self.path
    83         kwargs['d'] = self.path
    77         return self.run0('automate', *args, **kwargs)
    84         return self.run0('automate', *args, **kwargs)
       
    85 
       
    86     def mtnrunstdio(self, *args, **kwargs):
       
    87         # Prepare the command in automate stdio format
       
    88         command = []
       
    89         for k, v in kwargs.iteritems():
       
    90             command.append("%s:%s" % (len(k), k))
       
    91             if v:
       
    92                 command.append("%s:%s" % (len(v), v))
       
    93         if command:
       
    94             command.insert(0, 'o')
       
    95             command.append('e')
       
    96 
       
    97         command.append('l')
       
    98         for arg in args:
       
    99             command += "%s:%s" % (len(arg), arg)
       
   100         command.append('e')
       
   101         command = ''.join(command)
       
   102 
       
   103         self.ui.debug("mtn: sending '%s'\n" % command)
       
   104         self.mtnwritefp.write(command)
       
   105         self.mtnwritefp.flush()
       
   106 
       
   107         return self.mtnstdioreadcommandoutput(command)
       
   108 
       
   109     def mtnstdioreadpacket(self):
       
   110         read = None
       
   111         commandnbr = ''
       
   112         while read != ':':
       
   113             read = self.mtnreadfp.read(1)
       
   114             if not read:
       
   115                 raise util.Abort(_('bad mtn packet - no end of commandnbr'))
       
   116             commandnbr += read
       
   117         commandnbr = commandnbr[:-1]
       
   118 
       
   119         stream = self.mtnreadfp.read(1)
       
   120         if stream not in 'mewptl':
       
   121             raise util.Abort(_('bad mtn packet - bad stream type %s' % stream))
       
   122 
       
   123         read = self.mtnreadfp.read(1)
       
   124         if read != ':':
       
   125             raise util.Abort(_('bad mtn packet - no divider before size'))
       
   126 
       
   127         read = None
       
   128         lengthstr = ''
       
   129         while read != ':':
       
   130             read = self.mtnreadfp.read(1)
       
   131             if not read:
       
   132                 raise util.Abort(_('bad mtn packet - no end of packet size'))
       
   133             lengthstr += read
       
   134         try:
       
   135             length = long(lengthstr[:-1])
       
   136         except TypeError:
       
   137             raise util.Abort(_('bad mtn packet - bad packet size %s')
       
   138                 % lengthstr)
       
   139 
       
   140         read = self.mtnreadfp.read(length)
       
   141         if len(read) != length:
       
   142             raise util.Abort(_("bad mtn packet - unable to read full packet "
       
   143                 "read %s of %s") % (len(read), length))
       
   144 
       
   145         return (commandnbr, stream, length, read)
       
   146 
       
   147     def mtnstdioreadcommandoutput(self, command):
       
   148         retval = ''
       
   149         while True:
       
   150             commandnbr, stream, length, output = self.mtnstdioreadpacket()
       
   151             self.ui.debug('mtn: read packet %s:%s:%s\n' %
       
   152                 (commandnbr, stream, length))
       
   153 
       
   154             if stream == 'l':
       
   155                 # End of command
       
   156                 if output != '0':
       
   157                     raise util.Abort(_("mtn command '%s' returned %s") %
       
   158                         (command, output))
       
   159                 break
       
   160             elif stream in 'ew':
       
   161                 # Error, warning output
       
   162                 self.ui.warn(_('%s error:\n') % self.command)
       
   163                 self.ui.warn(output)
       
   164             elif stream == 'p':
       
   165                 # Progress messages
       
   166                 self.ui.debug('mtn: ' + output)
       
   167             elif stream == 'm':
       
   168                 # Main stream - command output
       
   169                 retval = output
       
   170 
       
   171         return retval
    78 
   172 
    79     def mtnloadmanifest(self, rev):
   173     def mtnloadmanifest(self, rev):
    80         if self.manifest_rev == rev:
   174         if self.manifest_rev == rev:
    81             return
   175             return
    82         self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
   176         self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
   223 
   317 
   224     def getchangedfiles(self, rev, i):
   318     def getchangedfiles(self, rev, i):
   225         # This function is only needed to support --filemap
   319         # This function is only needed to support --filemap
   226         # ... and we don't support that
   320         # ... and we don't support that
   227         raise NotImplementedError()
   321         raise NotImplementedError()
       
   322 
       
   323     def before(self):
       
   324         # Check if we have a new enough version to use automate stdio
       
   325         version = 0.0
       
   326         try:
       
   327             versionstr = self.mtnrunsingle("interface_version")
       
   328             version = float(versionstr)
       
   329         except Exception:
       
   330             raise util.Abort(_("unable to determine mtn automate interface "
       
   331                 "version"))
       
   332 
       
   333         if version >= 12.0:
       
   334             self.automatestdio = True
       
   335             self.ui.debug("mtn automate version %s - using automate stdio\n" %
       
   336                 version)
       
   337 
       
   338             # launch the long-running automate stdio process
       
   339             self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio',
       
   340                 '-d', self.path)
       
   341             # read the headers
       
   342             read = self.mtnreadfp.readline()
       
   343             if read != 'format-version: 2\n':
       
   344                 raise util.Abort(_('mtn automate stdio header unexpected: %s')
       
   345                     % read)
       
   346             while read != '\n':
       
   347                 read = self.mtnreadfp.readline()
       
   348                 if not read:
       
   349                     raise util.Abort(_("failed to reach end of mtn automate "
       
   350                         "stdio headers"))
       
   351         else:
       
   352             self.ui.debug("mtn automate version %s - not using automate stdio "
       
   353                 "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version)
       
   354 
       
   355     def after(self):
       
   356         if self.automatestdio:
       
   357             self.mtnwritefp.close()
       
   358             self.mtnwritefp = None
       
   359             self.mtnreadfp.close()
       
   360             self.mtnreadfp = None
       
   361