Exemplo n.º 1
0
    def items(self, section, *args, **kwargs):
        """Extend SafeConfigParser to add project_section to section.

        Args:
            See SafeConfigParser.
        Returns:
            See SafeConfigParser.
        """
        project_items = []
        has_project_section = False
        top_items = []

        # Get items from the project section
        try:
            project_items = ConfigParser.SafeConfigParser.items(
                self, "%s_%s" % (self._project_name, section), *args, **kwargs)
            has_project_section = True
        except ConfigParser.NoSectionError:
            pass

        # Get top-level items
        try:
            top_items = ConfigParser.SafeConfigParser.items(
                self, section, *args, **kwargs)
        except ConfigParser.NoSectionError:
            # If neither section exists raise the error on...
            if not has_project_section:
                raise

        item_dict = dict(top_items)
        item_dict.update(project_items)
        return {(tools.ToUnicode(item), tools.ToUnicode(val))
                for item, val in item_dict.items()}
Exemplo n.º 2
0
    def MakeCcFile(self, process_tags, cover_fname, raise_on_error,
                   add_maintainers, limit):
        """Make a cc file for us to use for per-commit Cc automation

        Also stores in self._generated_cc to make ShowActions() faster.

        Args:
            process_tags: Process tags as if they were aliases
            cover_fname: If non-None the name of the cover letter.
            raise_on_error: True to raise an error when an alias fails to match,
                False to just print a message.
            add_maintainers: Either:
                True/False to call the get_maintainers to CC maintainers
                List of maintainers to include (for testing)
            limit: Limit the length of the Cc list (None if no limit)
        Return:
            Filename of temp file created
        """
        col = terminal.Color()
        # Look for commit tags (of the form 'xxx:' at the start of the subject)
        fname = '/tmp/patman.%d' % os.getpid()
        fd = open(fname, 'w', encoding='utf-8')
        all_ccs = []
        for commit in self.commits:
            cc = []
            if process_tags:
                cc += gitutil.BuildEmailList(commit.tags,
                                             raise_on_error=raise_on_error)
            cc += gitutil.BuildEmailList(commit.cc_list,
                                         raise_on_error=raise_on_error)
            if type(add_maintainers) == type(cc):
                cc += add_maintainers
            elif add_maintainers:
                dir_list = [os.path.join(gitutil.GetTopLevel(), 'scripts')]
                cc += get_maintainer.GetMaintainer(dir_list, commit.patch)
            for x in set(cc) & set(settings.bounces):
                print(col.Color(col.YELLOW, 'Skipping "%s"' % x))
            cc = set(cc) - set(settings.bounces)
            cc = [tools.FromUnicode(m) for m in cc]
            if limit is not None:
                cc = cc[:limit]
            all_ccs += cc
            print(commit.patch, '\0'.join(sorted(set(cc))), file=fd)
            self._generated_cc[commit.patch] = cc

        if cover_fname:
            cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
            cover_cc = [tools.FromUnicode(m) for m in cover_cc]
            cover_cc = list(set(cover_cc + all_ccs))
            if limit is not None:
                cover_cc = cover_cc[:limit]
            cc_list = '\0'.join([tools.ToUnicode(x) for x in sorted(cover_cc)])
            print(cover_fname, cc_list, file=fd)

        fd.close()
        return fname
Exemplo n.º 3
0
    def get(self, section, option, *args, **kwargs):
        """Extend SafeConfigParser to try project_section before section.

        Args:
            See SafeConfigParser.
        Returns:
            See SafeConfigParser.
        """
        try:
            val = ConfigParser.SafeConfigParser.get(
                self, "%s_%s" % (self._project_name, section), option, *args,
                **kwargs)
        except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
            val = ConfigParser.SafeConfigParser.get(self, section, option,
                                                    *args, **kwargs)
        return tools.ToUnicode(val)
Exemplo n.º 4
0
    def testBasic(self):
        """Tests the basic flow of patman

        This creates a series from some hard-coded patches build from a simple
        tree with the following metadata in the top commit:

            Series-to: u-boot
            Series-prefix: RFC
            Series-cc: Stefan Brüns <*****@*****.**>
            Cover-letter-cc: Lord Mëlchett <*****@*****.**>
            Series-version: 3
            Patch-cc: fred
            Series-process-log: sort, uniq
            Series-changes: 4
            - Some changes
            - Multi
              line
              change

            Commit-changes: 2
            - Changes only for this commit

            Cover-changes: 4
            - Some notes for the cover letter

            Cover-letter:
            test: A test patch series
            This is a test of how the cover
            letter
            works
            END

        and this in the first commit:

            Commit-changes: 2
            - second revision change

            Series-notes:
            some notes
            about some things
            from the first commit
            END

            Commit-notes:
            Some notes about
            the first commit
            END

        with the following commands:

           git log -n2 --reverse >/path/to/tools/patman/test/test01.txt
           git format-patch --subject-prefix RFC --cover-letter HEAD~2
           mv 00* /path/to/tools/patman/test

        It checks these aspects:
            - git log can be processed by patchstream
            - emailing patches uses the correct command
            - CC file has information on each commit
            - cover letter has the expected text and subject
            - each patch has the correct subject
            - dry-run information prints out correctly
            - unicode is handled correctly
            - Series-to, Series-cc, Series-prefix, Cover-letter
            - Cover-letter-cc, Series-version, Series-changes, Series-notes
            - Commit-notes
        """
        process_tags = True
        ignore_bad_tags = True
        stefan = b'Stefan Br\xc3\xbcns <*****@*****.**>'.decode(
            'utf-8')
        rick = 'Richard III <*****@*****.**>'
        mel = b'Lord M\xc3\xablchett <*****@*****.**>'.decode('utf-8')
        add_maintainers = [stefan, rick]
        dry_run = True
        in_reply_to = mel
        count = 2
        settings.alias = {
            'fdt': ['simon'],
            'u-boot': ['*****@*****.**'],
            'simon': [self.leb],
            'fred': [self.fred],
        }

        text = self._get_text('test01.txt')
        series = patchstream.get_metadata_for_test(text)
        cover_fname, args = self._create_patches_for_test(series)
        with capture_sys_output() as out:
            patchstream.fix_patches(series, args)
            if cover_fname and series.get('cover'):
                patchstream.insert_cover_letter(cover_fname, series, count)
            series.DoChecks()
            cc_file = series.MakeCcFile(process_tags, cover_fname,
                                        not ignore_bad_tags, add_maintainers,
                                        None)
            cmd = gitutil.EmailPatches(series,
                                       cover_fname,
                                       args,
                                       dry_run,
                                       not ignore_bad_tags,
                                       cc_file,
                                       in_reply_to=in_reply_to,
                                       thread=None)
            series.ShowActions(args, cmd, process_tags)
        cc_lines = open(cc_file, encoding='utf-8').read().splitlines()
        os.remove(cc_file)

        lines = iter(out[0].getvalue().splitlines())
        self.assertEqual('Cleaned %s patches' % len(series.commits),
                         next(lines))
        self.assertEqual('Change log missing for v2', next(lines))
        self.assertEqual('Change log missing for v3', next(lines))
        self.assertEqual('Change log for unknown version v4', next(lines))
        self.assertEqual("Alias 'pci' not found", next(lines))
        self.assertIn('Dry run', next(lines))
        self.assertEqual('', next(lines))
        self.assertIn('Send a total of %d patches' % count, next(lines))
        prev = next(lines)
        for i, commit in enumerate(series.commits):
            self.assertEqual('   %s' % args[i], prev)
            while True:
                prev = next(lines)
                if 'Cc:' not in prev:
                    break
        self.assertEqual('To:	  [email protected]', prev)
        self.assertEqual('Cc:	  %s' % tools.FromUnicode(stefan), next(lines))
        self.assertEqual('Version:  3', next(lines))
        self.assertEqual('Prefix:\t  RFC', next(lines))
        self.assertEqual('Cover: 4 lines', next(lines))
        self.assertEqual('      Cc:  %s' % self.fred, next(lines))
        self.assertEqual('      Cc:  %s' % tools.FromUnicode(self.leb),
                         next(lines))
        self.assertEqual('      Cc:  %s' % tools.FromUnicode(mel), next(lines))
        self.assertEqual('      Cc:  %s' % rick, next(lines))
        expected = ('Git command: git send-email --annotate '
                    '--in-reply-to="%s" --to "*****@*****.**" '
                    '--cc "%s" --cc-cmd "%s --cc-cmd %s" %s %s' %
                    (in_reply_to, stefan, sys.argv[0], cc_file, cover_fname,
                     ' '.join(args)))
        self.assertEqual(expected, tools.ToUnicode(next(lines)))

        self.assertEqual(('%s %s\0%s' % (args[0], rick, stefan)),
                         tools.ToUnicode(cc_lines[0]))
        self.assertEqual(
            '%s %s\0%s\0%s\0%s' % (args[1], self.fred, self.leb, rick, stefan),
            tools.ToUnicode(cc_lines[1]))

        expected = '''
This is a test of how the cover
letter
works

some notes
about some things
from the first commit

Changes in v4:
- Multi
  line
  change
- Some changes
- Some notes for the cover letter

Simon Glass (2):
  pci: Correct cast for sandbox
  fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base()

 cmd/pci.c                   | 3 ++-
 fs/fat/fat.c                | 1 +
 lib/efi_loader/efi_memory.c | 1 +
 lib/fdtdec.c                | 3 ++-
 4 files changed, 6 insertions(+), 2 deletions(-)

--\x20
2.7.4

'''
        lines = open(cover_fname, encoding='utf-8').read().splitlines()
        self.assertEqual(
            'Subject: [RFC PATCH v3 0/2] test: A test patch series', lines[3])
        self.assertEqual(expected.splitlines(), lines[7:])

        for i, fname in enumerate(args):
            lines = open(fname, encoding='utf-8').read().splitlines()
            subject = [line for line in lines if line.startswith('Subject')]
            self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
                             subject[0][:18])

            # Check that we got our commit notes
            start = 0
            expected = ''

            if i == 0:
                start = 17
                expected = '''---
Some notes about
the first commit

(no changes since v2)

Changes in v2:
- second revision change'''
            elif i == 1:
                start = 17
                expected = '''---

Changes in v4:
- Multi
  line
  change
- Some changes

Changes in v2:
- Changes only for this commit'''

            if expected:
                expected = expected.splitlines()
                self.assertEqual(expected,
                                 lines[start:(start + len(expected))])
Exemplo n.º 5
0
    def testBasic(self):
        """Tests the basic flow of patman

        This creates a series from some hard-coded patches build from a simple
        tree with the following metadata in the top commit:

            Series-to: u-boot
            Series-prefix: RFC
            Series-cc: Stefan Brüns <*****@*****.**>
            Cover-letter-cc: Lord Mëlchett <*****@*****.**>
            Series-version: 2
            Series-changes: 4
            - Some changes

            Cover-letter:
            test: A test patch series
            This is a test of how the cover
            leter
            works
            END

        and this in the first commit:

            Series-notes:
            some notes
            about some things
            from the first commit
            END

            Commit-notes:
            Some notes about
            the first commit
            END

        with the following commands:

           git log -n2 --reverse >/path/to/tools/patman/test/test01.txt
           git format-patch --subject-prefix RFC --cover-letter HEAD~2
           mv 00* /path/to/tools/patman/test

        It checks these aspects:
            - git log can be processed by patchstream
            - emailing patches uses the correct command
            - CC file has information on each commit
            - cover letter has the expected text and subject
            - each patch has the correct subject
            - dry-run information prints out correctly
            - unicode is handled correctly
            - Series-to, Series-cc, Series-prefix, Cover-letter
            - Cover-letter-cc, Series-version, Series-changes, Series-notes
            - Commit-notes
        """
        process_tags = True
        ignore_bad_tags = True
        stefan = b'Stefan Br\xc3\xbcns <*****@*****.**>'.decode(
            'utf-8')
        rick = 'Richard III <*****@*****.**>'
        mel = b'Lord M\xc3\xablchett <*****@*****.**>'.decode('utf-8')
        ed = b'Lond Edmund Blackadd\xc3\xabr <*****@*****.**'.decode(
            'utf-8')
        fred = 'Fred Bloggs <*****@*****.**>'
        add_maintainers = [stefan, rick]
        dry_run = True
        in_reply_to = mel
        count = 2
        settings.alias = {
            'fdt': ['simon'],
            'u-boot': ['*****@*****.**'],
            'simon': [ed],
            'fred': [fred],
        }

        text = self.GetText('test01.txt')
        series = patchstream.GetMetaDataForTest(text)
        cover_fname, args = self.CreatePatchesForTest(series)
        with capture() as out:
            patchstream.FixPatches(series, args)
            if cover_fname and series.get('cover'):
                patchstream.InsertCoverLetter(cover_fname, series, count)
            series.DoChecks()
            cc_file = series.MakeCcFile(process_tags, cover_fname,
                                        not ignore_bad_tags, add_maintainers,
                                        None)
            cmd = gitutil.EmailPatches(series,
                                       cover_fname,
                                       args,
                                       dry_run,
                                       not ignore_bad_tags,
                                       cc_file,
                                       in_reply_to=in_reply_to,
                                       thread=None)
            series.ShowActions(args, cmd, process_tags)
        cc_lines = open(cc_file, encoding='utf-8').read().splitlines()
        os.remove(cc_file)

        lines = out[0].splitlines()
        self.assertEqual('Cleaned %s patches' % len(series.commits), lines[0])
        self.assertEqual('Change log missing for v2', lines[1])
        self.assertEqual('Change log missing for v3', lines[2])
        self.assertEqual('Change log for unknown version v4', lines[3])
        self.assertEqual("Alias 'pci' not found", lines[4])
        self.assertIn('Dry run', lines[5])
        self.assertIn('Send a total of %d patches' % count, lines[7])
        line = 8
        for i, commit in enumerate(series.commits):
            self.assertEqual('   %s' % args[i], lines[line + 0])
            line += 1
            while 'Cc:' in lines[line]:
                line += 1
        self.assertEqual('To:	  [email protected]', lines[line])
        self.assertEqual('Cc:	  %s' % tools.FromUnicode(stefan),
                         lines[line + 1])
        self.assertEqual('Version:  3', lines[line + 2])
        self.assertEqual('Prefix:\t  RFC', lines[line + 3])
        self.assertEqual('Cover: 4 lines', lines[line + 4])
        line += 5
        self.assertEqual('      Cc:  %s' % fred, lines[line + 0])
        self.assertEqual('      Cc:  %s' % tools.FromUnicode(ed),
                         lines[line + 1])
        self.assertEqual('      Cc:  %s' % tools.FromUnicode(mel),
                         lines[line + 2])
        self.assertEqual('      Cc:  %s' % rick, lines[line + 3])
        expected = ('Git command: git send-email --annotate '
                    '--in-reply-to="%s" --to "*****@*****.**" '
                    '--cc "%s" --cc-cmd "%s --cc-cmd %s" %s %s' %
                    (in_reply_to, stefan, sys.argv[0], cc_file, cover_fname,
                     ' '.join(args)))
        line += 4
        self.assertEqual(expected, tools.ToUnicode(lines[line]))

        self.assertEqual(('%s %s\0%s' % (args[0], rick, stefan)),
                         tools.ToUnicode(cc_lines[0]))
        self.assertEqual(
            ('%s %s\0%s\0%s\0%s' % (args[1], fred, ed, rick, stefan)),
            tools.ToUnicode(cc_lines[1]))

        expected = '''
This is a test of how the cover
leter
works

some notes
about some things
from the first commit

Changes in v4:
- Some changes

Simon Glass (2):
  pci: Correct cast for sandbox
  fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base()

 cmd/pci.c                   | 3 ++-
 fs/fat/fat.c                | 1 +
 lib/efi_loader/efi_memory.c | 1 +
 lib/fdtdec.c                | 3 ++-
 4 files changed, 6 insertions(+), 2 deletions(-)

--\x20
2.7.4

'''
        lines = open(cover_fname, encoding='utf-8').read().splitlines()
        self.assertEqual(
            'Subject: [RFC PATCH v3 0/2] test: A test patch series', lines[3])
        self.assertEqual(expected.splitlines(), lines[7:])

        for i, fname in enumerate(args):
            lines = open(fname, encoding='utf-8').read().splitlines()
            subject = [line for line in lines if line.startswith('Subject')]
            self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
                             subject[0][:18])
            if i == 0:
                # Check that we got our commit notes
                self.assertEqual('---', lines[17])
                self.assertEqual('Some notes about', lines[18])
                self.assertEqual('the first commit', lines[19])