comparison src/plugins/plugin_merge_req_mercurial.py @ 2544:a64887289931

plugin merge-requests, mercurial merge-requests: merge request import implementation
author Goffi <goffi@goffi.org>
date Fri, 30 Mar 2018 17:53:11 +0200
parents 0046283a285d
children 1362cabad225
comparison
equal deleted inserted replaced
2543:60758de1c227 2544:a64887289931
42 42
43 class MercurialProtocol(protocol.ProcessProtocol): 43 class MercurialProtocol(protocol.ProcessProtocol):
44 """handle hg commands""" 44 """handle hg commands"""
45 hg = None 45 hg = None
46 46
47 def __init__(self, deferred): 47 def __init__(self, deferred, stdin=None):
48 """
49 @param deferred(defer.Deferred): will be called when command is completed
50 @param stdin(str, None): if not None, will be push to standard input
51 """
52 self._stdin = stdin
48 self._deferred = deferred 53 self._deferred = deferred
49 self.data = [] 54 self.data = []
55
56 def connectionMade(self):
57 if self._stdin is not None:
58 self.transport.write(self._stdin)
59 self.transport.closeStdin()
50 60
51 def outReceived(self, data): 61 def outReceived(self, data):
52 self.data.append(data) 62 self.data.append(data)
53 63
54 def errReceived(self, data): 64 def errReceived(self, data):
58 data = u''.join([d.decode('utf-8') for d in self.data]) 68 data = u''.join([d.decode('utf-8') for d in self.data])
59 if (reason.value.exitCode == 0): 69 if (reason.value.exitCode == 0):
60 log.debug(_('Mercurial command succeed')) 70 log.debug(_('Mercurial command succeed'))
61 self._deferred.callback(data) 71 self._deferred.callback(data)
62 else: 72 else:
63 log.error(_(u"Can't complete Mercurial command (error code: {code}): {message}").format( 73 msg = _(u"Can't complete Mercurial command (error code: {code}): {message}").format(
64 code = reason.value.exitCode, 74 code = reason.value.exitCode,
65 message = data)) 75 message = data)
66 self._deferred.errback(Failure(RuntimeError)) 76 log.warning(msg)
77 self._deferred.errback(Failure(RuntimeError(msg)))
67 78
68 @classmethod 79 @classmethod
69 def run(cls, path, command, *args): 80 def run(cls, path, command, *args, **kwargs):
70 """Create a new MercurialRegisterProtocol and execute the given mercurialctl command. 81 """Create a new MercurialRegisterProtocol and execute the given mercurialctl command.
71 82
72 @param path(unicode): path to the repository 83 @param path(unicode): path to the repository
73 @param command(unicode): command to run 84 @param command(unicode): command to run
74 @param *args(unicode): command arguments 85 @param *args(unicode): command arguments
86 @param **kwargs: used because Python2 doesn't handle normal kw args after *args
87 can only be:
88 - stdin(unicode, None): data to push to standard input
75 @return ((D)): 89 @return ((D)):
76 """ 90 """
91 stdin = kwargs.pop('stdin', None)
92 if kwargs:
93 raise exceptions.InternalError(u'only stdin is allowed as keyword argument')
94 if stdin is not None:
95 stdin = stdin.encode('utf-8')
77 d = defer.Deferred() 96 d = defer.Deferred()
78 mercurial_prot = MercurialProtocol(d) 97 mercurial_prot = MercurialProtocol(d, stdin=stdin)
79 cmd_args = [cls.hg, command.encode('utf-8')] 98 cmd_args = [cls.hg, command.encode('utf-8')]
80 cmd_args.extend([a.encode('utf-8') for a in args]) 99 cmd_args.extend([a.encode('utf-8') for a in args])
81 reactor.spawnProcess(mercurial_prot, 100 reactor.spawnProcess(mercurial_prot,
82 cls.hg, 101 cls.hg,
83 cmd_args, 102 cmd_args,
84 path=path.encode('utf-8')) 103 path=path.encode('utf-8'))
85 return d 104 return d
86 105
87 106
88 class MercurialHandler(object): 107 class MercurialHandler(object):
108 data_types = (u'mercurial_changeset',)
89 109
90 def __init__(self, host): 110 def __init__(self, host):
91 log.info(_(u"Mercurial merge request handler initialization")) 111 log.info(_(u"Mercurial merge request handler initialization"))
92 try: 112 try:
93 MercurialProtocol.hg = which('hg')[0] 113 MercurialProtocol.hg = which('hg')[0]
94 except IndexError: 114 except IndexError:
95 raise exceptions.NotFound(_(u"Mercurial executable (hg) not found, can't use Mercurial handler")) 115 raise exceptions.NotFound(_(u"Mercurial executable (hg) not found, can't use Mercurial handler"))
96 self.host = host 116 self.host = host
97 self._m = host.plugins['MERGE_REQUESTS'] 117 self._m = host.plugins['MERGE_REQUESTS']
98 self._m.register('mercurial', self, [u'mercurial_changeset'], SHORT_DESC) 118 self._m.register('mercurial', self, self.data_types, SHORT_DESC)
99 119
100 def check(self, repository): 120 def check(self, repository):
101 d = MercurialProtocol.run(repository, 'identify') 121 d = MercurialProtocol.run(repository, 'identify')
102 d.addCallback(lambda dummy: True) 122 d.addCallback(lambda dummy: True)
103 d.addErrback(lambda dummy: False) 123 d.addErrback(lambda dummy: False)
104 return d 124 return d
105 125
106 def export(self, repository): 126 def export(self, repository):
107 return MercurialProtocol.run(repository, 'export', '-g', '-r', 'outgoing()', '--encoding=utf-8') 127 return MercurialProtocol.run(repository, 'export', '-g', '-r', 'outgoing()', '--encoding=utf-8')
128
129 def import_(self, repository, data, data_type, item_id, service, node, extra):
130 parsed_data = self.parse(data)
131 try:
132 parsed_name = parsed_data[0][u'commit_msg'].split(u'\n')[0]
133 parsed_name = parsed_name.replace(u' ', u'_')[:20]
134 except Exception:
135 parsed_name = u''
136 name = u'mr_{item_id}_{parsed_name}'.format(item_id=item_id, parsed_name=parsed_name)
137 return MercurialProtocol.run(repository, 'qimport', '-g', '--name', name, '--encoding=utf-8', '-', stdin=data)
108 138
109 def parse(self, data, data_type=None): 139 def parse(self, data, data_type=None):
110 lines = data.splitlines() 140 lines = data.splitlines()
111 total_lines = len(lines) 141 total_lines = len(lines)
112 patches = [] 142 patches = []