コード例 #1
0
    def test_diff_inject_start_line(self):
        patch = PatchHelper(
            io.BytesIO("""
# HG changeset patch
# User byron jones <*****@*****.**>
# Date 1523427125 -28800
#      Wed Apr 11 14:12:05 2018 +0800
# Node ID 3379ea3cea34ecebdcb2cf7fb9f7845861ea8f07
# Parent  46c36c18528fe2cc780d5206ed80ae8e37d3545d
# Diff Start Line 14
WIP transplant and diff-start-line

diff --git a/bad b/bad
@@ -0,0 +0,0 @@
blah

diff --git a/autoland/autoland/transplant.py b/autoland/autoland/transplant.py
--- a/autoland/autoland/transplant.py
+++ b/autoland/autoland/transplant.py
@@ -318,24 +318,58 @@ class PatchTransplant(Transplant):
# instead of passing the url to 'hg import' to make
...
""".strip()))

        self.assertEqual(
            patch.commit_description(), 'WIP transplant and diff-start-line\n'
            '\n'
            'diff --git a/bad b/bad\n'
            '@@ -0,0 +0,0 @@\n'
            'blah')
コード例 #2
0
    def _apply_patch_from_io_buff(self, io_buf):
        patch = PatchHelper(io_buf)

        if patch.header('Diff Start Line'):
            with tempfile.NamedTemporaryFile() as desc_temp, \
                    tempfile.NamedTemporaryFile() as diff_temp:
                patch.write_commit_description(desc_temp)
                desc_temp.flush()
                patch.write_diff(diff_temp)
                diff_temp.flush()

                # Import then commit to ensure correct parsing of the
                # commit description.

                # Apply the patch, with file rename detection (similarity).
                # Using 95 as the similarity to match automv's default.
                self.run_hg(
                    ['import', '-s', '95', '--no-commit', diff_temp.name])

                # Commit using the extracted date, user, and commit desc.
                self.run_hg([
                    'commit', '--date',
                    patch.header('Date'), '--user',
                    patch.header('User'), '--logfile', desc_temp.name
                ])

        else:
            with tempfile.NamedTemporaryFile() as temp_file:
                patch.write(temp_file)
                temp_file.flush()

                # Apply the patch, with file rename detection (similarity).
                # Using 95 as the similarity to match automv's default.
                self.run_hg(['import', '-s', '95', temp_file.name])
コード例 #3
0
    def test_no_header(self):
        patch = PatchHelper(
            io.BytesIO("""
WIP transplant and diff-start-line

diff --git a/autoland/autoland/transplant.py b/autoland/autoland/transplant.py
--- a/autoland/autoland/transplant.py
+++ b/autoland/autoland/transplant.py
@@ -318,24 +318,58 @@ class PatchTransplant(Transplant):
# instead of passing the url to 'hg import' to make
...
""".strip()))

        self.assertIsNone(patch.header('User'))

        self.assertEqual(patch.commit_description(),
                         'WIP transplant and diff-start-line')
コード例 #4
0
    def _apply_patch_from_io_buff(self, io_buf):
        patch = PatchHelper(io_buf)

        # In production we require each patch to require a `Diff Start Line` header.
        # In test this is tricky because mercurial doesn't generate this header.
        if not config.testing() and not patch.diff_start_line:
            raise Exception("invalid patch: missing `Diff Start Line` header")

        # Import then commit to ensure correct parsing of the
        # commit description.
        desc_temp = tempfile.NamedTemporaryFile()
        diff_temp = tempfile.NamedTemporaryFile()
        with desc_temp, diff_temp:
            patch.write_commit_description(desc_temp)
            desc_temp.flush()
            patch.write_diff(diff_temp)
            diff_temp.flush()

            # Apply the patch, with file rename detection (similarity).
            # Using 95 as the similarity to match automv's default.
            #
            # XXX Using `hg import` here is less than ideal because it isn't
            # using a 3-way merge. It would be better to use
            # `hg import --exact` then `hg rebase`, however we aren't
            # guaranteed to have the changeset's parent in the local repo.
            self.run_hg(['import', '-s', '95', '--no-commit', diff_temp.name])

            # Commit using the extracted date, user, and commit desc.
            # --landing_system is provided by the set_landing_system hgext.
            self.run_hg([
                'commit', '--date',
                patch.header('Date'), '--user',
                patch.header('User'), '--landing_system',
                self.landing_system_id, '--logfile', desc_temp.name
            ])
コード例 #5
0
    def test_vanilla(self):
        patch = PatchHelper(
            io.BytesIO("""
# HG changeset patch
# User byron jones <*****@*****.**>
# Date 1523427125 -28800
#      Wed Apr 11 14:12:05 2018 +0800
# Node ID 3379ea3cea34ecebdcb2cf7fb9f7845861ea8f07
# Parent  46c36c18528fe2cc780d5206ed80ae8e37d3545d
WIP transplant and diff-start-line

diff --git a/autoland/autoland/transplant.py b/autoland/autoland/transplant.py
--- a/autoland/autoland/transplant.py
+++ b/autoland/autoland/transplant.py
@@ -318,24 +318,58 @@ class PatchTransplant(Transplant):
# instead of passing the url to 'hg import' to make
...
""".strip()))

        self.assertEqual(patch.header('Date'), '1523427125 -28800')
        self.assertEqual(patch.header('Node ID'),
                         '3379ea3cea34ecebdcb2cf7fb9f7845861ea8f07')
        self.assertEqual(patch.header('User'),
                         'byron jones <*****@*****.**>')
        self.assertEqual(patch.header('Parent'),
                         '46c36c18528fe2cc780d5206ed80ae8e37d3545d')

        self.assertEqual(patch.commit_description(),
                         'WIP transplant and diff-start-line')
コード例 #6
0
 def test_is_diff_line(self):
     self.assertTrue(PatchHelper._is_diff_line('diff --git a/file b/file'))
     self.assertTrue(PatchHelper._is_diff_line('diff a/file b/file'))
     self.assertTrue(
         PatchHelper._is_diff_line(
             'diff -r 23280edf8655 autoland/autoland/patch_helper.py'))
     self.assertFalse(PatchHelper._is_diff_line('cheese'))
     self.assertFalse(PatchHelper._is_diff_line('diff'))
     self.assertFalse(PatchHelper._is_diff_line('diff '))
     self.assertFalse(PatchHelper._is_diff_line('diff file'))
コード例 #7
0
    def test_write_no_start_line(self):
        header = """
# HG changeset patch
# User byron jones <*****@*****.**>
# Date 1523427125 -28800
#      Wed Apr 11 14:12:05 2018 +0800
# Node ID 3379ea3cea34ecebdcb2cf7fb9f7845861ea8f07
# Parent  46c36c18528fe2cc780d5206ed80ae8e37d3545d
""".strip()
        commit_desc = """
WIP transplant and diff-start-line
""".strip()
        diff = """
diff --git a/autoland/autoland/transplant.py b/autoland/autoland/transplant.py
--- a/autoland/autoland/transplant.py
+++ b/autoland/autoland/transplant.py
@@ -318,24 +318,58 @@ class PatchTransplant(Transplant):
# instead of passing the url to 'hg import' to make
...
""".strip()
        patch = PatchHelper(
            io.BytesIO('%s\n%s\n\n%s' % (header, commit_desc, diff)))

        buf = io.BytesIO('')
        patch.write_commit_description(buf)
        self.assertEqual(buf.getvalue(), commit_desc)

        buf = io.BytesIO('')
        patch.write_diff(buf)
        self.assertEqual(buf.getvalue(), diff)
コード例 #8
0
    def _apply_patch_from_io_buff(self, io_buf):
        patch = PatchHelper(io_buf)

        # In production we require each patch to require a `Diff Start Line` header.
        # In test this is tricky because mercurial doesn't generate this header.
        if not config.testing() and not patch.diff_start_line:
            raise Exception("invalid patch: missing `Diff Start Line` header")

        # Import then commit to ensure correct parsing of the
        # commit description.
        desc_temp = tempfile.NamedTemporaryFile()
        diff_temp = tempfile.NamedTemporaryFile()
        with desc_temp, diff_temp:
            patch.write_commit_description(desc_temp)
            desc_temp.flush()
            patch.write_diff(diff_temp)
            diff_temp.flush()

            # XXX Using `hg import` here is less than ideal because it isn't
            # using a 3-way merge. It would be better to use
            # `hg import --exact` then `hg rebase`, however we aren't
            # guaranteed to have the changeset's parent in the local repo.

            try:
                # Fall back to 'patch' if hg's internal code fails (to work around
                # hg bugs/limitations).

                # In tests if the patch contains a 'Fail HG Import' header we simulate
                # a failure from hg's internal code.
                if config.testing() and patch.header("Fail HG Import"):
                    logger.info("testing: forcing patch fallback")

                    # Create junk to ensure it gets cleaned up.
                    import glob

                    filename = [
                        f for f in glob.glob("%s/*" % self.path)
                        if os.path.isfile(f)
                    ][0]
                    with open(filename, "w") as f:
                        f.write("junk\n")

                    raise Exception(
                        "1 out of 1 hunk FAILED -- saving rejects to file")

                # Apply the patch, with file rename detection (similarity).
                # Using 95 as the similarity to match automv's default.
                self.run_hg(
                    ["import", "-s", "95", "--no-commit", diff_temp.name])

            except Exception as e:
                msg = str(e)
                if ("hunk FAILED -- saving rejects to file" in msg
                        or "hunks FAILED -- saving rejects to file" in msg):
                    # Try again using 'patch' instead of hg's internal patch utility.

                    # But first reset to a clean repo as hg's attempt might have
                    # been partially applied.
                    self.clean_repo(strip_non_public_commits=False)

                    logger.info("import failed, trying with 'patch': %s" % e)
                    try:
                        self.run_hg(["import"] + ["-s", "95"] +
                                    ["--no-commit"] +
                                    ["--config", "ui.patch=patch"] +
                                    [diff_temp.name])
                        # When using an external patch util mercurial won't
                        # automatically handle add/remove/renames.
                        self.run_hg(["addremove", "-s", "95"])
                    except hglib.error.CommandError as hg_error:
                        raise Exception(hg_error.out)
                else:
                    raise

            # Commit using the extracted date, user, and commit desc.
            # --landing_system is provided by the set_landing_system hgext.
            self.run_hg(["commit"] + ["--date", patch.header("Date")] +
                        ["--user", patch.header("User")] +
                        ["--landing_system", self.landing_system_id] +
                        ["--logfile", desc_temp.name])