Exemple #1
0
def test_basic_local_update_using_distgit(cwd_upstream, api_instance,
                                          mock_remote_functionality_upstream):
    """basic propose-downstream test: mock remote API, use local upstream and dist-git"""
    u, d, api = api_instance
    mock_spec_download_remote_s(d)

    api.sync_release(dist_git_branch="main", version="0.1.0")

    assert (d / TARBALL_NAME).is_file()
    spec = Specfile(d / "beer.spec")
    assert spec.expanded_version == "0.1.0"

    with spec.sections() as sections:
        package_section = sections.package

    assert package_section[2] == "# some change"
    assert package_section[4] == "Name:           beer"
    assert package_section[5] == "Version:        0.1.0"
    assert package_section[6] == "Release:        1%{?dist}"
    assert package_section[7] == "Summary:        A tool to make you happy"

    assert (d / "README.packit").is_file()
    # assert that we have changelog entries for both versions
    with spec.sections() as sections:
        changelog = "\n".join(sections.changelog)
    assert "0.0.0" in changelog
    assert "0.1.0" in changelog
Exemple #2
0
def test_local_update_generated_spec(cwd_upstream, api_instance,
                                     mock_remote_functionality_upstream):
    """Check that specfile can be generated on clone."""
    u, d, api = api_instance
    mock_spec_download_remote_s(d)
    flexmock(api).should_receive("init_kerberos_ticket").at_least().once()
    flexmock(Upstream).should_receive(
        "get_latest_released_version").and_return("0.1.0")

    # Simulate generation by moving the spec to a different location
    # We are checking two things:
    # * spec-file is not used before the post-upstream-clone
    # * the version is get from the release state
    current_spec_location = u / "beer.spec"
    new_spec_location = u / ".." / "tmp.spec"
    shutil.move(current_spec_location, new_spec_location)
    subprocess.check_call(["git", "add", "beer.spec"], cwd=u)
    subprocess.check_call(
        ["git", "commit", "-m", "Spec removed from upstream"], cwd=u)
    api.up.package_config.actions = {
        ActionName.post_upstream_clone:
        [f"mv {new_spec_location} {current_spec_location}"]
    }

    api.sync_release(dist_git_branch="main")

    assert (d / TARBALL_NAME).is_file()
    spec = Specfile(d / "beer.spec")
    assert spec.expanded_version == "0.1.0"
    assert (d / "README.packit").is_file()
    # assert that we have changelog entries for both versions
    with spec.sections() as sections:
        changelog = "\n".join(sections.changelog)
    assert "0.0.0" in changelog
    assert "0.1.0" in changelog
Exemple #3
0
def test_write_spec_content(specfile):
    data = "new line 1\n"
    spec = Specfile(specfile, autosave=True)
    with spec.sections() as sections:
        sections.description = [data]

    assert "new line 1" in specfile.read_text()
Exemple #4
0
def test_basic_local_update_copy_upstream_release_description(
        cwd_upstream, api_instance, mock_remote_functionality_upstream):
    """basic propose-downstream test: mock remote API, use local upstream and dist-git,
    set copy_upstream_release_description in package config to True"""
    u, d, api = api_instance
    mock_spec_download_remote_s(d)
    flexmock(api).should_receive("init_kerberos_ticket").at_least().once()
    release = flexmock(body="Some description of the upstream release")
    api.up.local_project.git_project = flexmock(
        get_release=lambda name, tag_name: release)
    api.package_config.copy_upstream_release_description = True
    api.sync_release(dist_git_branch="main", version="0.1.0")

    assert (d / TARBALL_NAME).is_file()
    spec = Specfile(d / "beer.spec")
    assert spec.expanded_version == "0.1.0"
    assert (d / "README.packit").is_file()
    # assert that we have changelog entries for both versions
    with spec.sections() as sections:
        changelog = "\n".join(sections.changelog)

    assert ("""- 0.1.0-1
Some description of the upstream release
""" in changelog)

    assert "0.0.0" in changelog
    assert "0.1.0" in changelog
Exemple #5
0
def test_basic_local_update_empty_patch(
    distgit_and_remote,
    mock_remote_functionality_sourcegit,
    api_instance_source_git,
    ref,
):
    """propose-downstream for sourcegit test: mock remote API, use local upstream and dist-git
    Check that by default commit origin is not marked in dist-git.
    """

    distgit, _ = distgit_and_remote
    mock_spec_download_remote_s(distgit)
    api_instance_source_git.sync_release(
        dist_git_branch="main",
        version="0.1.0",
        upstream_ref=ref,
    )

    assert (distgit / TARBALL_NAME).is_file()
    spec = Specfile(distgit / "beer.spec")
    assert spec.expanded_version == "0.1.0"

    with spec.patches() as patches:
        assert not patches
    assert "From-source-git-commit" not in git.Repo(
        distgit).head.commit.message
Exemple #6
0
def test_patch_id_digits(specfile, lines, digits):
    """Check detecting the number of digits used for patch IDs (indices)"""
    content = specfile.read_text()
    content = content.replace("### patches ###\n", lines)
    specfile.write_text(content)
    spec = Specfile(specfile, sourcedir=specfile.parent, autosave=True)
    with spec.patches() as patches:
        assert patches[0].number_digits == digits
Exemple #7
0
def test_read_patch_comments(specfile, lines, files, expectation):
    """Check reading comment lines that belong to patches"""
    content = specfile.read_text()
    content = content.replace("### patches ###\n", lines)
    specfile.write_text(content)
    for patch_file in files:
        Path(specfile.parent, patch_file).touch()
    spec = Specfile(specfile, sourcedir=specfile.parent, autosave=True)
    with spec.patches() as patches:
        comments = {p.filename: [c.text for c in p.comments] for p in patches}
        assert comments == expectation
Exemple #8
0
    def create_from_upstream(self):
        """Create a source-git repo, by transforming downstream patches
        in Git commits applied on top of the selected upstream ref.
        """
        upstream_ref_sha = self.source_git.git.rev_list(
            "-1", self.upstream_ref)
        if upstream_ref_sha != self.source_git.head.commit.hexsha:
            raise PackitException(
                f"{self.upstream_ref!r} is not pointing to the current HEAD "
                f"in {self.source_git.working_dir!r}.")
        with self.dist_git_specfile.prep() as prep:
            if "%autosetup" not in prep:
                if not self.ignore_missing_autosetup:
                    raise PackitException(
                        "Initializing source-git repos for packages "
                        "not using %autosetup is not allowed by default. "
                        "You can use --ignore-missing-autosetup option to enforce "
                        "running the command without %autosetup.")
                logger.warning(
                    "Source-git repos for packages not using %autosetup may be not initialized"
                    "properly or may not work with other packit commands.")

        self._populate_distro_dir()
        self._reset_gitignore()
        self._configure_syncing()

        spec = Specfile(
            f"{self.distro_dir}/{self.pkg_name}.spec",
            sourcedir=self.dist_git.working_dir,
            autosave=True,
        )
        with spec.patches() as patches:
            patches.clear()

        self.source_git.git.stage(DISTRO_DIR, force=True)
        message = f"""Initialize as a source-git repository

{FROM_DIST_GIT_TOKEN}: {self.dist_git.head.commit.hexsha}
"""
        self.source_git.git.commit(message=message)

        pkg_tool = PkgTool(
            fas_username=self.config.fas_user,
            directory=self.dist_git.working_dir,
            tool=self.pkg_tool or self.config.pkg_tool,
        )
        pkg_tool.sources()
        self._run_prep()
        self._rebase_patches()
Exemple #9
0
    def set_specfile_content(
        self,
        specfile: Specfile,
        version: Optional[str] = None,
        comment: Optional[str] = None,
    ):
        """
        Update this specfile using provided specfile

        Args:
            specfile: specfile to get changes from (we update self.specfile)
            version: version to set in self.specfile
            comment: new comment for the version in %changelog
        """
        with self.specfile.sections() as sections, specfile.sections(
        ) as other_sections:
            try:
                previous_changelog = sections.changelog[:]
            except AttributeError:
                previous_changelog = []
            sections[:] = other_sections[:]
            try:
                sections.changelog = previous_changelog
            except AttributeError:
                sections.append(Section("changelog", previous_changelog))
        if version is not None:
            self.specfile.version = version
        if comment is not None:
            self.specfile.add_changelog_entry(comment)
Exemple #10
0
 def dist_git_specfile(self) -> Specfile:
     if not self._dist_git_specfile:
         path = str(Path(self.dist_git.working_dir,
                         f"{self.pkg_name}.spec"))
         self._dist_git_specfile = Specfile(
             path, sourcedir=self.dist_git.working_dir, autosave=True)
     return self._dist_git_specfile
Exemple #11
0
def test_basic_local_update_without_patching(
    sourcegit_and_remote,
    distgit_and_remote,
    mock_remote_functionality_sourcegit,
    api_instance_source_git,
):
    """propose-downstream for sourcegit test: mock remote API, use local upstream and dist-git
    Check that the upstream commit hash is saved when 'mock_commit_origin' is set.
    """

    sourcegit, _ = sourcegit_and_remote
    distgit, _ = distgit_and_remote
    mock_spec_download_remote_s(distgit)

    api_instance_source_git.sync_release(
        dist_git_branch="main",
        version="0.1.0",
        upstream_ref="0.1.0",
        mark_commit_origin=True,
    )

    assert (distgit / TARBALL_NAME).is_file()
    spec = Specfile(distgit / "beer.spec")
    assert spec.expanded_version == "0.1.0"
    assert (f"From-source-git-commit: {git.Repo(sourcegit).head.commit.hexsha}"
            in git.Repo(distgit).head.commit.message)
Exemple #12
0
 def specfile(self) -> Specfile:
     if self._specfile is None:
         self._specfile = Specfile(
             self.absolute_specfile_path,
             sourcedir=self.absolute_source_dir,
             autosave=True,
         )
     return self._specfile
Exemple #13
0
def test_basic_local_update(cwd_upstream, api_instance,
                            mock_remote_functionality_upstream):
    """basic propose-downstream test: mock remote API, use local upstream and dist-git"""
    u, d, api = api_instance
    mock_spec_download_remote_s(d)
    flexmock(api).should_receive("init_kerberos_ticket").at_least().once()

    api.sync_release(dist_git_branch="main", version="0.1.0")

    assert (d / TARBALL_NAME).is_file()
    spec = Specfile(d / "beer.spec")
    assert spec.expanded_version == "0.1.0"
    assert (d / "README.packit").is_file()
    # assert that we have changelog entries for both versions
    with spec.sections() as sections:
        changelog = "\n".join(sections.changelog)
    assert "0.0.0" in changelog
    assert "0.1.0" in changelog
Exemple #14
0
def test_remove_patches_no_blanklines(specfile):
    no_blanks = specfile.read_text().replace("\n\n", "\n")
    no_patches = no_blanks.replace("\n### patches ###\n", "\n")
    patches = no_blanks.replace(
        "### patches ###\n",
        """\
# Some comment line to be removed
Patch1: yellow.patch
Patch2: blue.patch
# One
# Or more lines
Patch : dark.patch
""",
    )
    specfile.write_text(patches)
    spec = Specfile(specfile, sourcedir=specfile.parent, autosave=True)
    with spec.patches() as patches:
        patches.clear()
    assert specfile.read_text() == no_patches
Exemple #15
0
def test_basic_local_update_from_downstream(
        cwd_upstream, api_instance, mock_remote_functionality_upstream):
    flexmock(LocalProject, _parse_namespace_from_git_url=lambda: None)
    u, d, api = api_instance

    api.sync_from_downstream("main", "main", True)

    new_upstream = api.up.local_project.working_dir
    assert (new_upstream / "beer.spec").is_file()
    spec = Specfile(new_upstream / "beer.spec")
    assert spec.expanded_version == "0.0.0"
Exemple #16
0
    def test_download_remote_sources_via_spec(self):
        """
        Use case: package_config.sources and Source0 are out of sync,
        make sure packit downloads correct archive specifiec in the spec file
        """
        # we should use an actual git.centos.org url but we'd store the tarball in our history
        # which we don't want I'd say
        # "https://git.centos.org/sources/rsync/c8s/82e7829c0b3cefbd33c233005341e2073c425629"
        git_centos_org_url = "https://example.org/"
        package_config = PackageConfig(
            specfile_path="rsync.spec",
            sources=[
                SourcesItem(
                    path="rsync-3.1.2.tar.gz",
                    url=git_centos_org_url,
                ),
            ],
            jobs=[],
        )
        # same drill here, let's not store tarballs in our git-history
        # source = "https://download.samba.org/pub/rsync/src/rsync-3.1.3.tar.gz"
        source = "https://httpbin.org/anything/rsync-3.1.3.tar.gz"

        base_git = PackitRepositoryBase(config=flexmock(),
                                        package_config=package_config)
        specfile_content = ("Name: rsync\n"
                            "Version: 3.1.3\n"
                            "Release: 1\n"
                            f"Source0: {source}\n"
                            "License: GPLv3+\n"
                            "Summary: rsync\n"
                            "%description\nrsync\n")
        tmp = Path(self.static_tmp)
        spec_path = tmp / "rsync.spec"
        spec_path.write_text(specfile_content)
        specfile = Specfile(spec_path, sourcedir=tmp, autosave=True)
        flexmock(base_git).should_receive("specfile").and_return(specfile)

        def mocked_is_file():
            import inspect

            # return False only if Path.is_file() is called directly from within
            # the download_remote_sources() method
            # this is necessary because specfile relies on Path.is_file() as well
            return inspect.stack()[3].function != "download_remote_sources"

        flexmock(Path).should_receive("is_file").replace_with(mocked_is_file)

        base_git.download_remote_sources()

        expected_path = tmp / "rsync-3.1.3.tar.gz"
        assert Path(expected_path).exists()
Exemple #17
0
def test_basic_local_update_direct_push(cwd_upstream, api_instance,
                                        distgit_and_remote,
                                        mock_remote_functionality_upstream):
    """basic propose-downstream test: mock remote API, use local upstream and dist-git"""
    u, d, api = api_instance
    _, distgit_remote = distgit_and_remote
    mock_spec_download_remote_s(d)

    api.sync_release(dist_git_branch="main", version="0.1.0", create_pr=False)

    remote_dir_clone = Path(f"{distgit_remote}-clone")
    subprocess.check_call(
        ["git", "clone", distgit_remote,
         str(remote_dir_clone)],
        cwd=str(remote_dir_clone.parent),
    )

    spec = Specfile(remote_dir_clone / "beer.spec")
    assert spec.expanded_version == "0.1.0"
    assert (remote_dir_clone / "README.packit").is_file()
Exemple #18
0
def test_basic_local_update_direct_push_no_dg_spec(
        cwd_upstream, api_instance, distgit_and_remote,
        mock_remote_functionality_upstream):
    u, d, api = api_instance
    d.joinpath("beer.spec").unlink()
    subprocess.check_call(
        ["git", "commit", "-m", "remove spec", "-a"],
        cwd=str(d),
    )
    _, distgit_remote = distgit_and_remote
    mock_spec_download_remote_s(d)

    api.sync_release(dist_git_branch="main", version="0.1.0", create_pr=False)

    remote_dir_clone = Path(f"{distgit_remote}-clone")
    subprocess.check_call(
        ["git", "clone", distgit_remote,
         str(remote_dir_clone)],
        cwd=str(remote_dir_clone.parent),
    )

    spec = Specfile(remote_dir_clone / "beer.spec")
    assert spec.expanded_version == "0.1.0"
    assert (remote_dir_clone / "README.packit").is_file()
Exemple #19
0
def test_set_spec_has_autochangelog(spec_content, has_autochangelog, tmp_path):
    spec_path = tmp_path / "life.spec"
    spec_path.write_text(spec_content)
    specfile = Specfile(spec_path, sourcedir=tmp_path, autosave=True)

    assert specfile.has_autochangelog == has_autochangelog