gerrit via email

Bjoern Michaelsen bjoern.michaelsen at canonical.com
Thu Jul 19 05:25:23 PDT 2012


Hi Terrence,

On Thu, Jul 19, 2012 at 07:51:58AM -0400, Terrence Enger wrote:
> Despite checking the open patches on gerrit occasionally thereafter, I
> never caught it showing my patch.  Lionel Elie Mamane has already
> applied the patch, but he may have worked from my email rather than
> gerrit.

My mail about the maildrop was a statement of intent, not that we have a full
solution in place already. There is scripting by David and me for the maildrop,
but it still needs tweaking and testing. Once we have that, we can easily
forward your mail from the list to gerrit.

> So, I wonder ...
> 
> (*) Is it the case that the patch went through gerrit as intended, and
>     I just failed to notice?

no, it went directly in.

> (*) Should I have put the patch in the body of the email rather than
>     an attachment?  Bjoern Michaelsen's instructions in
>     <http://lists.freedesktop.org/archives/libreoffice/2012-July/034689.html>
>     do not specify.

Making the patch an attachment should be fine, 'git am' will find it.

> (*) Did I do something else wrong?

no ;)

> (*) Is my situation common enough to be worth mentioning in
>     <https://wiki.documentfoundation.org/Development#Sending_patches_directly_to_gerrit.libreoffice.org>.
>     (I do not want to make that change myself until I have had success
>     at least once.)

Well, I wonder what you would want to write in that section as it is about
using Gerrit directly (for which you need OpenID). Once the maildrop is in
place we will likely have a section about sending your patch to
gerrit at libreoffice.org instead of sending it to the mailing list.

And before anyone gets out the forks and torches: gerrit sends a notification
about the new change to the dev list (and with the bot to IRC) and with kendy
latest tweaks that also includes the patch itself, so the dev list will get
notified with the full patch still.

Anyway: One step after the other: If you are interested in getting the maildrop
faster, David likely will appreciate your help!

Best,

Bjoern

P.S.: Attaching my unfinished script just to tease you.
-------------- next part --------------
#!/usr/bin/env python

import sys
import email
import os.path
import smtplib
import tempfile
import subprocess
import logging
import minilog


sourceurl = '/home/gerritbot/syncrepos/core.git'
desturl = '/tmp/test/core.git'
legalbranches = [ 'master', 'libreoffice-3-6', 'libreoffice-3-5', 'libreoffice-3-5-6' ]

logfile=os.path.join(os.environ['HOME'], 'patchpickup.log')
loglevel='INFO'

class PatchPusher():
    def __init__(self, branch, logger):
        self.tmpdir = tempfile.mkdtemp()
        self.workrepo = os.path.join(self.tmpdir, 'repo')
        self.repo = repo
        self.branch = branch
        self.logger = logger

    def clone_base(self, sourceurl):
        minilog.logged_call( \
            ['git', 'clone', '--branch', self.branch, sourceurl, self.workrepo], \
             self.logger, \
            {})
        
    def fetch_all(self):
        minilog.logged_call( \
            ['git','--work-tree=%s' % self.workrepo, 'fetch', '--all'], \
            self.logger, \
            {})

    def cherry_pick(self, commit):
        minilog.logged_call( \
            ['git','--work-tree=%s' % self.workrepo, 'cherry-pick', '--all'], \
            self.logger, \
            {})
        
    def apply_message(self, message):
        messagefile = open(os.path.join(self.tmpdir,'message'))
        messagefile.write(str(message))
        messagefile.close()
        minilog.logged_call( \
            ['git','--work-tree=%s' % self.workrepo, 'am', messagefile], \
            self.logger, \
            {})

    def upload_change(self, desturl):
        minilog.logged_call( \
            ['git','--work-tree=%s' % self.workrepo, 'push', desturl, 'HEAD:refs/for/%s' % self.branch], \
            self.logger, \
            {})

class EmailCommand():
    def __init__(self, message, sourceurl, desturl, logger):
        self.message = message
        self.sourceurl = sourceurl
        self.desturl = desturl
        self.logger = logger
        self.command = None
        self.branch = master
        self.commit = None
        self.success = False
        if not message.has_key('subject'):
            raise Exception('message has no subject header -- ignoring.')
        subject = message['subject']
        self.parse_params(subject)
        self.parse_command(subject)

    def parse_params(self, subject):
        state = None
        words = subject.split(' ')
        for word in words:
            if state == 'branch':
                self.branch = word
                state = None
            if state == 'commit':
                self.commit = word
                state == None
            elif state is None and word == 'branch':
                state == 'branch'
            if state is None annd word == 'commit':
                state == 'commit'
        if self.commit is None and len(words) > 1:
            self.commit = words[1]
        if not self.branch in legalbranches:
            raise Exception('%s does not look like a legal branch to me.' % self.branch)

    def parse_command(self, subject):
        if (subject.startswith('[PATCH]') or subject.startswith('[ONGERRIT]')):
            self.command = 'apply'
        elif (subject.startswith('[CHERRYPICK]'):
            self.command = 'cherrypick'
        elif (subject.startswith('[HELP]'):
            self.command = 'help'

    def execute(self):
        logstring = io.StringIO()
        loghandler = logging.StreamHandler(self.logstring)
        loghandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(message)s'))
        logger.addHandler(loghandler)
        logger.info('executing command: %s, branch: %s, commit: %s' % (self.command, self.branch, self.commit))
        try:
            getattr(self, 'do_%s' % self.command)()
            self.success = True
        except Exception as e:
            logger.error(e)
        logger.removeHandler(loghandler)
        self.log = log.getValue()
        return self

    def do_apply(self):
        patchpusher = PatchPusher(self.branch, self.logger)
        patchpusher.clonebase(self.sourceurl)
        patchpusher.apply_message(message)
        patchpusher.upload_change(self.desturl)

    def do_cherrypick(self):
        if self.commit is None:
            raise Exception('could not find what to cherrypick from subject: %s' % subject)
        patchpusher = PatchPusher(self.branch, self.logger)
        self.clonebase(self.sourceurl)
        self.fetch_all()
        self.cherrypick(self.commit)
        self.upload_change(self.desturl)

    def do_help(self):
        pass

class ReplyMessage(email.Message):
    def __init__(self, command):
        email.Message.__init__(self)
        
logger = logging.getLogger('patchpickup')
loghandler = logging.FileHandler(logfile)
loghandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(message)s'))
logger.addHandler(loghandler)
logger.setLevel(loglevel)

try:
    message = email.message_from_file(sys.stdin)
    reply = ReplyMessage(EmailCommand(message, sourceurl, desturl).execute())
except Exception as e:
    logger.error(e)


More information about the LibreOffice mailing list