Esempio n. 1
0
    def test_rename_file(self):
        tree = self.make_test_tree()

        class RenameFileFixer(Fixer):
            def run(self, basedir, package, *args, **kwargs):
                os.rename(
                    os.path.join(basedir, "debian/control"),
                    os.path.join(basedir, "debian/control.blah"),
                )
                return FixerResult("Renamed a file.")

        orig_basis_tree = tree.branch.basis_tree()
        with tree.lock_write():
            result, summary = run_lintian_fixer(tree,
                                                RenameFileFixer(
                                                    "rename", "some-tag"),
                                                update_changelog=False)
        self.assertEqual(summary, "Renamed a file.")
        self.assertIs(None, result.certainty)
        self.assertEqual([], result.fixed_lintian_tags)
        self.assertEqual(2, tree.branch.revno())
        basis_tree = tree.branch.basis_tree()
        with basis_tree.lock_read(), orig_basis_tree.lock_read():
            self.assertFalse(basis_tree.has_filename("debian/control"))
            self.assertTrue(basis_tree.has_filename("debian/control.blah"))
            self.assertNotEqual(orig_basis_tree.get_revision_id(),
                                basis_tree.get_revision_id())
            self.expectFailure(
                "mv --auto appears to be broken",
                self.assertEqual,
                basis_tree.path2id("debian/control.blah"),
                orig_basis_tree.path2id("debian/control"),
            )
Esempio n. 2
0
    def test_new_file(self):
        tree = self.make_test_tree()

        class NewFileFixer(Fixer):
            def run(self, basedir, package, *args, **kwargs):
                with open(os.path.join(basedir, "debian/somefile"), "w") as f:
                    f.write("test")
                return FixerResult("Created new file.", ["some-tag"])

        with tree.lock_write():
            result, summary = run_lintian_fixer(tree,
                                                NewFileFixer(
                                                    "new-file", "some-tag"),
                                                update_changelog=False)
        self.assertEqual(summary, "Created new file.")
        self.assertIs(None, result.certainty)
        self.assertEqual(["some-tag"], result.fixed_lintian_tags)
        rev = tree.branch.repository.get_revision(tree.last_revision())
        self.assertEqual(
            rev.message,
            ("Created new file.\n"
             "\n"
             "Changes-By: lintian-brush\n"
             "Fixes: lintian: some-tag\n"
             "See-also: https://lintian.debian.org/tags/some-tag.html\n"),
        )
        self.assertEqual(2, tree.branch.revno())
        basis_tree = tree.branch.basis_tree()
        with basis_tree.lock_read():
            self.assertEqual(basis_tree.get_file_text("debian/somefile"),
                             b"test")
Esempio n. 3
0
 def test_simple_modify(self):
     tree = self.make_test_tree()
     with tree.lock_write():
         result, summary = run_lintian_fixer(tree,
                                             DummyFixer(
                                                 "dummy", "some-tag"),
                                             update_changelog=False)
     self.assertEqual(summary, "Fixed some tag.")
     self.assertEqual(["some-tag"], result.fixed_lintian_tags)
     self.assertEqual("certain", result.certainty)
     self.assertEqual(2, tree.branch.revno())
     self.assertEqual(
         tree.get_file_lines("debian/control")[-1], b"a new line\n")
Esempio n. 4
0
 def make_change(self, tree, committer=None):
     with tree.lock_write():
         result, summary = run_lintian_fixer(
             tree,
             DummyFixer("dummy", "some-tag"),
             update_changelog=False,
             committer=committer,
         )
     self.assertEqual(summary, "Fixed some tag.")
     self.assertEqual(["some-tag"], result.fixed_lintian_tags)
     self.assertEqual("certain", result.certainty)
     self.assertEqual(2, tree.branch.revno())
     self.assertEqual(
         tree.get_file_lines("debian/control")[-1], b"a new line\n")
Esempio n. 5
0
    def test_simple_modify_acceptably_uncertain(self):
        tree = self.make_test_tree()

        class UncertainFixer(Fixer):
            def run(self, basedir, package, *args, **kwargs):
                with open(os.path.join(basedir, "debian/somefile"), "w") as f:
                    f.write("test")
                return FixerResult("Renamed a file.", certainty="possible")

        with tree.lock_write():
            result, summary = run_lintian_fixer(
                tree,
                UncertainFixer("dummy", "some-tag"),
                update_changelog=False,
                minimum_certainty="possible",
            )
        self.assertEqual(2, tree.branch.revno())
Esempio n. 6
0
    def test_upstream_change(self):
        tree = self.make_test_tree(version="0.1-1")

        class NewFileFixer(Fixer):
            def run(self, basedir, package, *args, **kwargs):
                with open(os.path.join(basedir, "configure.ac"), "w") as f:
                    f.write("AC_INIT(foo, bar)\n")
                return FixerResult("Created new configure.ac.", [],
                                   patch_name="add-config")

        with tree.lock_write():
            result, summary = run_lintian_fixer(
                tree,
                NewFileFixer("add-config", "add-config"),
                update_changelog=False,
                timestamp=datetime(2020, 9, 8, 0, 36, 35, 857836),
            )
        self.assertEqual(
            summary, "Add patch add-config.patch: Created new configure.ac.")
        self.assertIs(None, result.certainty)
        self.assertEqual([], result.fixed_lintian_tags)
        rev = tree.branch.repository.get_revision(tree.last_revision())
        self.assertEqual(
            rev.message,
            ("Created new configure.ac.\n"
             "\n"
             "Changes-By: lintian-brush\n"),
        )
        self.assertEqual(2, tree.branch.revno())
        basis_tree = tree.branch.basis_tree()
        with basis_tree.lock_read():
            self.assertEqual(basis_tree.get_file_text("debian/patches/series"),
                             b"add-config.patch\n")
            lines = basis_tree.get_file_lines(
                "debian/patches/add-config.patch")
        self.assertEqual(lines[0], b"Description: Created new configure.ac.\n")
        self.assertEqual(lines[1], b"Origin: other\n")
        self.assertEqual(lines[2], b"Last-Update: 2020-09-08\n")
        self.assertEqual(lines[3], b"\n")
        self.assertEqual(lines[4], b"=== added file 'configure.ac'\n")
        self.assertEqual(lines[7], b"@@ -0,0 +1,1 @@\n")
        self.assertEqual(lines[8], b"+AC_INIT(foo, bar)\n")
Esempio n. 7
0
    def make_changes(
        self,
        local_tree,
        subpath,
        update_changelog,
        reporter,
        committer,
        base_proposal=None,
    ):
        from lintian_brush import NoChanges
        from lintian_brush.multiarch_hints import (
            MultiArchHintFixer, )

        base_revid = local_tree.last_revision()
        minimum_certainty = self.minimum_certainty
        allow_reformatting = self.allow_reformatting
        try:
            cfg = Config.from_workingtree(local_tree, subpath)
        except FileNotFoundError:
            pass
        else:
            if minimum_certainty is None:
                minimum_certainty = cfg.minimum_certainty()
            if allow_reformatting is None:
                allow_reformatting = cfg.allow_reformatting()
            if update_changelog is None:
                update_changelog = cfg.update_changelog()

        if control_files_in_root(local_tree, subpath):
            raise ChangerError(
                "control-files-in-root",
                "control files live in root rather than debian/ "
                "(LarstIQ mode)",
            )

        if is_debcargo_package(local_tree, subpath):
            raise ChangerError("nothing-to-do", "Package uses debcargo")
        elif not control_file_present(local_tree, subpath):
            raise ChangerError("missing-control-file",
                               "Unable to find debian/control")

        try:
            with local_tree.lock_write():
                result, summary = run_lintian_fixer(
                    local_tree,
                    MultiArchHintFixer(self.hints),
                    update_changelog=update_changelog,
                    minimum_certainty=minimum_certainty,
                    subpath=subpath,
                    allow_reformatting=allow_reformatting,
                    net_access=True,
                    committer=committer,
                    changes_by="apply-multiarch-hints",
                )
        except NoChanges:
            raise ChangerError("nothing-to-do", "no hints to apply")
        except FormattingUnpreservable as e:
            raise ChangerError(
                "formatting-unpreservable",
                "unable to preserve formatting while editing %s" % e.path,
            )
        except GeneratedFile as e:
            raise ChangerError("generated-file",
                               "unable to edit generated file: %r" % e)

        applied_hints = []
        hint_names = []
        for (binary, hint, description, certainty) in result.changes:
            hint_names.append(hint["link"].split("#")[-1])
            entry = dict(hint.items())
            hint_names.append(entry["link"].split("#")[-1])
            entry["action"] = description
            entry["certainty"] = certainty
            applied_hints.append(entry)
            logging.info("%s: %s" % (binary["Package"], description))

        reporter.report_metadata("applied-hints", applied_hints)

        branches = [("main", None, base_revid, local_tree.last_revision())]

        tags = []

        return ChangerResult(
            description="Applied multi-arch hints.",
            mutator=result,
            branches=branches,
            tags=tags,
            value=calculate_value(hint_names),
            sufficient_for_proposal=True,
            proposed_commit_message="Apply multi-arch hints.",
        )
Esempio n. 8
0
def main(argv=None):  # noqa: C901
    import argparse
    from breezy.workingtree import WorkingTree

    import breezy  # noqa: E402

    breezy.initialize()
    import breezy.git  # noqa: E402
    import breezy.bzr  # noqa: E402

    from .config import Config

    parser = argparse.ArgumentParser(prog="multi-arch-fixer")
    parser.add_argument(
        "--directory",
        metavar="DIRECTORY",
        help="directory to run in",
        type=str,
        default=".",
    )
    parser.add_argument(
        "--disable-inotify", action="store_true", default=False, help=argparse.SUPPRESS
    )
    parser.add_argument(
        "--identity",
        help="Print user identity that would be used when committing",
        action="store_true",
        default=False,
    )
    # Hide the minimum-certainty option for the moment.
    parser.add_argument(
        "--minimum-certainty",
        type=str,
        choices=SUPPORTED_CERTAINTIES,
        default=None,
        help=argparse.SUPPRESS,
    )
    parser.add_argument(
        "--no-update-changelog",
        action="store_false",
        default=None,
        dest="update_changelog",
        help="do not update the changelog",
    )
    parser.add_argument(
        "--update-changelog",
        action="store_true",
        dest="update_changelog",
        help="force updating of the changelog",
        default=None,
    )
    parser.add_argument(
        "--version", action="version", version="%(prog)s " + version_string
    )
    parser.add_argument(
        "--allow-reformatting",
        default=None,
        action="store_true",
        help=argparse.SUPPRESS,
    )

    args = parser.parse_args(argv)

    logging.basicConfig(level=logging.INFO, format='%(message)s')

    minimum_certainty = args.minimum_certainty
    wt, subpath = WorkingTree.open_containing(args.directory)
    if args.identity:
        logging.info('%s', get_committer(wt))
        return 0

    update_changelog = args.update_changelog
    allow_reformatting = args.allow_reformatting
    try:
        cfg = Config.from_workingtree(wt, subpath)
    except FileNotFoundError:
        pass
    else:
        if minimum_certainty is None:
            minimum_certainty = cfg.minimum_certainty()
        if allow_reformatting is None:
            allow_reformatting = cfg.allow_reformatting()
        if update_changelog is None:
            update_changelog = cfg.update_changelog()

    use_inotify = ((False if args.disable_inotify else None),)
    try:
        check_clean_tree(wt, wt.basis_tree(), subpath)
    except WorkspaceDirty:
        logging.info("%s: Please commit pending changes first.", wt.basedir)
        return 1

    dirty_tracker = get_dirty_tracker(wt, subpath, use_inotify)
    if dirty_tracker:
        dirty_tracker.mark_clean()

    with cache_download_multiarch_hints() as f:
        hints = multiarch_hints_by_binary(parse_multiarch_hints(f))

    if control_files_in_root(wt, subpath):
        report_fatal(
            "control-files-in-root",
            "control files live in root rather than debian/ " "(LarstIQ mode)",
        )
        return 1

    if is_debcargo_package(wt, subpath):
        report_okay("nothing-to-do", "Package uses debcargo")
        return 0
    if not control_file_present(wt, subpath):
        report_fatal("missing-control-file", "Unable to find debian/control")
        return 1

    try:
        result, summary = run_lintian_fixer(
            wt,
            MultiArchHintFixer(hints),
            update_changelog=update_changelog,
            minimum_certainty=minimum_certainty,
            dirty_tracker=dirty_tracker,
            subpath=subpath,
            allow_reformatting=allow_reformatting,
            net_access=True,
            changes_by="apply-multiarch-hints",
        )
    except NoChanges:
        report_okay("nothing-to-do", "no hints to apply")
        return 0
    except FormattingUnpreservable as e:
        report_fatal(
            "formatting-unpreservable",
            "unable to preserve formatting while editing %s" % e.path,
        )
        return 1
    except GeneratedFile as e:
        report_fatal(
            "generated-file", "unable to edit generated file: %r" % e)
        return 1
    except NotDebianPackage:
        logging.info("%s: Not a debian package.", wt.basedir)
        return 1
    else:
        applied_hints = []
        hint_names = []
        for (binary, hint, description, certainty) in result.changes:
            hint_names.append(hint["link"].split("#")[-1])
            entry = dict(hint.items())
            hint_names.append(entry["link"].split("#")[-1])
            entry["action"] = description
            entry["certainty"] = certainty
            applied_hints.append(entry)
            logging.info("%s: %s" % (binary["Package"], description))
        if os.environ.get('SVP_API') == '1':
            with open(os.environ['SVP_RESULT'], 'w') as f:
                json.dump({
                    'description': "Applied multi-arch hints.",
                    'value': calculate_value(hint_names),
                    'commit-message': 'Apply multi-arch hints',
                    'context': {
                        'applied-hints': applied_hints,
                    }}, f)