Beispiel #1
0
def move_upstream_changes_to_patch(
    local_tree: WorkingTree,
    basis_tree: Tree,
    subpath: str,
    patch_name: str,
    description: str,
    dirty_tracker=None,
    timestamp: Optional[datetime] = None,
) -> Tuple[List[str], str]:
    """Move upstream changes to patch.

    Args:
      local_tree: local tree
      subpath: subpath
      patch_name: Suggested patch name
      description: Description
      dirty_tracker: Dirty tracker
    """
    if timestamp is None:
        timestamp = datetime.now()
    diff = BytesIO()
    show_diff_trees(basis_tree, local_tree, diff)
    reset_tree(local_tree, basis_tree, subpath, dirty_tracker)
    header = Message()
    lines = description.splitlines()
    # See https://dep-team.pages.debian.net/deps/dep3/ for fields.
    header["Description"] = (lines[0] + "\n" +
                             "\n".join([(" " + line) if line else " ."
                                        for line in lines[1:]]))
    header["Origin"] = "other"
    header["Last-Update"] = timestamp.strftime("%Y-%m-%d")
    patches_directory = tree_patches_directory(local_tree, subpath)
    patchname = add_patch(
        local_tree,
        os.path.join(subpath, patches_directory),
        patch_name,
        diff.getvalue(),
        header,
    )
    specific_files = [
        os.path.join(subpath, patches_directory),
        os.path.join(subpath, patches_directory, "series"),
        os.path.join(subpath, patches_directory, patchname),
    ]
    local_tree.add(specific_files)
    return specific_files, patchname
Beispiel #2
0
    def modify_working_tree(self, tree):
        if 0: tree = WorkingTree()
        # RJLRJL: patched out renames as calls seem to be insoluble
        # and related to a problem with finding the id vs rel_path
        tree.merge_from_branch(self.branch_tree.branch, b'rev-b')

        self.build_tree_contents([
            ('trunk/added', b''),
            ('trunk/addedmissing', b''),
            ('trunk/modified', b'new'),
            ('trunk/unversioned', b''),
        ])
        tree.add(['added'], [b'added-id'])
        tree.add(['addedmissing'], [b'addedmissing-id'])

        # RJLRJL These are the problem omes
        # def rename_one(self, from_rel, to_rel, after=False):
        # """Rename one file.

        # This can change the directory or the filename or both.

        # Second, it can
        # only change the file_id without touching any physical file.

        # rename_one uses the second mode if 'after == True' and 'to_rel' is
        # either not versioned or newly added, and present in the working tree.

        # rename_one uses the second mode if 'after == False' and 'from_rel' is
        # versioned but no longer in the working tree, and 'to_rel' is not
        # versioned but present in the working tree.

        # rename_one uses the first mode if 'after == False' and 'from_rel' is
        # versioned and present in the working tree, and 'to_rel' is not
        # versioned and not present in the working tree.

        # Everything else results in an error.
        # """
        print('\n***Performing rename_one', type(tree))
        tree.rename_one('renamed', 'renamed1')

        print('\n*** doing move')
        tree.move(('moved', ), 'dir')
        print('\n and move and rename')
        tree.rename_one('movedandrenamed', 'movedandrenamed1')
        print('\n and last')
        tree.move(('movedandrenamed1', ), 'dir')
        # RJL

        tree.remove(('removed', ))
        os.remove('trunk/missing')
        os.remove('trunk/addedmissing')

        print('\n --- WARNING BYPASS ---')
        # RJLRJL Bypassed just now
        # # test for https://bugs.launchpad.net/qbrz/+bug/538753
        # # must sort before trunk/dir

        # self.build_tree(['trunk/a-newdir/'])
        # self.build_tree_contents([('trunk/a-newdir/newdirchild', b'')])
        # tree.add(['a-newdir'], [b'a-newdir-id'])
        # tree.add(['a-newdir/newdirchild'], [b'newdirchild-id'])

        # # manuly add conflicts for files that don't exist
        # # See https://bugs.launchpad.net/qbrz/+bug/528548
        # tree.add_conflicts([TextConflict('nofileconflict')])
        # RJLRJL

        print('modify_working_tree done')
Beispiel #3
0
def run_lintian_fixer(  # noqa: C901
    local_tree: WorkingTree,
    fixer: Fixer,
    committer: Optional[str] = None,
    update_changelog: Union[bool, Callable[[], bool]] = True,
    compat_release: Optional[str] = None,
    minimum_certainty: Optional[str] = None,
    trust_package: bool = False,
    allow_reformatting: bool = False,
    dirty_tracker=None,
    subpath: str = "",
    net_access: bool = True,
    opinionated: Optional[bool] = None,
    diligence: int = 0,
    timestamp: Optional[datetime] = None,
    basis_tree: Optional[Tree] = None,
    changes_by: str = "lintian-brush",
):
    """Run a lintian fixer on a tree.

    Args:
      local_tree: WorkingTree object
      basis_tree: Tree
      fixer: Fixer object to apply
      committer: Optional committer (name and email)
      update_changelog: Whether to add a new entry to the changelog
      compat_release: Minimum release that the package should be usable on
        (e.g. 'stable' or 'unstable')
      minimum_certainty: How certain the fixer should be
        about its changes.
      trust_package: Whether to run code from the package if necessary
      allow_reformatting: Whether to allow reformatting of changed files
      dirty_tracker: Optional object that can be used to tell if the tree
        has been changed.
      subpath: Path in tree to operate on
      net_access: Whether to allow accessing external services
      opinionated: Whether to be opinionated
      diligence: Level of diligence
    Returns:
      tuple with set of FixerResult, summary of the changes
    """
    if basis_tree is None:
        basis_tree = local_tree.basis_tree()

    changelog_path = os.path.join(subpath, "debian/changelog")

    try:
        with local_tree.get_file(changelog_path) as f:
            cl = Changelog(f, max_blocks=1)
    except NoSuchFile:
        raise NotDebianPackage(local_tree, subpath)
    package = cl.package
    if cl.distributions == "UNRELEASED":
        current_version = cl.version
    else:
        current_version = cl.version
        increment_version(current_version)
    if compat_release is None:
        compat_release = "sid"
    if minimum_certainty is None:
        minimum_certainty = DEFAULT_MINIMUM_CERTAINTY
    logger.debug('Running fixer %r', fixer)
    try:
        result = fixer.run(
            local_tree.abspath(subpath),
            package=package,
            current_version=current_version,
            compat_release=compat_release,
            minimum_certainty=minimum_certainty,
            trust_package=trust_package,
            allow_reformatting=allow_reformatting,
            net_access=net_access,
            opinionated=opinionated,
            diligence=diligence,
        )
    except BaseException:
        reset_tree(local_tree, basis_tree, subpath, dirty_tracker=dirty_tracker)
        raise
    if not certainty_sufficient(result.certainty, minimum_certainty):
        reset_tree(local_tree, basis_tree, subpath, dirty_tracker=dirty_tracker)
        raise NotCertainEnough(
            fixer, result.certainty, minimum_certainty,
            overridden_lintian_issues=result.overridden_lintian_issues)
    specific_files: Optional[List[str]]
    if dirty_tracker:
        relpaths = dirty_tracker.relpaths()
        # Sort paths so that directories get added before the files they
        # contain (on VCSes where it matters)
        local_tree.add(
            [
                p
                for p in sorted(relpaths)
                if local_tree.has_filename(p) and not local_tree.is_ignored(p)
            ]
        )
        specific_files = [p for p in relpaths if local_tree.is_versioned(p)]
        if not specific_files:
            raise NoChanges(
                fixer, "Script didn't make any changes",
                result.overridden_lintian_issues)
    else:
        local_tree.smart_add([local_tree.abspath(subpath)])
        specific_files = [subpath] if subpath else None

    if local_tree.supports_setting_file_ids():
        RenameMap.guess_renames(basis_tree, local_tree, dry_run=False)

    changes = list(
        local_tree.iter_changes(
            basis_tree,
            specific_files=specific_files,
            want_unversioned=False,
            require_versioned=True,
        )
    )

    if len(local_tree.get_parent_ids()) <= 1 and not changes:
        raise NoChanges(
            fixer, "Script didn't make any changes",
            result.overridden_lintian_issues)

    if not result.description:
        raise DescriptionMissing(fixer)

    lines = result.description.splitlines()
    summary = lines[0]
    details = list(itertools.takewhile(lambda line: line, lines[1:]))

    # If there are upstream changes in a non-native package, perhaps
    # export them to debian/patches
    if has_non_debian_changes(changes, subpath) and current_version.debian_revision:
        try:
            patch_name, specific_files = _upstream_changes_to_patch(
                local_tree,
                basis_tree,
                dirty_tracker,
                subpath,
                result.patch_name or fixer.name,
                result.description,
                timestamp=timestamp,
            )
        except BaseException:
            reset_tree(local_tree, basis_tree, subpath, dirty_tracker=dirty_tracker)
            raise

        summary = "Add patch %s: %s" % (patch_name, summary)

    if only_changes_last_changelog_block(
        local_tree, basis_tree, changelog_path, changes
    ):
        # If the script only changed the last entry in the changelog,
        # don't update the changelog
        update_changelog = False

    if callable(update_changelog):
        update_changelog = update_changelog()

    if update_changelog:
        from .changelog import add_changelog_entry

        add_changelog_entry(local_tree, changelog_path, [summary] + details)
        if specific_files:
            specific_files.append(changelog_path)

    description = result.description + "\n"
    description += "\n"
    description += "Changes-By: %s\n" % changes_by
    for tag in result.fixed_lintian_tags:
        description += "Fixes: lintian: %s\n" % tag
        description += "See-also: https://lintian.debian.org/tags/%s.html\n" % tag

    if committer is None:
        committer = get_committer(local_tree)

    revid = local_tree.commit(
        description,
        allow_pointless=False,
        reporter=NullCommitReporter(),
        committer=committer,
        specific_files=specific_files,
    )
    result.revision_id = revid
    # TODO(jelmer): Support running sbuild & verify lintian warning is gone?
    return result, summary