Beispiel #1
0
def update_commit_data(cd,
                       message=None,
                       author=None,
                       sign_str=None,
                       edit=False):
    """Return a new CommitData object updated according to the command line
    options."""
    # Set the commit message from commandline.
    if message is not None:
        cd = cd.set_message(message)

    # Modify author data.
    if author is not None:
        cd = cd.set_author(author)

    # Add Signed-off-by: or similar.
    if sign_str is None:
        sign_str = config.get("stgit.autosign")
    if sign_str:
        cd = cd.set_message(
            add_trailer(cd.message_str, sign_str, cd.committer.name,
                        cd.committer.email))

    if edit:
        tmpl = templates.get_template('patchdescr.tmpl')
        if tmpl:
            cd = cd.set_message(cd.message + tmpl)
        cd = cd.set_message(edit_bytes(cd.message, '.stgit-new.txt'))

    return cd
Beispiel #2
0
def update_commit_data(cd, options):
    """Return a new CommitData object updated according to the command line
    options."""
    # Set the commit message from commandline.
    if options.message is not None:
        cd = cd.set_message(options.message)

    # Modify author data.
    cd = cd.set_author(options.author(cd.author))

    # Add Signed-off-by: or similar.
    if options.sign_str is not None:
        sign_str = options.sign_str
    else:
        sign_str = config.get("stgit.autosign")
    if sign_str is not None:
        cd = cd.set_message(
            add_sign_line(cd.message, sign_str, cd.committer.name,
                          cd.committer.email))

    # Let user edit the commit message manually, unless
    # --save-template or --message was specified.
    if not getattr(options, 'save_template', None) and options.message is None:
        tmpl = templates.get_template('patchdescr.tmpl')
        if tmpl:
            cd = cd.set_message(cd.message + tmpl)
        cd = cd.set_message(edit_string(cd.message, '.stgit-new.txt'))

    return cd
def update_commit_data(repo,
                       cd,
                       message=None,
                       author=None,
                       trailers=None,
                       edit=False,
                       verbose=False):
    """Create updated CommitData according to the command line options."""
    iw = repo.default_iw

    # Set the commit message from commandline.
    if message is not None:
        cd = cd.set_message(message)

    # Modify author data.
    if author is not None:
        cd = cd.set_author(author)

    # Add Signed-off-by: or similar.
    if not trailers:
        autosign = config.get("stgit.autosign")
        if autosign:
            trailers = [(autosign, None)]
    if trailers:
        cd = cd.set_message(
            add_trailers(cd.message_str, trailers, cd.committer.name,
                         cd.committer.email))

    if edit:
        message_str = cd.message_str
        tmpl = templates.get_template('patchdescr.tmpl')
        if tmpl:
            message_str += tmpl

        status = '\n# '.join(_git_status())
        message_str += COMMIT_MESSAGE_INSTRUCTIONS + status
        if verbose:
            # include a diff
            message_str += (COMMIT_MESSAGE_DEMARCATION_LINE +
                            COMMIT_MESSAGE_INSTRUCTIONS_2)
            message_str += iw.diff(
                repo.rev_parse('HEAD').data.tree,
                binary=False,
            ).decode('utf-8')
        new_message = edit_string(message_str, '.stgit-new.txt')
        new_message = new_message.split(COMMIT_MESSAGE_DEMARCATION_LINE)[0]
        new_message = '\n'.join(line for line in new_message.splitlines()
                                if not line.startswith('#'))
        cd = cd.set_message(new_message)

    return cd
Beispiel #4
0
def edit_file(series, line, comment, show_patch=True):
    fname = '.stgitmsg.txt'
    tmpl = templates.get_template('patchdescr.tmpl')

    with open(fname, 'w+') as f:
        if line:
            print(line, file=f)
        elif tmpl:
            print(tmpl, end=' ', file=f)
        else:
            print(file=f)
        print(__comment_prefix, comment, file=f)
        print(__comment_prefix,
              'Lines prefixed with "%s" will be automatically removed.' %
              __comment_prefix,
              file=f)
        print(__comment_prefix,
              'Trailing empty lines will be automatically removed.',
              file=f)

        if show_patch:
            print(__patch_prefix, file=f)
            # series.get_patch(series.get_current()).get_top()
            diff_str = git.diff(
                rev1=series.get_patch(series.get_current()).get_bottom())
            f.write(diff_str)

        # Vim modeline must be near the end.
        print(
            __comment_prefix,
            'vi: set textwidth=75 filetype=diff nobackup:',
            file=f,
        )

    call_editor(fname)

    with open(fname, 'r+') as f:
        __clean_comments(f)
        f.seek(0)
        result = f.read()

    os.remove(fname)

    return result
Beispiel #5
0
def update_commit_data(cd,
                       message=None,
                       author=None,
                       sign_str=None,
                       edit=False,
                       verbose=False):
    """Create updated CommitData according to the command line options."""
    # Set the commit message from commandline.
    if message is not None:
        cd = cd.set_message(message)

    # Modify author data.
    if author is not None:
        cd = cd.set_author(author)

    # Add Signed-off-by: or similar.
    if sign_str is None:
        sign_str = config.get("stgit.autosign")
    if sign_str:
        cd = cd.set_message(
            add_trailer(cd.message_str, sign_str, cd.committer.name,
                        cd.committer.email))

    if edit:
        message_str = cd.message_str
        tmpl = templates.get_template('patchdescr.tmpl')
        if tmpl:
            message_str += tmpl

        status = '\n# '.join(_git_status())
        message_str += COMMIT_MESSAGE_INSTRUCTIONS + status
        if verbose:
            # include a diff
            message_str += (COMMIT_MESSAGE_DEMARCATION_LINE +
                            COMMIT_MESSAGE_INSTRUCTIONS_2)
            message_str += '\n'.join(_git_diff())
        new_message = edit_string(message_str, '.stgit-new.txt')
        new_message = new_message.split(COMMIT_MESSAGE_DEMARCATION_LINE)[0]
        new_message = '\n'.join(line for line in new_message.splitlines()
                                if not line.startswith('#'))
        cd = cd.set_message(new_message)

    return cd
Beispiel #6
0
def edit_file(series, line, comment, show_patch = True):
    fname = '.stgitmsg.txt'
    tmpl = templates.get_template('patchdescr.tmpl')

    f = file(fname, 'w+')
    if line:
        print >> f, line
    elif tmpl:
        print >> f, tmpl,
    else:
        print >> f
    print >> f, __comment_prefix, comment
    print >> f, __comment_prefix, \
          'Lines prefixed with "%s" will be automatically removed.' \
          % __comment_prefix
    print >> f, __comment_prefix, \
          'Trailing empty lines will be automatically removed.'

    if show_patch:
       print >> f, __patch_prefix
       # series.get_patch(series.get_current()).get_top()
       diff_str = git.diff(rev1 = series.get_patch(series.get_current()).get_bottom())
       f.write(diff_str)

    #Vim modeline must be near the end.
    print >> f, __comment_prefix, 'vi: set textwidth=75 filetype=diff nobackup:'
    f.close()

    call_editor(fname)

    f = file(fname, 'r+')

    __clean_comments(f)
    f.seek(0)
    result = f.read()

    f.close()
    os.remove(fname)

    return result
Beispiel #7
0
def edit_file(series, line, comment, show_patch=True):
    fname = '.stgitmsg.txt'
    tmpl = templates.get_template('patchdescr.tmpl')

    f = file(fname, 'w+')
    if line:
        print >> f, line
    elif tmpl:
        print >> f, tmpl,
    else:
        print >> f
    print >> f, __comment_prefix, comment
    print >> f, __comment_prefix, \
          'Lines prefixed with "%s" will be automatically removed.' \
          % __comment_prefix
    print >> f, __comment_prefix, \
          'Trailing empty lines will be automatically removed.'

    if show_patch:
        print >> f, __patch_prefix
        # series.get_patch(series.get_current()).get_top()
        git.diff([],
                 series.get_patch(series.get_current()).get_bottom(), None, f)

    #Vim modeline must be near the end.
    print >> f, __comment_prefix, 'vi: set textwidth=75 filetype=diff nobackup:'
    f.close()

    call_editor(fname)

    f = file(fname, 'r+')

    __clean_comments(f)
    f.seek(0)
    result = f.read()

    f.close()
    os.remove(fname)

    return result
Beispiel #8
0
def edit_file(series, line, comment, show_patch = True):
    fname = '.stgitmsg.txt'
    tmpl = templates.get_template('patchdescr.tmpl')

    with open(fname, 'w+') as f:
        if line:
            print(line, file=f)
        elif tmpl:
            print(tmpl, end=' ', file=f)
        else:
            print(file=f)
        print(__comment_prefix, comment, file=f)
        print(__comment_prefix,
              'Lines prefixed with "%s" will be automatically removed.'
              % __comment_prefix, file=f)
        print(__comment_prefix,
              'Trailing empty lines will be automatically removed.', file=f)

        if show_patch:
           print(__patch_prefix, file=f)
           # series.get_patch(series.get_current()).get_top()
           diff_str = git.diff(rev1 = series.get_patch(series.get_current()).get_bottom())
           f.write(diff_str)

        #Vim modeline must be near the end.
        print(__comment_prefix, 'vi: set textwidth=75 filetype=diff nobackup:', file=f)

    call_editor(fname)

    with open(fname, 'r+') as f:
        __clean_comments(f)
        f.seek(0)
        result = f.read()

    os.remove(fname)

    return result
Beispiel #9
0
def func(parser, options, args):
    """Send the patches by e-mail using the patchmail.tmpl file as
    a template
    """
    stack = directory.repository.current_stack
    applied = stack.patchorder.applied

    if options.all:
        patches = applied
    elif len(args) >= 1:
        unapplied = stack.patchorder.unapplied
        patches = parse_patches(args, applied + unapplied, len(applied))
    else:
        raise CmdException('Incorrect options. Unknown patches to send')

    # early test for sender identity
    __get_sender()

    out.start('Checking the validity of the patches')
    for p in patches:
        if stack.patches.get(p).is_empty():
            raise CmdException('Cannot send empty patch "%s"' % p)
    out.done()

    total_nr = len(patches)
    if total_nr == 0:
        raise CmdException('No patches to send')

    if options.in_reply_to:
        if options.no_thread or options.unrelated:
            raise CmdException('--in-reply-to option not allowed with '
                               '--no-thread or --unrelated')
        ref_id = options.in_reply_to
    else:
        ref_id = None

    # get username/password if sending by SMTP
    __set_smtp_credentials(options)

    # send the cover message (if any)
    if options.cover or options.edit_cover:
        if options.unrelated:
            raise CmdException('cover sending not allowed with --unrelated')

        # find the template file
        if options.cover:
            with io.open(options.cover, 'r') as f:
                tmpl = f.read()
        else:
            tmpl = templates.get_template('covermail.tmpl')
            if not tmpl:
                raise CmdException('No cover message template file found')

        msg_id = __send_message('cover', tmpl, options, patches)

        # subsequent e-mails are seen as replies to the first one
        if not options.no_thread:
            ref_id = msg_id

    # send the patches
    if options.template:
        with io.open(options.template, 'r') as f:
            tmpl = f.read()
    else:
        if options.attach:
            tmpl = templates.get_template('mailattch.tmpl')
        elif options.attach_inline:
            tmpl = templates.get_template('patchandattch.tmpl')
        else:
            tmpl = templates.get_template('patchmail.tmpl')
        if not tmpl:
            raise CmdException('No e-mail template file found')

    for (p, n) in zip(patches, range(1, total_nr + 1)):
        msg_id = __send_message('patch', tmpl, options, p, n, total_nr, ref_id)

        # subsequent e-mails are seen as replies to the first one
        if not options.no_thread and not options.unrelated and not ref_id:
            ref_id = msg_id
Beispiel #10
0
def func(parser, options, args):
    """Export a range of patches.
    """
    stack = directory.repository.get_stack(options.branch)

    if options.dir:
        dirname = options.dir
    else:
        dirname = 'patches-%s' % stack.name
        directory.cd_to_topdir()

    if not options.branch and git.local_changes():
        out.warn('Local changes in the tree;'
                 ' you might want to commit them first')

    if not options.stdout:
        if not os.path.isdir(dirname):
            os.makedirs(dirname)
        series = file(os.path.join(dirname, 'series'), 'w+')

    applied = stack.patchorder.applied
    unapplied = stack.patchorder.unapplied
    if len(args) != 0:
        patches = common.parse_patches(args, applied + unapplied, len(applied))
    else:
        patches = applied

    num = len(patches)
    if num == 0:
        raise common.CmdException, 'No patches applied'

    zpadding = len(str(num))
    if zpadding < 2:
        zpadding = 2

    # get the template
    if options.template:
        tmpl = file(options.template).read()
    else:
        tmpl = templates.get_template('patchexport.tmpl')
        if not tmpl:
            tmpl = ''

    # note the base commit for this series
    if not options.stdout:
        base_commit = stack.patches.get(patches[0]).commit.sha1
        print >> series, '# This series applies on GIT commit %s' % base_commit

    patch_no = 1;
    for p in patches:
        pname = p
        if options.patch:
            pname = '%s.patch' % pname
        elif options.extension:
            pname = '%s.%s' % (pname, options.extension)
        if options.numbered:
            pname = '%s-%s' % (str(patch_no).zfill(zpadding), pname)
        pfile = os.path.join(dirname, pname)
        if not options.stdout:
            print >> series, pname

        # get the patch description
        patch = stack.patches.get(p)
        cd = patch.commit.data

        descr = cd.message.strip()
        descr_lines = descr.split('\n')

        short_descr = descr_lines[0].rstrip()
        long_descr = reduce(lambda x, y: x + '\n' + y,
                            descr_lines[1:], '').strip()

        diff = stack.repository.diff_tree(cd.parent.data.tree, cd.tree, options.diff_flags)

        tmpl_dict = {'description': descr,
                     'shortdescr': short_descr,
                     'longdescr': long_descr,
                     'diffstat': gitlib.diffstat(diff).rstrip(),
                     'authname': cd.author.name,
                     'authemail': cd.author.email,
                     'authdate': cd.author.date.isoformat(),
                     'commname': cd.committer.name,
                     'commemail': cd.committer.email}
        for key in tmpl_dict:
            if not tmpl_dict[key]:
                tmpl_dict[key] = ''

        try:
            descr = tmpl % tmpl_dict
        except KeyError, err:
            raise common.CmdException, 'Unknown patch template variable: %s' \
                  % err
        except TypeError:
            raise common.CmdException, 'Only "%(name)s" variables are ' \
                  'supported in the patch template'
Beispiel #11
0
def func(parser, options, args):
    """Export a range of patches.
    """
    if options.dir:
        dirname = options.dir
    else:
        dirname = 'patches-%s' % crt_series.get_name()

    if not options.branch and git.local_changes():
        out.warn('Local changes in the tree;'
                 ' you might want to commit them first')

    if not options.stdout:
        if not os.path.isdir(dirname):
            os.makedirs(dirname)
        series = file(os.path.join(dirname, 'series'), 'w+')

    if options.diff_opts:
        diff_flags = options.diff_opts.split()
    else:
        diff_flags = []

    applied = crt_series.get_applied()
    if len(args) != 0:
        patches = parse_patches(args, applied)
    else:
        patches = applied

    num = len(patches)
    if num == 0:
        raise CmdException, 'No patches applied'

    zpadding = len(str(num))
    if zpadding < 2:
        zpadding = 2

    # get the template
    if options.template:
        tmpl = file(options.template).read()
    else:
        tmpl = templates.get_template('patchexport.tmpl')
        if not tmpl:
            tmpl = ''

    # note the base commit for this series
    if not options.stdout:
        base_commit = crt_series.get_patch(patches[0]).get_bottom()
        print >> series, '# This series applies on GIT commit %s' % base_commit

    patch_no = 1;
    for p in patches:
        pname = p
        if options.patch:
            pname = '%s.patch' % pname
        elif options.extension:
            pname = '%s.%s' % (pname, options.extension)
        if options.numbered:
            pname = '%s-%s' % (str(patch_no).zfill(zpadding), pname)
        pfile = os.path.join(dirname, pname)
        if not options.stdout:
            print >> series, pname

        # get the patch description
        patch = crt_series.get_patch(p)

        descr = patch.get_description().strip()
        descr_lines = descr.split('\n')

        short_descr = descr_lines[0].rstrip()
        long_descr = reduce(lambda x, y: x + '\n' + y,
                            descr_lines[1:], '').strip()

        tmpl_dict = {'description': patch.get_description().rstrip(),
                     'shortdescr': short_descr,
                     'longdescr': long_descr,
                     'diffstat': git.diffstat(rev1 = patch.get_bottom(),
                                              rev2 = patch.get_top()),
                     'authname': patch.get_authname(),
                     'authemail': patch.get_authemail(),
                     'authdate': patch.get_authdate(),
                     'commname': patch.get_commname(),
                     'commemail': patch.get_commemail()}
        for key in tmpl_dict:
            if not tmpl_dict[key]:
                tmpl_dict[key] = ''

        try:
            descr = tmpl % tmpl_dict
        except KeyError, err:
            raise CmdException, 'Unknown patch template variable: %s' \
                  % err
        except TypeError:
            raise CmdException, 'Only "%(name)s" variables are ' \
                  'supported in the patch template'
Beispiel #12
0
def func(parser, options, args):
    """Send the patches by e-mail using the patchmail.tmpl file as
    a template
    """
    smtpserver = config.get('stgit.smtpserver')

    applied = crt_series.get_applied()

    if options.all:
        patches = applied
    elif len(args) >= 1:
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied, len(applied))
    else:
        raise CmdException, 'Incorrect options. Unknown patches to send'

    smtppassword = options.smtp_password or config.get('stgit.smtppassword')
    smtpuser = options.smtp_user or config.get('stgit.smtpuser')

    if (smtppassword and not smtpuser):
        raise CmdException, 'SMTP password supplied, username needed'
    if (smtpuser and not smtppassword):
        raise CmdException, 'SMTP username supplied, password needed'

    total_nr = len(patches)
    if total_nr == 0:
        raise CmdException, 'No patches to send'

    if options.refid:
        if options.noreply or options.unrelated:
            raise CmdException, \
                  '--refid option not allowed with --noreply or --unrelated'
        ref_id = options.refid
    else:
        ref_id = None

    sleep = options.sleep or config.getint('stgit.smtpdelay')

    # send the cover message (if any)
    if options.cover or options.edit_cover:
        if options.unrelated:
            raise CmdException, 'cover sending not allowed with --unrelated'

        # find the template file
        if options.cover:
            tmpl = file(options.cover).read()
        else:
            tmpl = templates.get_template('covermail.tmpl')
            if not tmpl:
                raise CmdException, 'No cover message template file found'

        msg_id = email.Utils.make_msgid('stgit')
        msg = __build_cover(tmpl, total_nr, msg_id, options)
        from_addr, to_addr_list = __parse_addresses(msg)

        msg_string = msg.as_string(options.mbox)

        # subsequent e-mails are seen as replies to the first one
        if not options.noreply:
            ref_id = msg_id

        if options.mbox:
            out.stdout_raw(msg_string + '\n')
        else:
            out.start('Sending the cover message')
            __send_message(smtpserver, from_addr, to_addr_list, msg_string,
                           sleep, smtpuser, smtppassword)
            out.done()

    # send the patches
    if options.template:
        tmpl = file(options.template).read()
    else:
        tmpl = templates.get_template('patchmail.tmpl')
        if not tmpl:
            raise CmdException, 'No e-mail template file found'

    for (p, patch_nr) in zip(patches, range(1, len(patches) + 1)):
        msg_id = email.Utils.make_msgid('stgit')
        msg = __build_message(tmpl, p, patch_nr, total_nr, msg_id, ref_id,
                              options)
        from_addr, to_addr_list = __parse_addresses(msg)

        msg_string = msg.as_string(options.mbox)

        # subsequent e-mails are seen as replies to the first one
        if not options.noreply and not options.unrelated and not ref_id:
            ref_id = msg_id

        if options.mbox:
            out.stdout_raw(msg_string + '\n')
        else:
            out.start('Sending patch "%s"' % p)
            __send_message(smtpserver, from_addr, to_addr_list, msg_string,
                           sleep, smtpuser, smtppassword)
            out.done()
Beispiel #13
0
def func(parser, options, args):
    """Send the patches by e-mail using the patchmail.tmpl file as
    a template
    """
    applied = crt_series.get_applied()

    if options.all:
        patches = applied
    elif len(args) >= 1:
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied, len(applied))
    else:
        raise CmdException, 'Incorrect options. Unknown patches to send'

    # early test for sender identity
    __get_sender()

    out.start('Checking the validity of the patches')
    for p in patches:
        if crt_series.empty_patch(p):
            raise CmdException, 'Cannot send empty patch "%s"' % p
    out.done()

    total_nr = len(patches)
    if total_nr == 0:
        raise CmdException, 'No patches to send'

    if options.in_reply_to:
        if options.no_thread or options.unrelated:
            raise CmdException, \
                  '--in-reply-to option not allowed with --no-thread or --unrelated'
        ref_id = options.in_reply_to
    else:
        ref_id = None

    # get username/password if sending by SMTP
    __set_smtp_credentials(options)

    # send the cover message (if any)
    if options.cover or options.edit_cover:
        if options.unrelated:
            raise CmdException, 'cover sending not allowed with --unrelated'

        # find the template file
        if options.cover:
            tmpl = file(options.cover).read()
        else:
            tmpl = templates.get_template('covermail.tmpl')
            if not tmpl:
                raise CmdException, 'No cover message template file found'

        msg_id = __send_message('cover', tmpl, options, patches)

        # subsequent e-mails are seen as replies to the first one
        if not options.no_thread:
            ref_id = msg_id

    # send the patches
    if options.template:
        tmpl = file(options.template).read()
    else:
        if options.attach:
            tmpl = templates.get_template('mailattch.tmpl')
        elif options.attach_inline:
            tmpl = templates.get_template('patchandattch.tmpl')
        else:
            tmpl = templates.get_template('patchmail.tmpl')
        if not tmpl:
            raise CmdException, 'No e-mail template file found'

    for (p, n) in zip(patches, range(1, total_nr + 1)):
        msg_id = __send_message('patch', tmpl, options, p, n, total_nr, ref_id)

        # subsequent e-mails are seen as replies to the first one
        if not options.no_thread and not options.unrelated and not ref_id:
            ref_id = msg_id
Beispiel #14
0
def func(parser, options, args):
    """Export a range of patches.
    """
    if options.dir:
        dirname = options.dir
    else:
        dirname = 'patches-%s' % crt_series.get_name()

    if not options.branch and git.local_changes():
        out.warn('Local changes in the tree;'
                 ' you might want to commit them first')

    if not options.stdout:
        if not os.path.isdir(dirname):
            os.makedirs(dirname)
        series = file(os.path.join(dirname, 'series'), 'w+')

    if options.diff_opts:
        diff_flags = options.diff_opts.split()
    else:
        diff_flags = []

    applied = crt_series.get_applied()
    if len(args) != 0:
        patches = parse_patches(args, applied)
    else:
        patches = applied

    num = len(patches)
    if num == 0:
        raise CmdException, 'No patches applied'

    zpadding = len(str(num))
    if zpadding < 2:
        zpadding = 2

    # get the template
    if options.template:
        tmpl = file(options.template).read()
    else:
        tmpl = templates.get_template('patchexport.tmpl')
        if not tmpl:
            tmpl = ''

    # note the base commit for this series
    if not options.stdout:
        base_commit = crt_series.get_patch(patches[0]).get_bottom()
        print >> series, '# This series applies on GIT commit %s' % base_commit

    patch_no = 1
    for p in patches:
        pname = p
        if options.patch:
            pname = '%s.patch' % pname
        elif options.extension:
            pname = '%s.%s' % (pname, options.extension)
        if options.numbered:
            pname = '%s-%s' % (str(patch_no).zfill(zpadding), pname)
        pfile = os.path.join(dirname, pname)
        if not options.stdout:
            print >> series, pname

        # get the patch description
        patch = crt_series.get_patch(p)

        descr = patch.get_description().strip()
        descr_lines = descr.split('\n')

        short_descr = descr_lines[0].rstrip()
        long_descr = reduce(lambda x, y: x + '\n' + y, descr_lines[1:],
                            '').strip()

        tmpl_dict = {
            'description': patch.get_description().rstrip(),
            'shortdescr': short_descr,
            'longdescr': long_descr,
            'diffstat': git.diffstat(rev1=patch.get_bottom(),
                                     rev2=patch.get_top()),
            'authname': patch.get_authname(),
            'authemail': patch.get_authemail(),
            'authdate': patch.get_authdate(),
            'commname': patch.get_commname(),
            'commemail': patch.get_commemail()
        }
        for key in tmpl_dict:
            if not tmpl_dict[key]:
                tmpl_dict[key] = ''

        try:
            descr = tmpl % tmpl_dict
        except KeyError, err:
            raise CmdException, 'Unknown patch template variable: %s' \
                  % err
        except TypeError:
            raise CmdException, 'Only "%(name)s" variables are ' \
                  'supported in the patch template'
Beispiel #15
0
def func(parser, options, args):
    """Send the patches by e-mail using the patchmail.tmpl file as
    a template
    """
    smtpserver = config.get('stgit.smtpserver')

    applied = crt_series.get_applied()

    if options.all:
        patches = applied
    elif len(args) >= 1:
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied, len(applied))
    else:
        raise CmdException, 'Incorrect options. Unknown patches to send'

    smtppassword = options.smtp_password or config.get('stgit.smtppassword')
    smtpuser = options.smtp_user or config.get('stgit.smtpuser')

    if (smtppassword and not smtpuser):
        raise CmdException, 'SMTP password supplied, username needed'
    if (smtpuser and not smtppassword):
        raise CmdException, 'SMTP username supplied, password needed'

    total_nr = len(patches)
    if total_nr == 0:
        raise CmdException, 'No patches to send'

    if options.refid:
        if options.noreply or options.unrelated:
            raise CmdException, \
                  '--refid option not allowed with --noreply or --unrelated'
        ref_id = options.refid
    else:
        ref_id = None

    sleep = options.sleep or config.getint('stgit.smtpdelay')

    # send the cover message (if any)
    if options.cover or options.edit_cover:
        if options.unrelated:
            raise CmdException, 'cover sending not allowed with --unrelated'

        # find the template file
        if options.cover:
            tmpl = file(options.cover).read()
        else:
            tmpl = templates.get_template('covermail.tmpl')
            if not tmpl:
                raise CmdException, 'No cover message template file found'

        msg_id = email.Utils.make_msgid('stgit')
        msg = __build_cover(tmpl, total_nr, msg_id, options)
        from_addr, to_addr_list = __parse_addresses(msg)

        msg_string = msg.as_string(options.mbox)

        # subsequent e-mails are seen as replies to the first one
        if not options.noreply:
            ref_id = msg_id

        if options.mbox:
            out.stdout_raw(msg_string + '\n')
        else:
            out.start('Sending the cover message')
            __send_message(smtpserver, from_addr, to_addr_list, msg_string,
                           sleep, smtpuser, smtppassword)
            out.done()

    # send the patches
    if options.template:
        tmpl = file(options.template).read()
    else:
        tmpl = templates.get_template('patchmail.tmpl')
        if not tmpl:
            raise CmdException, 'No e-mail template file found'

    for (p, patch_nr) in zip(patches, range(1, len(patches) + 1)):
        msg_id = email.Utils.make_msgid('stgit')
        msg = __build_message(tmpl, p, patch_nr, total_nr, msg_id, ref_id,
                              options)
        from_addr, to_addr_list = __parse_addresses(msg)

        msg_string = msg.as_string(options.mbox)

        # subsequent e-mails are seen as replies to the first one
        if not options.noreply and not options.unrelated and not ref_id:
            ref_id = msg_id

        if options.mbox:
            out.stdout_raw(msg_string + '\n')
        else:
            out.start('Sending patch "%s"' % p)
            __send_message(smtpserver, from_addr, to_addr_list, msg_string,
                           sleep, smtpuser, smtppassword)
            out.done()
Beispiel #16
0
def func(parser, options, args):
    """Export a range of patches.
    """
    stack = directory.repository.get_stack(options.branch)

    if options.dir:
        dirname = options.dir
    else:
        dirname = 'patches-%s' % stack.name
        directory.cd_to_topdir()

    if not options.branch and git.local_changes():
        out.warn('Local changes in the tree;'
                 ' you might want to commit them first')

    applied = stack.patchorder.applied
    unapplied = stack.patchorder.unapplied
    if len(args) != 0:
        patches = common.parse_patches(args, applied + unapplied, len(applied))
    else:
        patches = applied

    num = len(patches)
    if num == 0:
        raise common.CmdException('No patches applied')

    zpadding = len(str(num))
    if zpadding < 2:
        zpadding = 2

    # get the template
    if options.template:
        with io.open(options.template, 'r') as f:
            tmpl = f.read()
    else:
        tmpl = templates.get_template('patchexport.tmpl')
        if not tmpl:
            tmpl = ''

    if not options.stdout:
        if not os.path.isdir(dirname):
            os.makedirs(dirname)
        series = io.open(os.path.join(dirname, 'series'), 'w')
        # note the base commit for this series
        base_commit = stack.base.sha1
        print('# This series applies on GIT commit %s' % base_commit,
              file=series)

    for patch_no, p in enumerate(patches, 1):
        pname = p
        if options.patch:
            pname = '%s.patch' % pname
        elif options.extension:
            pname = '%s.%s' % (pname, options.extension)
        if options.numbered:
            pname = '%s-%s' % (str(patch_no).zfill(zpadding), pname)
        pfile = os.path.join(dirname, pname)
        if not options.stdout:
            print(pname, file=series)

        # get the patch description
        patch = stack.patches.get(p)
        cd = patch.commit.data

        descr = cd.message.strip()
        descr_lines = descr.split('\n')

        short_descr = descr_lines[0].rstrip()
        long_descr = '\n'.join(descr_lines[1:]).strip()

        diff = stack.repository.diff_tree(cd.parent.data.tree, cd.tree,
                                          options.diff_flags)

        tmpl_dict = {
            'description': descr,
            'shortdescr': short_descr,
            'longdescr': long_descr,
            'diffstat': gitlib.diffstat(diff).rstrip(),
            'authname': cd.author.name,
            'authemail': cd.author.email,
            'authdate': cd.author.date.isoformat(),
            'commname': cd.committer.name,
            'commemail': cd.committer.email
        }

        try:
            descr = templates.specialize_template(tmpl, tmpl_dict)
        except KeyError as err:
            raise common.CmdException('Unknown patch template variable: %s' %
                                      err)
        except TypeError:
            raise common.CmdException('Only "%(name)s" variables are '
                                      'supported in the patch template')

        if options.stdout:
            if hasattr(sys.stdout, 'buffer'):
                f = sys.stdout.buffer
            else:
                f = sys.stdout
        else:
            f = io.open(pfile, 'wb')

        if options.stdout and num > 1:
            f.write('\n'.join(['-' * 79, patch.name, '-' * 79,
                               '']).encode('utf-8'))

        f.write(descr)
        f.write(diff)
        if not options.stdout:
            f.close()

    if not options.stdout:
        series.close()
Beispiel #17
0
def func(parser, options, args):
    """Send the patches by e-mail using the patchmail.tmpl file as
    a template
    """
    smtpserver = options.smtp_server or config.get('stgit.smtpserver')

    applied = crt_series.get_applied()

    if options.all:
        patches = applied
    elif len(args) >= 1:
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied, len(applied))
    else:
        raise CmdException, 'Incorrect options. Unknown patches to send'

    # early test for sender identity
    __get_sender()

    out.start('Checking the validity of the patches')
    for p in patches:
        if crt_series.empty_patch(p):
            raise CmdException, 'Cannot send empty patch "%s"' % p
    out.done()

    smtppassword = options.smtp_password or config.get('stgit.smtppassword')
    smtpuser = options.smtp_user or config.get('stgit.smtpuser')
    smtpusetls = options.smtp_tls or config.get('stgit.smtptls') == 'yes'

    if (smtppassword and not smtpuser):
        raise CmdException, 'SMTP password supplied, username needed'
    if (smtpusetls and not smtpuser):
        raise CmdException, 'SMTP over TLS requested, username needed'
    if (smtpuser and not smtppassword):
        smtppassword = getpass.getpass("Please enter SMTP password: "******"%s"' % p)
            __send_message(smtpserver, from_addr, to_addr_list, msg_string,
                           smtpuser, smtppassword, smtpusetls)
            # give recipients a chance of receiving related patches in the
            # correct order.
            if patch_nr < total_nr:
                time.sleep(sleep)
            out.done()