Ejemplo n.º 1
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",
        )
Ejemplo n.º 2
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
Ejemplo n.º 3
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.package_config.run_action(action_name="pre-sync")

        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)

            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.package_config.with_action(action_name="prepare-files"):
                self.dg.sync_files(self.up.local_project)
                if upstream_ref:
                    if self.package_config.with_action(action_name="patch"):
                        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.package_config.has_action("prepare-files"):
                self.dg.sync_files(self.up.local_project)

            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.checkout())
Ejemplo n.º 4
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)