Ejemplo n.º 1
0
Archivo: edit.py Proyecto: samv/stgit
def patch_desc(repo, cd, append_diff, diff_flags, replacement_diff):
    """Return a description text for the patch, suitable for editing
    and/or reimporting with L{update_patch_description()}.

    @param cd: The L{CommitData<stgit.lib.git.CommitData>} to generate
               a description of
    @param append_diff: Whether to append the patch diff to the
                        description
    @type append_diff: C{bool}
    @param diff_flags: Extra parameters to pass to C{git diff}
    @param replacement_diff: Diff text to use; or C{None} if it should
                             be computed from C{cd}
    @type replacement_diff: C{str} or C{None}"""
    desc = ['From: %s <%s>' % (cd.author.name, cd.author.email),
            'Date: %s' % cd.author.date.isoformat(),
            '',
            cd.message]
    if append_diff:
        if replacement_diff:
            diff = replacement_diff
        else:
            just_diff = repo.diff_tree(cd.parent.data.tree, cd.tree, diff_flags)
            diff = '\n'.join([git.diffstat(just_diff), just_diff])
        desc += ['---', '', diff]
    return '\n'.join(desc)
Ejemplo n.º 2
0
def patch_desc(repo, cd, append_diff, diff_flags, replacement_diff):
    """Return a description text for the patch, suitable for editing
    and/or reimporting with L{update_patch_description()}.

    @param cd: The L{CommitData<stgit.lib.git.CommitData>} to generate
               a description of
    @param append_diff: Whether to append the patch diff to the
                        description
    @type append_diff: C{bool}
    @param diff_flags: Extra parameters to pass to C{git diff}
    @param replacement_diff: Diff text to use; or C{None} if it should
                             be computed from C{cd}
    @type replacement_diff: C{str} or C{None}"""
    desc = '\n'.join([
        'From: %s <%s>' % (cd.author.name, cd.author.email),
        'Date: %s' % cd.author.date.isoformat(),
        '',
        cd.message,
    ]).encode('utf-8')
    if append_diff:
        desc += b'\n---\n'
        if replacement_diff:
            desc += b'\n' + replacement_diff
        else:
            diff = repo.diff_tree(cd.parent.data.tree, cd.tree, diff_flags)
            if diff:
                desc += b'\n'.join([b'', diffstat(diff).encode('utf-8'), diff])
    return desc
Ejemplo n.º 3
0
def func(parser, options, args):
    """Show commit log and diff
    """
    if options.applied:
        patches = crt_series.get_applied()
    elif options.unapplied:
        patches = crt_series.get_unapplied()
    elif len(args) == 0:
        patches = ['HEAD']
    elif '..' in ' '.join(args):
        # patch ranges
        applied = crt_series.get_applied()
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied + \
                                crt_series.get_hidden(), len(applied))
    else:
        # individual patches or commit ids
        patches = args

    if not options.stat:
        options.diff_flags.extend(color_diff_flags())
    commit_ids = [git_id(crt_series, patch) for patch in patches]
    commit_str = '\n'.join([
        git.pretty_commit(commit_id, flags=options.diff_flags)
        for commit_id in commit_ids
    ])
    if options.stat:
        commit_str = gitlib.diffstat(commit_str)
    if commit_str:
        pager(commit_str)
Ejemplo n.º 4
0
def func(parser, options, args):
    """Show the tree diff
    """
    args = git.ls_files(args)
    directory.cd_to_topdir()

    if options.revs:
        rev_list = options.revs.split('..')
        rev_list_len = len(rev_list)
        if rev_list_len == 1:
            rev1 = rev_list[0]
            rev2 = None
        elif rev_list_len == 2:
            rev1 = rev_list[0]
            rev2 = rev_list[1]
        else:
            parser.error('incorrect parameters to -r')
    else:
        rev1 = 'HEAD'
        rev2 = None

    if not options.stat:
        options.diff_flags.extend(color_diff_flags())
    diff_str = git.diff(args, rev1 and git_id(crt_series, rev1),
                        rev2 and git_id(crt_series, rev2),
                        diff_flags = options.diff_flags)
    if options.stat:
        out.stdout_raw(gitlib.diffstat(diff_str) + '\n')
    else:
        if diff_str:
            pager(diff_str)
Ejemplo n.º 5
0
def func(parser, options, args):
    """Show commit log and diff
    """
    if options.applied:
        patches = crt_series.get_applied()
    elif options.unapplied:
        patches = crt_series.get_unapplied()
    elif len(args) == 0:
        patches = ['HEAD']
    elif '..' in ' '.join(args):
        # patch ranges
        applied = crt_series.get_applied()
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied + \
                                crt_series.get_hidden(), len(applied))
    else:
        # individual patches or commit ids
        patches = args

    if not options.stat:
        options.diff_flags.extend(color_diff_flags())
    commit_ids = [git_id(crt_series, patch) for patch in patches]
    commit_str = '\n'.join([git.pretty_commit(commit_id,
                                              flags = options.diff_flags)
                            for commit_id in commit_ids])
    if options.stat:
        commit_str = gitlib.diffstat(commit_str)
    if commit_str:
        pager(commit_str)
Ejemplo n.º 6
0
def func(parser, options, args):
    """Show the files modified by a patch (or the current patch)
    """
    if options.bare and options.stat:
        raise CmdException('Cannot specify both --bare and --stat')
    if len(args) == 0:
        patch = 'HEAD'
    elif len(args) == 1:
        patch = args[0]
    else:
        parser.error('incorrect number of arguments')

    rev1 = git_id(crt_series, '%s^' % patch)
    rev2 = git_id(crt_series, '%s' % patch)

    if options.stat:
        output = gitlib.diffstat(
            git.diff(rev1=rev1, rev2=rev2, diff_flags=options.diff_flags))
    elif options.bare:
        output = git.barefiles(rev1, rev2)
    else:
        output = git.files(rev1, rev2, diff_flags=options.diff_flags)
    if output:
        if not output.endswith('\n'):
            output += '\n'
        out.stdout_raw(output)
Ejemplo n.º 7
0
def func(parser, options, args):
    """Show the tree diff
    """
    args = git.ls_files(args)
    directory.cd_to_topdir()

    if options.revs:
        rev_list = options.revs.split('..')
        rev_list_len = len(rev_list)
        if rev_list_len == 1:
            rev1 = rev_list[0]
            rev2 = None
        elif rev_list_len == 2:
            rev1 = rev_list[0]
            rev2 = rev_list[1]
        else:
            parser.error('incorrect parameters to -r')
    else:
        rev1 = 'HEAD'
        rev2 = None

    if not options.stat:
        options.diff_flags.extend(color_diff_flags())
    diff_str = git.diff(args,
                        rev1 and git_id(crt_series, rev1),
                        rev2 and git_id(crt_series, rev2),
                        diff_flags=options.diff_flags)
    if options.stat:
        out.stdout_raw(gitlib.diffstat(diff_str) + '\n')
    else:
        if diff_str:
            pager(diff_str)
Ejemplo n.º 8
0
def func(parser, options, args):
    """Show commit log and diff
    """
    if options.applied:
        patches = crt_series.get_applied()
    elif options.unapplied:
        patches = crt_series.get_unapplied()
    elif len(args) == 0:
        patches = ['HEAD']
    elif '..' in ' '.join(args):
        # patch ranges
        applied = crt_series.get_applied()
        unapplied = crt_series.get_unapplied()
        patches = parse_patches(args, applied + unapplied + \
                                crt_series.get_hidden(), len(applied))
    else:
        # individual patches or commit ids
        patches = args

    if not options.stat:
        options.diff_flags.extend(color_diff_flags())
    commit_ids = [git_id(crt_series, patch) for patch in patches]
    commit_bytes = b'\n'.join(
        (Run('git', 'show', *(options.diff_flags +
                              [commit_id])).decoding(None).raw_output())
        for commit_id in commit_ids)
    if options.stat:
        commit_bytes = git.diffstat(commit_bytes).encode('utf-8')
    if commit_bytes:
        pager(commit_bytes)
Ejemplo n.º 9
0
Archivo: mail.py Proyecto: samv/stgit
def __build_cover(tmpl, msg_id, options, patches):
    """Build the cover message (series description) to be sent via SMTP
    """
    sender = __get_sender()

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = str(len(patches))
    patch_nr_str = '0'.zfill(len(total_nr_str))
    if len(patches) > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    tmpl_dict = {'sender':       sender,
                 # for backward template compatibility
                 'maintainer':   sender,
                 # for backward template compatibility
                 'endofheaders': '',
                 # for backward template compatibility
                 'date':         '',
                 'version':      version_str,
                 'vspace':       version_space,
                 'prefix':       prefix_str,
                 'pspace':       prefix_space,
                 'patchnr':      patch_nr_str,
                 'totalnr':      total_nr_str,
                 'number':       number_str,
                 'nspace':       number_space,
                 'snumber':      number_str.strip(),
                 'shortlog':     stack.shortlog(crt_series.get_patch(p)
                                                for p in reversed(patches)),
                 'diffstat':     gitlib.diffstat(git.diff(
                     rev1 = git_id(crt_series, '%s^' % patches[0]),
                     rev2 = git_id(crt_series, '%s' % patches[-1]),
                     diff_flags = options.diff_flags))}

    try:
        msg_string = tmpl % tmpl_dict
    except KeyError, err:
        raise CmdException, 'Unknown patch template variable: %s' \
              % err
Ejemplo n.º 10
0
Archivo: files.py Proyecto: snits/stgit
def func(parser, options, args):
    """Show the files modified by a patch (or the current patch)
    """
    if len(args) == 0:
        patch = 'HEAD'
    elif len(args) == 1:
        patch = args[0]
    else:
        parser.error('incorrect number of arguments')

    rev1 = git_id(crt_series, '%s^' % patch)
    rev2 = git_id(crt_series, '%s' % patch)

    if options.stat:
        output = gitlib.diffstat(git.diff(rev1 = rev1, rev2 = rev2,
                                          diff_flags = options.diff_flags))
    elif options.bare:
        output = git.barefiles(rev1, rev2)
    else:
        output = git.files(rev1, rev2, diff_flags = options.diff_flags)
    if output:
        if not output.endswith('\n'):
            output += '\n'
        out.stdout_raw(output)
Ejemplo n.º 11
0
def __build_cover(tmpl, msg_id, options, patches):
    """Build the cover message (series description) to be sent via SMTP
    """
    sender = __get_sender()

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = text(len(patches))
    patch_nr_str = '0'.zfill(len(total_nr_str))
    if len(patches) > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    tmpl_dict = {
        'sender':
        sender,  # for backward template compatibility
        'maintainer':
        sender,  # for backward template compatibility
        'endofheaders':
        '',  # for backward template compatibility
        'date':
        '',
        'version':
        version_str,
        'vspace':
        version_space,
        'prefix':
        prefix_str,
        'pspace':
        prefix_space,
        'patchnr':
        patch_nr_str,
        'totalnr':
        total_nr_str,
        'number':
        number_str,
        'nspace':
        number_space,
        'snumber':
        number_str.strip(),
        'shortlog':
        stack.shortlog(crt_series.get_patch(p) for p in reversed(patches)),
        'diffstat':
        diffstat(
            git.diff(
                rev1=git_id(crt_series, '%s^' % patches[0]),
                rev2=git_id(crt_series, '%s' % patches[-1]),
                diff_flags=options.diff_flags,
            )),
    }

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

    if options.edit_cover:
        msg_bytes = edit_bytes(msg_bytes, '.stgitmail.txt')

    # The Python email message
    try:
        msg = message_from_bytes(msg_bytes)
    except Exception as ex:
        raise CmdException('template parsing error: %s' % str(ex))

    extra_cc = []
    if options.auto:
        for patch in patches:
            p = crt_series.get_patch(patch)
            if p.get_description():
                descr = p.get_description().strip()
                extra_cc.extend(__get_signers_list(descr))
        extra_cc = list(set(extra_cc))

    if not options.git:
        __build_address_headers(msg, options, extra_cc)
    __build_extra_headers(msg, msg_id, options.in_reply_to)
    __encode_message(msg)

    return msg
Ejemplo n.º 12
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'
Ejemplo n.º 13
0
Archivo: mail.py Proyecto: samv/stgit
def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id):
    """Build the message to be sent via SMTP
    """
    p = crt_series.get_patch(patch)

    if p.get_description():
        descr = p.get_description().strip()
    else:
        # provide a place holder and force the edit message option on
        descr = '<empty message>'
        options.edit_patches = True

    descr_lines = descr.split('\n')
    short_descr = descr_lines[0].strip()
    long_descr = '\n'.join(l.rstrip() for l in descr_lines[1:]).lstrip('\n')

    authname = p.get_authname();
    authemail = p.get_authemail();
    commname = p.get_commname();
    commemail = p.get_commemail();

    sender = __get_sender()

    fromauth = '%s <%s>' % (authname, authemail)
    if fromauth != sender:
        fromauth = 'From: %s\n\n' % fromauth
    else:
        fromauth = ''

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = str(total_nr)
    patch_nr_str = str(patch_nr).zfill(len(total_nr_str))
    if not options.unrelated and total_nr > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    diff = git.diff(rev1 = git_id(crt_series, '%s^' % patch),
                    rev2 = git_id(crt_series, '%s' % patch),
                    diff_flags = options.diff_flags)
    tmpl_dict = {'patch':        patch,
                 'sender':       sender,
                 # for backward template compatibility
                 'maintainer':   sender,
                 'shortdescr':   short_descr,
                 'longdescr':    long_descr,
                 # for backward template compatibility
                 'endofheaders': '',
                 'diff':         diff,
                 'diffstat':     gitlib.diffstat(diff),
                 # for backward template compatibility
                 'date':         '',
                 'version':      version_str,
                 'vspace':       version_space,
                 'prefix':       prefix_str,
                 'pspace':       prefix_space,
                 'patchnr':      patch_nr_str,
                 'totalnr':      total_nr_str,
                 'number':       number_str,
                 'nspace':       number_space,
                 'snumber':      number_str.strip(),
                 'fromauth':     fromauth,
                 'authname':     authname,
                 'authemail':    authemail,
                 'authdate':     p.get_authdate(),
                 'commname':     commname,
                 'commemail':    commemail}
    # change None to ''
    for key in tmpl_dict:
        if not tmpl_dict[key]:
            tmpl_dict[key] = ''

    try:
        msg_string = tmpl % tmpl_dict
    except KeyError, err:
        raise CmdException, 'Unknown patch template variable: %s' \
              % err
Ejemplo n.º 14
0
Archivo: mail.py Proyecto: snits/stgit
def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id):
    """Build the message to be sent via SMTP
    """
    p = crt_series.get_patch(patch)

    if p.get_description():
        descr = p.get_description().strip()
    else:
        # provide a place holder and force the edit message option on
        descr = '<empty message>'
        options.edit_patches = True

    descr_lines = descr.split('\n')
    short_descr = descr_lines[0].strip()
    long_descr = '\n'.join(l.rstrip() for l in descr_lines[1:]).lstrip('\n')

    authname = p.get_authname()
    authemail = p.get_authemail()
    commname = p.get_commname()
    commemail = p.get_commemail()

    sender = __get_sender()

    fromauth = '%s <%s>' % (authname, authemail)
    if fromauth != sender:
        fromauth = 'From: %s\n\n' % fromauth
    else:
        fromauth = ''

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = text(total_nr)
    patch_nr_str = text(patch_nr).zfill(len(total_nr_str))
    if not options.unrelated and total_nr > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    diff = git.diff(rev1 = git_id(crt_series, '%s^' % patch),
                    rev2 = git_id(crt_series, '%s' % patch),
                    diff_flags = options.diff_flags)
    tmpl_dict = {'patch':        patch,
                 'sender':       sender,
                 # for backward template compatibility
                 'maintainer':   sender,
                 'shortdescr':   short_descr,
                 'longdescr':    long_descr,
                 # for backward template compatibility
                 'endofheaders': '',
                 'diff':         diff,
                 'diffstat':     gitlib.diffstat(diff),
                 # for backward template compatibility
                 'date':         '',
                 'version':      version_str,
                 'vspace':       version_space,
                 'prefix':       prefix_str,
                 'pspace':       prefix_space,
                 'patchnr':      patch_nr_str,
                 'totalnr':      total_nr_str,
                 'number':       number_str,
                 'nspace':       number_space,
                 'snumber':      number_str.strip(),
                 'fromauth':     fromauth,
                 'authname':     authname,
                 'authemail':    authemail,
                 'authdate':     p.get_authdate(),
                 'commname':     commname,
                 'commemail':    commemail}
    # change None to ''
    for key in tmpl_dict:
        if not tmpl_dict[key]:
            tmpl_dict[key] = ''

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

    if options.edit_patches:
        msg_string = __edit_message(msg_string)

    # The Python email message
    try:
        msg = email.message_from_string(msg_string)
    except Exception as ex:
        raise CmdException('template parsing error: %s' % str(ex))

    if options.auto:
        extra_cc = __get_signers_list(descr)
    else:
        extra_cc = []

    if not options.git:
        __build_address_headers(msg, options, extra_cc)
    __build_extra_headers(msg, msg_id, ref_id)
    __encode_message(msg)

    return msg
Ejemplo n.º 15
0
Archivo: mail.py Proyecto: snits/stgit
def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id):
    """Build the message to be sent via SMTP
    """
    p = crt_series.get_patch(patch)

    if p.get_description():
        descr = p.get_description().strip()
    else:
        # provide a place holder and force the edit message option on
        descr = '<empty message>'
        options.edit_patches = True

    descr_lines = descr.split('\n')
    short_descr = descr_lines[0].strip()
    long_descr = '\n'.join(l.rstrip() for l in descr_lines[1:]).lstrip('\n')

    authname = p.get_authname()
    authemail = p.get_authemail()
    commname = p.get_commname()
    commemail = p.get_commemail()

    sender = __get_sender()

    fromauth = '%s <%s>' % (authname, authemail)
    if fromauth != sender:
        fromauth = 'From: %s\n\n' % fromauth
    else:
        fromauth = ''

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = text(total_nr)
    patch_nr_str = text(patch_nr).zfill(len(total_nr_str))
    if not options.unrelated and total_nr > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    diff = git.diff(rev1=git_id(crt_series, '%s^' % patch),
                    rev2=git_id(crt_series, '%s' % patch),
                    diff_flags=options.diff_flags)
    tmpl_dict = {
        'patch': patch,
        'sender': sender,
        # for backward template compatibility
        'maintainer': sender,
        'shortdescr': short_descr,
        'longdescr': long_descr,
        # for backward template compatibility
        'endofheaders': '',
        'diff': diff,
        'diffstat': gitlib.diffstat(diff),
        # for backward template compatibility
        'date': '',
        'version': version_str,
        'vspace': version_space,
        'prefix': prefix_str,
        'pspace': prefix_space,
        'patchnr': patch_nr_str,
        'totalnr': total_nr_str,
        'number': number_str,
        'nspace': number_space,
        'snumber': number_str.strip(),
        'fromauth': fromauth,
        'authname': authname,
        'authemail': authemail,
        'authdate': p.get_authdate(),
        'commname': commname,
        'commemail': commemail
    }
    # change None to ''
    for key in tmpl_dict:
        if not tmpl_dict[key]:
            tmpl_dict[key] = ''

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

    if options.edit_patches:
        msg_string = __edit_message(msg_string)

    # The Python email message
    try:
        msg = email.message_from_string(msg_string)
    except Exception as ex:
        raise CmdException('template parsing error: %s' % str(ex))

    if options.auto:
        extra_cc = __get_signers_list(descr)
    else:
        extra_cc = []

    if not options.git:
        __build_address_headers(msg, options, extra_cc)
    __build_extra_headers(msg, msg_id, ref_id)
    __encode_message(msg)

    return msg
Ejemplo n.º 16
0
def __build_message(tmpl, msg_id, options, patch, patch_nr, total_nr, ref_id):
    """Build the message to be sent via SMTP
    """
    repository = directory.repository
    stack = repository.current_stack

    p = stack.patches.get(patch)

    if p.commit.data.message:
        descr = p.commit.data.message.strip()
    else:
        # provide a place holder and force the edit message option on
        descr = '<empty message>'
        options.edit_patches = True

    descr_lines = descr.split('\n')
    short_descr = descr_lines[0].strip()
    long_descr = '\n'.join(l.rstrip() for l in descr_lines[1:]).lstrip('\n')

    author = p.commit.data.author
    committer = p.commit.data.committer

    sender = __get_sender()

    if author.name_email != sender:
        fromauth = 'From: %s\n\n' % author.name_email
    else:
        fromauth = ''

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = text(total_nr)
    patch_nr_str = text(patch_nr).zfill(len(total_nr_str))
    if not options.unrelated and total_nr > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    diff = repository.diff_tree(
        p.commit.data.parent.data.tree,
        p.commit.data.tree,
        diff_opts=options.diff_flags,
    )
    tmpl_dict = {
        'patch': patch,
        'sender': sender,
        'maintainer': sender,  # for backward template compatibility
        'shortdescr': short_descr,
        'longdescr': long_descr,
        'endofheaders': '',  # for backward template compatibility
        'diff': diff,
        'diffstat': diffstat(diff),
        'date': '',  # for backward template compatibility
        'version': version_str,
        'vspace': version_space,
        'prefix': prefix_str,
        'pspace': prefix_space,
        'patchnr': patch_nr_str,
        'totalnr': total_nr_str,
        'number': number_str,
        'nspace': number_space,
        'snumber': number_str.strip(),
        'fromauth': fromauth,
        'authname': author.name,
        'authemail': author.email,
        'authdate': author.date.rfc2822_format(),
        'commname': committer.name,
        'commemail': committer.email,
    }

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

    if options.edit_patches:
        msg_bytes = edit_bytes(msg_bytes, '.stgitmail.txt')

    # The Python email message
    try:
        msg = message_from_bytes(msg_bytes)
    except Exception as ex:
        raise CmdException('template parsing error: %s' % str(ex))

    if options.auto:
        extra_cc = __get_signers_list(descr)
    else:
        extra_cc = []

    if not options.git:
        __build_address_headers(msg, options, extra_cc)
    __build_extra_headers(msg, msg_id, ref_id)
    __encode_message(msg)

    return msg
Ejemplo n.º 17
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()
Ejemplo n.º 18
0
Archivo: mail.py Proyecto: snits/stgit
def __build_cover(tmpl, msg_id, options, patches):
    """Build the cover message (series description) to be sent via SMTP
    """
    sender = __get_sender()

    if options.version:
        version_str = '%s' % options.version
        version_space = ' '
    else:
        version_str = ''
        version_space = ''

    if options.prefix:
        prefix_str = options.prefix
    else:
        prefix_str = config.get('stgit.mail.prefix')
    if prefix_str:
        prefix_space = ' '
    else:
        prefix_str = ''
        prefix_space = ''

    total_nr_str = text(len(patches))
    patch_nr_str = '0'.zfill(len(total_nr_str))
    if len(patches) > 1:
        number_str = '%s/%s' % (patch_nr_str, total_nr_str)
        number_space = ' '
    else:
        number_str = ''
        number_space = ''

    tmpl_dict = {'sender':       sender,
                 # for backward template compatibility
                 'maintainer':   sender,
                 # for backward template compatibility
                 'endofheaders': '',
                 # for backward template compatibility
                 'date':         '',
                 'version':      version_str,
                 'vspace':       version_space,
                 'prefix':       prefix_str,
                 'pspace':       prefix_space,
                 'patchnr':      patch_nr_str,
                 'totalnr':      total_nr_str,
                 'number':       number_str,
                 'nspace':       number_space,
                 'snumber':      number_str.strip(),
                 'shortlog':     stack.shortlog(crt_series.get_patch(p)
                                                for p in reversed(patches)),
                 'diffstat':     gitlib.diffstat(git.diff(
                     rev1 = git_id(crt_series, '%s^' % patches[0]),
                     rev2 = git_id(crt_series, '%s' % patches[-1]),
                     diff_flags = options.diff_flags))}

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

    if options.edit_cover:
        msg_string = __edit_message(msg_string)

    # The Python email message
    try:
        msg = email.message_from_string(msg_string)
    except Exception as ex:
        raise CmdException('template parsing error: %s' % str(ex))

    extra_cc = []
    if options.auto:
        for patch in patches:
            p = crt_series.get_patch(patch)
            if p.get_description():
                descr = p.get_description().strip()
                extra_cc.extend(__get_signers_list(descr))
        extra_cc = list(set(extra_cc))


    if not options.git:
        __build_address_headers(msg, options, extra_cc)
    __build_extra_headers(msg, msg_id, options.in_reply_to)
    __encode_message(msg)

    return msg