plugin merge-requests, mercurial merge-requests: merge request import implementation
This commit is contained in:
parent
2422d0a1d7
commit
60043be6b4
2 changed files with 76 additions and 7 deletions
|
|
@ -44,10 +44,20 @@ class MercurialProtocol(protocol.ProcessProtocol):
|
|||
"""handle hg commands"""
|
||||
hg = None
|
||||
|
||||
def __init__(self, deferred):
|
||||
def __init__(self, deferred, stdin=None):
|
||||
"""
|
||||
@param deferred(defer.Deferred): will be called when command is completed
|
||||
@param stdin(str, None): if not None, will be push to standard input
|
||||
"""
|
||||
self._stdin = stdin
|
||||
self._deferred = deferred
|
||||
self.data = []
|
||||
|
||||
def connectionMade(self):
|
||||
if self._stdin is not None:
|
||||
self.transport.write(self._stdin)
|
||||
self.transport.closeStdin()
|
||||
|
||||
def outReceived(self, data):
|
||||
self.data.append(data)
|
||||
|
||||
|
|
@ -60,22 +70,31 @@ class MercurialProtocol(protocol.ProcessProtocol):
|
|||
log.debug(_('Mercurial command succeed'))
|
||||
self._deferred.callback(data)
|
||||
else:
|
||||
log.error(_(u"Can't complete Mercurial command (error code: {code}): {message}").format(
|
||||
msg = _(u"Can't complete Mercurial command (error code: {code}): {message}").format(
|
||||
code = reason.value.exitCode,
|
||||
message = data))
|
||||
self._deferred.errback(Failure(RuntimeError))
|
||||
message = data)
|
||||
log.warning(msg)
|
||||
self._deferred.errback(Failure(RuntimeError(msg)))
|
||||
|
||||
@classmethod
|
||||
def run(cls, path, command, *args):
|
||||
def run(cls, path, command, *args, **kwargs):
|
||||
"""Create a new MercurialRegisterProtocol and execute the given mercurialctl command.
|
||||
|
||||
@param path(unicode): path to the repository
|
||||
@param command(unicode): command to run
|
||||
@param *args(unicode): command arguments
|
||||
@param **kwargs: used because Python2 doesn't handle normal kw args after *args
|
||||
can only be:
|
||||
- stdin(unicode, None): data to push to standard input
|
||||
@return ((D)):
|
||||
"""
|
||||
stdin = kwargs.pop('stdin', None)
|
||||
if kwargs:
|
||||
raise exceptions.InternalError(u'only stdin is allowed as keyword argument')
|
||||
if stdin is not None:
|
||||
stdin = stdin.encode('utf-8')
|
||||
d = defer.Deferred()
|
||||
mercurial_prot = MercurialProtocol(d)
|
||||
mercurial_prot = MercurialProtocol(d, stdin=stdin)
|
||||
cmd_args = [cls.hg, command.encode('utf-8')]
|
||||
cmd_args.extend([a.encode('utf-8') for a in args])
|
||||
reactor.spawnProcess(mercurial_prot,
|
||||
|
|
@ -86,6 +105,7 @@ class MercurialProtocol(protocol.ProcessProtocol):
|
|||
|
||||
|
||||
class MercurialHandler(object):
|
||||
data_types = (u'mercurial_changeset',)
|
||||
|
||||
def __init__(self, host):
|
||||
log.info(_(u"Mercurial merge request handler initialization"))
|
||||
|
|
@ -95,7 +115,7 @@ class MercurialHandler(object):
|
|||
raise exceptions.NotFound(_(u"Mercurial executable (hg) not found, can't use Mercurial handler"))
|
||||
self.host = host
|
||||
self._m = host.plugins['MERGE_REQUESTS']
|
||||
self._m.register('mercurial', self, [u'mercurial_changeset'], SHORT_DESC)
|
||||
self._m.register('mercurial', self, self.data_types, SHORT_DESC)
|
||||
|
||||
def check(self, repository):
|
||||
d = MercurialProtocol.run(repository, 'identify')
|
||||
|
|
@ -106,6 +126,16 @@ class MercurialHandler(object):
|
|||
def export(self, repository):
|
||||
return MercurialProtocol.run(repository, 'export', '-g', '-r', 'outgoing()', '--encoding=utf-8')
|
||||
|
||||
def import_(self, repository, data, data_type, item_id, service, node, extra):
|
||||
parsed_data = self.parse(data)
|
||||
try:
|
||||
parsed_name = parsed_data[0][u'commit_msg'].split(u'\n')[0]
|
||||
parsed_name = parsed_name.replace(u' ', u'_')[:20]
|
||||
except Exception:
|
||||
parsed_name = u''
|
||||
name = u'mr_{item_id}_{parsed_name}'.format(item_id=item_id, parsed_name=parsed_name)
|
||||
return MercurialProtocol.run(repository, 'qimport', '-g', '--name', name, '--encoding=utf-8', '-', stdin=data)
|
||||
|
||||
def parse(self, data, data_type=None):
|
||||
lines = data.splitlines()
|
||||
total_lines = len(lines)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from sat.core.i18n import _
|
|||
from sat.core.constants import Const as C
|
||||
from sat.core import exceptions
|
||||
from twisted.internet import defer
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from collections import namedtuple
|
||||
from sat.tools import utils
|
||||
from sat.core.log import getLogger
|
||||
|
|
@ -89,6 +90,11 @@ class MergeRequests(object):
|
|||
in_sign='ss', out_sign='aa{ss}',
|
||||
method=self._parseData,
|
||||
async=True)
|
||||
host.bridge.addMethod("mergeRequestsImport", ".plugin",
|
||||
in_sign='ssssa{ss}s', out_sign='',
|
||||
method=self._import,
|
||||
async=True
|
||||
)
|
||||
|
||||
def register(self, name, handler, data_types, short_desc, priority=0):
|
||||
"""register an merge request handler
|
||||
|
|
@ -251,3 +257,36 @@ class MergeRequests(object):
|
|||
except KeyError:
|
||||
raise exceptions.NotFound(_(u'No handler can handle data type "{type}"').format(type=data_type))
|
||||
return defer.maybeDeferred(handler.handler.parse, data, data_type)
|
||||
|
||||
def _import(self, repository, item_id, service=None, node=None, extra=None, profile_key=C.PROF_KEY_NONE):
|
||||
client = self.host.getClient(profile_key)
|
||||
service = jid.JID(service) if service else None
|
||||
d = self.import_request(client, repository, item_id, service, node or None, extra=extra or None)
|
||||
return d
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def import_request(self, client, repository, item, service=None, node=None, extra=None):
|
||||
"""Import a merge request in specified directory
|
||||
|
||||
@param repository(unicode): path to the repository where the code stands
|
||||
"""
|
||||
if not node:
|
||||
node = NS_MERGE_REQUESTS
|
||||
tickets_xmlui, metadata = yield self._s.getDataFormItems(
|
||||
client,
|
||||
service,
|
||||
node,
|
||||
max_items=1,
|
||||
item_ids=[item],
|
||||
form_ns=NS_MERGE_REQUESTS)
|
||||
ticket_xmlui = tickets_xmlui[0]
|
||||
data = ticket_xmlui.named_widgets[FIELD_DATA].value
|
||||
data_type = ticket_xmlui.named_widgets[FIELD_DATA_TYPE].value
|
||||
try:
|
||||
handler = self._type_handlers[data_type]
|
||||
except KeyError:
|
||||
raise exceptions.NotFound(_(u'No handler found to import {data_type}').format(data_type=data_type))
|
||||
log.info(_(u"Importing patch [{item_id}] using {name} handler").format(
|
||||
item_id = item,
|
||||
name = handler.name))
|
||||
yield handler.handler.import_(repository, data, data_type, item, service, node, extra)
|
||||
|
|
|
|||
Loading…
Reference in a new issue