Exemplo n.º 1
0
    def sync_from_downstream(
        self,
        dist_git_branch: str,
        upstream_branch: str,
        no_pr: bool = False,
        fork: bool = True,
        remote_name: str = None,
    ):
        """
        Sync content of Fedora dist-git repo back to upstream

        :param dist_git_branch: branch in dist-git
        :param upstream_branch: upstream branch
        :param no_pr: won't create a pull request if set to True
        :param fork: forks the project if set to True
        :param remote_name: name of remote where we should push; if None, try to find a ssh_url
        """
        logger.info(f"upstream active branch {self.up.active_branch}")

        self.dg.update_branch(dist_git_branch)
        self.dg.checkout_branch(dist_git_branch)

        local_pr_branch = f"{dist_git_branch}-downstream-sync"
        logger.info(f'using "{dist_git_branch}" dist-git branch')

        self.up.create_branch(local_pr_branch)
        self.up.checkout_branch(local_pr_branch)

        sync_files(
            self.package_config.synced_files.raw_files_to_sync,
            self.dg.local_project.working_dir,
            self.up.local_project.working_dir,
        )

        if not no_pr:
            description = (
                f"Downstream commit: {self.dg.local_project.git_repo.head.commit}\n"
            )

            commit_msg = f"sync from downstream branch {dist_git_branch!r}"
            pr_title = f"Update from downstream branch {dist_git_branch!r}"

            self.up.commit(title=commit_msg, msg=description)

            # the branch may already be up, let's push forcefully
            source_branch = self.up.push(
                self.up.local_project.ref,
                fork=fork,
                force=True,
                remote_name=remote_name,
            )
            self.up.create_pull(
                pr_title,
                description,
                source_branch=source_branch,
                target_branch=upstream_branch,
            )
Exemplo n.º 2
0
    def sync_pr(self,
                pr_id,
                dist_git_branch: str,
                upstream_version: str = None):
        assert_existence(self.dg.local_project)
        # do not add anything between distgit clone and saving gpg keys!
        self.up.allowed_gpg_keys = self.dg.get_allowed_gpg_keys_from_downstream_config(
        )

        self.up.run_action(actions=ActionName.pre_sync)

        self.up.checkout_pr(pr_id=pr_id)
        self.dg.check_last_commit()

        local_pr_branch = f"pull-request-{pr_id}-sync"
        # fetch and reset --hard upstream/$branch?
        self.dg.create_branch(
            dist_git_branch,
            base=f"remotes/origin/{dist_git_branch}",
            setup_tracking=True,
        )

        self.dg.update_branch(dist_git_branch)
        self.dg.checkout_branch(dist_git_branch)

        self.dg.create_branch(local_pr_branch)
        self.dg.checkout_branch(local_pr_branch)

        if self.up.with_action(action=ActionName.create_patches):
            patches = self.up.create_patches(
                upstream=upstream_version,
                destination=str(self.dg.absolute_specfile_dir),
            )
            self.dg.add_patches_to_specfile(patches)

        description = (
            f"Upstream pr: {pr_id}\n"
            f"Upstream commit: {self.up.local_project.git_repo.head.commit}\n")

        self._handle_sources(add_new_sources=True, force_new_sources=False)

        raw_sync_files = self.package_config.synced_files.get_raw_files_to_sync(
            Path(self.up.local_project.working_dir),
            Path(self.dg.local_project.working_dir),
        )
        sync_files(raw_sync_files)

        self.dg.commit(title=f"Sync upstream pr: {pr_id}", msg=description)

        self.push_and_create_pr(
            pr_title=f"Upstream pr: {pr_id}",
            pr_description=description,
            dist_git_branch="master",
        )
Exemplo n.º 3
0
    def sync_pr(self,
                pr_id,
                dist_git_branch: str,
                upstream_version: str = None):
        self.up.run_action(action=ActionName.pre_sync)

        self.up.checkout_pr(pr_id=pr_id)
        local_pr_branch = f"pull-request-{pr_id}-sync"
        # fetch and reset --hard upstream/$branch?
        self.dg.create_branch(
            dist_git_branch,
            base=f"remotes/origin/{dist_git_branch}",
            setup_tracking=True,
        )

        self.dg.update_branch(dist_git_branch)
        self.dg.checkout_branch(dist_git_branch)

        self.dg.create_branch(local_pr_branch)
        self.dg.checkout_branch(local_pr_branch)

        if self.up.with_action(action=ActionName.create_patches):
            patches = self.up.create_patches(
                upstream=upstream_version,
                destination=self.dg.local_project.working_dir)
            self.dg.add_patches_to_specfile(patches)

        description = (
            f"Upstream pr: {pr_id}\n"
            f"Upstream commit: {self.up.local_project.git_repo.head.commit}\n")

        self._handle_sources(add_new_sources=True, force_new_sources=False)

        sync_files(
            self.package_config.synced_files.raw_files_to_sync,
            self.up.local_project.working_dir,
            self.dg.local_project.working_dir,
        )
        self.dg.commit(title=f"Sync upstream pr: {pr_id}", msg=description)

        self.push_and_create_pr(
            pr_title=f"Upstream pr: {pr_id}",
            pr_description=description,
            dist_git_branch="master",
        )
Exemplo n.º 4
0
    def sync_from_downstream(
        self,
        dist_git_branch: str,
        upstream_branch: str,
        no_pr: bool = False,
        fork: bool = True,
        remote_name: str = None,
        exclude_files: Iterable[str] = None,
        force: bool = False,
    ):
        """
        Sync content of Fedora dist-git repo back to upstream

        :param exclude_files: files that will be excluded from the sync
        :param dist_git_branch: branch in dist-git
        :param upstream_branch: upstream branch
        :param no_pr: won't create a pull request if set to True
        :param fork: forks the project if set to True
        :param remote_name: name of remote where we should push; if None, try to find a ssh_url
        :param force: ignore changes in the git index
        """
        exclude_files = exclude_files or []
        if not dist_git_branch:
            raise PackitException("Dist-git branch is not set.")
        if not upstream_branch:
            raise PackitException("Upstream branch is not set.")
        logger.info(f"Upstream active branch: {self.up.active_branch}")

        if not force and self.up.is_dirty():
            raise PackitException(
                "The repository is dirty, will not discard the changes. Use --force to bypass."
            )
        self.dg.update_branch(dist_git_branch)
        self.dg.checkout_branch(dist_git_branch)

        logger.info(f"Using {dist_git_branch!r} dist-git branch.")

        if no_pr:
            self.up.checkout_branch(upstream_branch)
        else:
            local_pr_branch = f"{dist_git_branch}-downstream-sync"
            self.up.create_branch(local_pr_branch)
            self.up.checkout_branch(local_pr_branch)

        raw_sync_files = self.package_config.synced_files.get_raw_files_to_sync(
            dest_dir=Path(self.dg.local_project.working_dir),
            src_dir=Path(self.up.local_project.working_dir),
        )

        reverse_raw_sync_files = [
            raw_file.reversed() for raw_file in raw_sync_files
            if Path(raw_file.dest).name not in exclude_files
        ]
        sync_files(reverse_raw_sync_files, fail_on_missing=False)

        if not no_pr:
            description = f"Downstream commit: {self.dg.local_project.commit_hexsha}\n"

            commit_msg = f"Sync from downstream branch {dist_git_branch!r}"
            pr_title = f"Update from downstream branch {dist_git_branch!r}"

            self.up.commit(title=commit_msg, msg=description)

            # the branch may already be up, let's push forcefully
            source_branch, fork_username = self.up.push_to_fork(
                self.up.local_project.ref,
                fork=fork,
                force=True,
                remote_name=remote_name,
            )
            self.up.create_pull(
                pr_title,
                description,
                source_branch=source_branch,
                target_branch=upstream_branch,
                fork_username=fork_username,
            )
Exemplo n.º 5
0
    def sync_release(
        self,
        dist_git_branch: str,
        use_local_content=False,
        version: str = None,
        force_new_sources=False,
        upstream_ref: str = None,
        create_pr: bool = True,
        force: bool = False,
    ) -> Optional[PullRequest]:
        """
        Update given package in Fedora

        :param dist_git_branch: branch in dist-git
        :param use_local_content: don't check out anything
        :param version: upstream version to update in Fedora
        :param force_new_sources: don't check the lookaside cache and perform new-sources
        :param upstream_ref: for a source-git repo, use this ref as the latest upstream commit
        :param create_pr: create a pull request if set to True
        :param force: ignore changes in the git index

        :return created PullRequest if create_pr is True, else None
        """
        assert_existence(self.up.local_project)
        assert_existence(self.dg.local_project)
        if self.dg.is_dirty():
            raise PackitException(
                f"The distgit repository {self.dg.local_project.working_dir} is dirty."
                f"This is not supported.")
        if not force and self.up.is_dirty() and not use_local_content:
            raise PackitException(
                "The repository is dirty, will not discard the changes. Use --force to bypass."
            )
        # do not add anything between distgit clone and saving gpg keys!
        self.up.allowed_gpg_keys = self.dg.get_allowed_gpg_keys_from_downstream_config(
        )

        upstream_ref = upstream_ref or self.package_config.upstream_ref
        create_pr = create_pr and self.package_config.create_pr
        self.up.run_action(actions=ActionName.post_upstream_clone)

        full_version = version or self.up.get_version()

        if not full_version:
            raise PackitException(
                "Could not figure out version of latest upstream release.")
        current_up_branch = self.up.active_branch
        try:
            upstream_tag = self.up.package_config.upstream_tag_template.format(
                version=full_version)
            if not use_local_content:
                self.up.local_project.checkout_release(upstream_tag)

            self.dg.check_last_commit()

            self.up.run_action(actions=ActionName.pre_sync)
            self.dg.create_branch(
                dist_git_branch,
                base=f"remotes/origin/{dist_git_branch}",
                setup_tracking=True,
            )

            # fetch and reset --hard upstream/$branch?
            logger.info(f"Using {dist_git_branch!r} dist-git branch.")
            self.dg.update_branch(dist_git_branch)
            self.dg.checkout_branch(dist_git_branch)

            if create_pr:
                local_pr_branch = f"{full_version}-{dist_git_branch}-update"
                self.dg.create_branch(local_pr_branch)
                self.dg.checkout_branch(local_pr_branch)

            description = (
                f"Upstream tag: {upstream_tag}\n"
                f"Upstream commit: {self.up.local_project.commit_hexsha}\n")

            path = os.path.join(self.dg.local_project.working_dir,
                                "README.packit")
            logger.debug(f"Path of README: {path}")
            with open(path, "w") as f:
                f.write(
                    SYNCING_NOTE.format(packit_version=get_packit_version()))

            files_to_sync = self.package_config.get_all_files_to_sync()

            if self.up.with_action(action=ActionName.prepare_files):
                comment = f"- new upstream release: {full_version}"
                try:
                    self.dg.set_specfile_content(self.up.specfile,
                                                 full_version, comment)
                except FileNotFoundError as ex:
                    # no downstream spec file: this is either a mistake or
                    # there is no spec file in dist-git yet, hence warning
                    logger.warning(
                        f"There is not spec file downstream: {ex}, copying the one from upstream."
                    )
                    shutil.copy2(
                        self.up.absolute_specfile_path,
                        self.dg.get_absolute_specfile_path(),
                    )

                raw_sync_files = files_to_sync.get_raw_files_to_sync(
                    Path(self.up.local_project.working_dir),
                    Path(self.dg.local_project.working_dir),
                )

                # exclude spec, we have special plans for it
                raw_sync_files = [
                    x for x in raw_sync_files
                    if x.src != self.up.absolute_specfile_path
                ]

                sync_files(raw_sync_files)
                if upstream_ref:
                    if self.up.with_action(action=ActionName.create_patches):
                        patches = self.up.create_patches(
                            upstream=upstream_ref,
                            destination=str(self.dg.absolute_specfile_dir),
                        )
                        self.dg.specfile_add_patches(patches)

                self._handle_sources(add_new_sources=True,
                                     force_new_sources=force_new_sources)

            # when the action is defined, we still need to copy the files
            if self.up.has_action(action=ActionName.prepare_files):
                raw_sync_files = files_to_sync.get_raw_files_to_sync(
                    Path(self.up.local_project.working_dir),
                    Path(self.dg.local_project.working_dir),
                )
                sync_files(raw_sync_files)

            self.dg.commit(title=f"{full_version} upstream release",
                           msg=description)

            new_pr = None
            if create_pr:
                new_pr = self.push_and_create_pr(
                    pr_title=f"Update to upstream release {full_version}",
                    pr_description=description,
                    dist_git_branch=dist_git_branch,
                )
            else:
                self.dg.push(refspec=f"HEAD:{dist_git_branch}")
        finally:
            if not use_local_content:
                self.up.local_project.git_repo.git.checkout(current_up_branch)
            self.dg.refresh_specfile()

        return new_pr
Exemplo n.º 6
0
    def sync_release(
        self,
        dist_git_branch: str = None,
        version: str = None,
        tag: str = None,
        use_local_content=False,
        force_new_sources=False,
        upstream_ref: str = None,
        create_pr: bool = True,
        force: bool = False,
    ) -> Optional[PullRequest]:
        """
        Update given package in Fedora

        :param dist_git_branch: branch in dist-git, defaults to repo's default branch
        :param use_local_content: don't check out anything
        :param version: upstream version to update in Fedora
        :param tag: upstream git tag
        :param force_new_sources: don't check the lookaside cache and perform new-sources
        :param upstream_ref: for a source-git repo, use this ref as the latest upstream commit
        :param create_pr: create a pull request if set to True
        :param force: ignore changes in the git index

        :return created PullRequest if create_pr is True, else None
        """
        dist_git_branch = (
            dist_git_branch or self.dg.local_project.git_project.default_branch
        )
        # process version and tag parameters
        if version and tag:
            raise PackitException(
                "Function parameters version and tag are mutually exclusive."
            )
        elif not tag:
            version = version or self.up.get_version()
            if not version:
                raise PackitException(
                    "Could not figure out version of latest upstream release."
                )
            upstream_tag = self.up.convert_version_to_tag(version)
        else:
            upstream_tag = tag
            version = self.up.get_version_from_tag(tag)

        assert_existence(self.up.local_project, "Upstream local project")
        assert_existence(self.dg.local_project, "Dist-git local project")
        if self.dg.is_dirty():
            raise PackitException(
                f"The distgit repository {self.dg.local_project.working_dir} is dirty."
                f"This is not supported."
            )
        if not force and self.up.is_dirty() and not use_local_content:
            raise PackitException(
                "The repository is dirty, will not discard the changes. Use --force to bypass."
            )
        # do not add anything between distgit clone and saving gpg keys!
        self.up.allowed_gpg_keys = self.dg.get_allowed_gpg_keys_from_downstream_config()

        upstream_ref = self.up._expand_git_ref(
            upstream_ref or self.package_config.upstream_ref
        )
        create_pr = create_pr and self.package_config.create_pr
        self.up.run_action(actions=ActionName.post_upstream_clone)

        current_up_branch = self.up.active_branch
        try:
            # we want to check out the tag only when local_content is not set
            # and it's an actual upstream repo and not source-git
            if upstream_ref:
                logger.info(
                    "We will not check out the upstream tag "
                    "because this is a source-git repo."
                )
            elif not use_local_content:
                self.up.local_project.checkout_release(upstream_tag)

            self.dg.check_last_commit()

            self.up.run_action(actions=ActionName.pre_sync)
            self.dg.create_branch(
                dist_git_branch,
                base=f"remotes/origin/{dist_git_branch}",
                setup_tracking=True,
            )

            # fetch and reset --hard upstream/$branch?
            logger.info(f"Using {dist_git_branch!r} dist-git branch.")
            self.dg.update_branch(dist_git_branch)
            self.dg.checkout_branch(dist_git_branch)

            if create_pr:
                local_pr_branch = f"{version}-{dist_git_branch}-update"
                self.dg.create_branch(local_pr_branch)
                self.dg.checkout_branch(local_pr_branch)

            description = (
                f"Upstream tag: {upstream_tag}\n"
                f"Upstream commit: {self.up.local_project.commit_hexsha}\n"
            )

            readme_path = self.dg.local_project.working_dir / "README.packit"
            logger.debug(f"README: {readme_path}")
            readme_path.write_text(
                SYNCING_NOTE.format(packit_version=get_packit_version())
            )

            raw_sync_files = (
                self.package_config.get_all_files_to_sync().get_raw_files_to_sync(
                    self.up.local_project.working_dir,
                    self.dg.local_project.working_dir,
                )
            )

            if self.up.with_action(action=ActionName.prepare_files):
                raw_files_to_sync = self._prepare_files_to_sync(
                    raw_sync_files=raw_sync_files,
                    full_version=version,
                    upstream_tag=upstream_tag,
                )
                sync_files(raw_files_to_sync)
                if upstream_ref and self.up.with_action(
                    action=ActionName.create_patches
                ):
                    patches = self.up.create_patches(
                        upstream=upstream_ref,
                        destination=str(self.dg.absolute_specfile_dir),
                    )
                    self.dg.specfile_add_patches(patches)
                self._handle_sources(
                    add_new_sources=True, force_new_sources=force_new_sources
                )

            # when the action is defined, we still need to copy the files
            if self.up.has_action(action=ActionName.prepare_files):

                sync_files(raw_sync_files)

            self.dg.commit(title=f"{version} upstream release", msg=description)

            new_pr = None
            if create_pr:
                title = f"Update to upstream release {version}"

                if not self.dg.pr_exists(title, description.rstrip(), dist_git_branch):
                    new_pr = self.push_and_create_pr(
                        pr_title=title,
                        pr_description=description,
                        dist_git_branch=dist_git_branch,
                    )
            else:
                self.dg.push(refspec=f"HEAD:{dist_git_branch}")
        finally:
            if not use_local_content and not upstream_ref:
                self.up.local_project.git_repo.git.checkout(current_up_branch)
            self.dg.refresh_specfile()
            self.dg.local_project.git_repo.git.reset("--hard", "HEAD")
        return new_pr
Exemplo n.º 7
0
    def sync_release(
        self,
        dist_git_branch: str,
        use_local_content=False,
        version: str = None,
        force_new_sources=False,
        upstream_ref: str = None,
    ):
        """
        Update given package in Fedora
        """
        assert_existence(self.up.local_project)
        assert_existence(self.dg.local_project)

        self.up.run_action(action=ActionName.post_upstream_clone)

        full_version = version or self.up.get_version()
        if not full_version:
            raise PackitException(
                "Could not figure out version of latest upstream release.")
        current_up_branch = self.up.active_branch
        try:
            # TODO: this is problematic, since we may overwrite stuff in the repo
            #       but the thing is that we need to do it
            #       I feel like the ideal thing to do would be to clone the repo and work in tmpdir
            # TODO: this is also naive, upstream may use different tagging scheme, e.g.
            #       release = 232, tag = v232
            if not use_local_content:
                self.up.checkout_release(full_version)

            self.up.run_action(action=ActionName.pre_sync)

            local_pr_branch = f"{full_version}-{dist_git_branch}-update"
            # fetch and reset --hard upstream/$branch?
            logger.info(f"Using {dist_git_branch!r} dist-git branch")

            self.dg.create_branch(
                dist_git_branch,
                base=f"remotes/origin/{dist_git_branch}",
                setup_tracking=True,
            )

            self.dg.update_branch(dist_git_branch)
            self.dg.checkout_branch(dist_git_branch)

            self.dg.create_branch(local_pr_branch)
            self.dg.checkout_branch(local_pr_branch)

            description = (
                f"Upstream tag: {full_version}\n"
                f"Upstream commit: {self.up.local_project.git_repo.head.commit}\n"
            )

            if self.up.with_action(action=ActionName.prepare_files):
                sync_files(
                    self.package_config.synced_files.raw_files_to_sync,
                    self.up.local_project.working_dir,
                    self.dg.local_project.working_dir,
                )
                if upstream_ref:
                    if self.up.with_action(action=ActionName.create_patches):
                        patches = self.up.create_patches(
                            upstream=upstream_ref,
                            destination=self.dg.local_project.working_dir,
                        )
                        self.dg.add_patches_to_specfile(patches)

                self._handle_sources(add_new_sources=True,
                                     force_new_sources=force_new_sources)

            if self.up.has_action(action=ActionName.prepare_files):
                sync_files(
                    self.package_config.synced_files.raw_files_to_sync,
                    self.up.local_project.working_dir,
                    self.dg.local_project.working_dir,
                )

            self.dg.commit(title=f"{full_version} upstream release",
                           msg=description)

            self.push_and_create_pr(
                pr_title=f"Update to upstream release {full_version}",
                pr_description=description,
                dist_git_branch=dist_git_branch,
            )
        finally:
            if not use_local_content:
                self.up.local_project.git_repo.git.checkout(current_up_branch)
Exemplo n.º 8
0
    def sync_release(
        self,
        dist_git_branch: str,
        use_local_content=False,
        version: str = None,
        force_new_sources=False,
        upstream_ref: str = None,
        create_pr: bool = True,
        force: bool = False,
    ):
        """
        Update given package in Fedora

        :param dist_git_branch: branch in dist-git
        :param use_local_content: don't check out anything
        :param version: upstream version to update in Fedora
        :param force_new_sources: don't check the lookaside cache and perform new-sources
        :param upstream_ref: for a source-git repo, use this ref as the latest upstream commit
        :param create_pr: create a pull request if set to True
        :param force: ignore changes in the git index
        """
        assert_existence(self.up.local_project)
        assert_existence(self.dg.local_project)
        if not force and self.up.is_dirty() and not use_local_content:
            raise PackitException(
                "The repository is dirty, will not discard the changes. Use --force to bypass."
            )
        # do not add anything between distgit clone and saving gpg keys!
        self.up.allowed_gpg_keys = self.dg.get_allowed_gpg_keys_from_downstream_config(
        )

        upstream_ref = upstream_ref or self.package_config.upstream_ref
        create_pr = create_pr or self.package_config.create_pr
        self.up.run_action(actions=ActionName.post_upstream_clone)

        full_version = version or self.up.get_version()
        if not full_version:
            raise PackitException(
                "Could not figure out version of latest upstream release.")
        current_up_branch = self.up.active_branch
        try:
            # TODO: this is problematic, since we may overwrite stuff in the repo
            #       but the thing is that we need to do it
            #       I feel like the ideal thing to do would be to clone the repo and work in tmpdir
            # TODO: this is also naive, upstream may use different tagging scheme, e.g.
            #       release = 232, tag = v232
            if not use_local_content:
                self.up.checkout_release(full_version)

            self.dg.check_last_commit()

            self.up.run_action(actions=ActionName.pre_sync)
            self.dg.create_branch(
                dist_git_branch,
                base=f"remotes/origin/{dist_git_branch}",
                setup_tracking=True,
            )

            # fetch and reset --hard upstream/$branch?
            logger.info(f"Using {dist_git_branch!r} dist-git branch")
            self.dg.update_branch(dist_git_branch)
            self.dg.checkout_branch(dist_git_branch)

            if create_pr:
                local_pr_branch = f"{full_version}-{dist_git_branch}-update"
                self.dg.create_branch(local_pr_branch)
                self.dg.checkout_branch(local_pr_branch)

            description = (
                f"Upstream tag: {full_version}\n"
                f"Upstream commit: {self.up.local_project.git_repo.head.commit}\n"
            )

            path = os.path.join(self.dg.local_project.working_dir,
                                "README.packit")
            logger.debug(f"Path of README {path}")
            with open(path, "w") as f:
                f.write(SYNCING_NOTE)

            if self.up.with_action(action=ActionName.prepare_files):
                raw_sync_files = self.package_config.synced_files.get_raw_files_to_sync(
                    Path(self.up.local_project.working_dir),
                    Path(self.dg.local_project.working_dir),
                )

                # exclude spec, we have special plans for it
                raw_sync_files = [
                    x for x in raw_sync_files
                    if x.src != self.up.absolute_specfile_path
                ]

                comment = f"- new upstream release: {full_version}"
                self.dg.set_specfile_content(self.up.specfile, full_version,
                                             comment)

                sync_files(raw_sync_files)
                if upstream_ref:
                    if self.up.with_action(action=ActionName.create_patches):
                        patches = self.up.create_patches(
                            upstream=upstream_ref,
                            destination=str(self.dg.absolute_specfile_dir),
                        )
                        self.dg.add_patches_to_specfile(patches)

                self._handle_sources(add_new_sources=True,
                                     force_new_sources=force_new_sources)

            # when the action is defined, we still need to copy the files
            if self.up.has_action(action=ActionName.prepare_files):
                raw_sync_files = self.package_config.synced_files.get_raw_files_to_sync(
                    Path(self.up.local_project.working_dir),
                    Path(self.dg.local_project.working_dir),
                )
                sync_files(raw_sync_files)

            self.dg.commit(title=f"{full_version} upstream release",
                           msg=description)

            if create_pr:
                self.push_and_create_pr(
                    pr_title=f"Update to upstream release {full_version}",
                    pr_description=description,
                    dist_git_branch=dist_git_branch,
                )
            else:
                self.dg.push(refspec=f"HEAD:{dist_git_branch}")
        finally:
            if not use_local_content:
                self.up.local_project.git_repo.git.checkout(current_up_branch)
Exemplo n.º 9
0
    def sync_from_downstream(
        self,
        dist_git_branch: str = None,
        upstream_branch: str = None,
        no_pr: bool = False,
        fork: bool = True,
        remote_name: str = None,
        exclude_files: Iterable[str] = None,
        force: bool = False,
        sync_only_specfile: bool = False,
    ):
        """
        Sync content of Fedora dist-git repo back to upstream

        :param dist_git_branch: branch in dist-git, defaults to repo's default branch
        :param upstream_branch: upstream branch, defaults to repo's default branch
        :param no_pr: won't create a pull request if set to True
        :param fork: forks the project if set to True
        :param remote_name: name of remote where we should push; if None, try to find a ssh_url
        :param exclude_files: files that will be excluded from the sync
        :param force: ignore changes in the git index
        :param sync_only_specfile: whether to sync only content of specfile
        """
        exclude_files = exclude_files or []
        if not dist_git_branch:
            dist_git_branch = self.dg.local_project.git_project.default_branch
            logger.info(
                f"Dist-git branch not set, defaulting to {dist_git_branch!r}.")
        if not upstream_branch:
            upstream_branch = self.up.local_project.git_project.default_branch
            logger.info(
                f"Upstream branch not set, defaulting to {upstream_branch!r}.")
        logger.info(f"Upstream active branch: {self.up.active_branch}")

        if not force and self.up.is_dirty():
            raise PackitException(
                "The repository is dirty, will not discard the changes. Use --force to bypass."
            )
        self.dg.update_branch(dist_git_branch)
        self.dg.checkout_branch(dist_git_branch)

        logger.info(f"Using {dist_git_branch!r} dist-git branch.")

        if no_pr:
            self.up.checkout_branch(upstream_branch)
        else:
            local_pr_branch = f"{dist_git_branch}-downstream-sync"
            self.up.create_branch(local_pr_branch)
            self.up.checkout_branch(local_pr_branch)

        files = ([
            self.package_config.get_specfile_sync_files_item(
                from_downstream=True)
        ] if sync_only_specfile else self.package_config.files_to_sync)

        # Drop files to be excluded from the sync.
        for ef in exclude_files:
            files = [
                f.drop_src(ef, criteria=lambda x, y: Path(x).name == y)
                for f in files if f is not None
            ]
        # Make paths absolute and check if they are within the
        # working directories.
        for file in files:
            file.resolve(
                src_base=self.dg.local_project.working_dir,
                dest_base=self.up.local_project.working_dir,
            )
        sync_files(files)

        if not no_pr:
            description = f"Downstream commit: {self.dg.local_project.commit_hexsha}\n"

            commit_msg = f"Sync from downstream branch {dist_git_branch!r}"
            pr_title = f"Update from downstream branch {dist_git_branch!r}"

            self.up.commit(title=commit_msg, msg=description)

            # the branch may already be up, let's push forcefully
            source_branch, fork_username = self.up.push_to_fork(
                self.up.local_project.ref,
                fork=fork,
                force=True,
                remote_name=remote_name,
            )
            self.up.create_pull(
                pr_title,
                description,
                source_branch=source_branch,
                target_branch=upstream_branch,
                fork_username=fork_username,
            )
Exemplo n.º 10
0
    def update_dist_git(
        self,
        version: Optional[str],
        upstream_ref: Optional[str],
        add_new_sources: bool,
        force_new_sources: bool,
        upstream_tag: Optional[str],
        commit_title: str,
        commit_msg: str,
        sync_default_files: bool = True,
        pkg_tool: str = "",
    ):
        """Update a dist-git repo from an upstream (aka source-git) repo

        - copy files to be synced to dist-git
        - generate and update patch files and the spec-file
        - upload source archives to the lookaside cache
        - commit the changes to dist-git, if a commit title is defined

        Args:
            version: Upstream version to update in Fedora.
            upstream_ref: For a source-git repo, use this ref as the latest upstream commit.
            add_new_sources: Download and upload source archives.
            force_new_sources: Download/upload the archive even if it's name
                is already in the cache or in sources file.
            upstream_tag: Use the message of the commit referenced by this tag to update the
                changelog in the spec-file, if requested.
            commit_title: Commit message title (aka subject-line) in dist-git.
                Do not commit if this is false-ish.
            commit_msg: Use this commit message in dist-git.
            sync_default_files: Whether to sync the default files, that is: packit.yaml and
                the spec-file.
            pkg_tool: what tool (fedpkg/centpkg) to use upload to lookaside cache
        """
        if sync_default_files:
            synced_files = self.package_config.get_all_files_to_sync()
        else:
            synced_files = self.package_config.files_to_sync
        # Make all paths absolute and check that they are within
        # the working directories of the repositories.
        for item in synced_files:
            item.resolve(
                src_base=self.up.local_project.working_dir,
                dest_base=self.dg.local_project.working_dir,
            )

        if self.up.with_action(action=ActionName.prepare_files):
            synced_files = self._prepare_files_to_sync(
                synced_files=synced_files,
                full_version=version,
                upstream_tag=upstream_tag,
            )

        sync_files(synced_files)

        if upstream_ref and self.up.with_action(
                action=ActionName.create_patches):
            patches = self.up.create_patches(
                upstream=upstream_ref,
                destination=str(self.dg.absolute_specfile_dir),
            )
            # Undo identical patches, but don't remove them
            # from the list, so that they are added to the spec-file.
            PatchGenerator.undo_identical(patches,
                                          self.dg.local_project.git_repo)
            self.dg.specfile_add_patches(
                patches, self.package_config.patch_generation_patch_id_digits)

        if add_new_sources or force_new_sources:
            self._handle_sources(
                force_new_sources=force_new_sources,
                pkg_tool=pkg_tool,
            )

        if commit_title:
            self.dg.commit(title=commit_title, msg=commit_msg, prefix="")