def test_create_from_upstream_no_patch(hello_source_git_repo, hello_dist_git_repo): """A source-git repo is properly initialized from a dist-git repo. - No downstream patches. """ spec = Path(hello_dist_git_repo.working_dir, "hello.spec") content = [ line for line in spec.read_text().splitlines() if not line.startswith("Patch") ] spec.write_text("\n".join(content)) Path(hello_dist_git_repo.working_dir, "turn-into-fedora.patch").unlink() hello_dist_git_repo.git.add(".") hello_dist_git_repo.git.commit(message="Remove the patch") flexmock( PkgTool, sources=download_sources(hello_source_git_repo, hello_dist_git_repo) ) sgg = SourceGitGenerator( config=flexmock(fas_user=None, pkg_tool="fedpkg"), source_git=hello_source_git_repo, dist_git=hello_dist_git_repo, upstream_ref=HELLO_RELEASE, pkg_name="hello", ) sgg.create_from_upstream() source_git_config = yaml.safe_load( Path(hello_source_git_repo.working_dir, DISTRO_DIR, SRC_GIT_CONFIG).read_text() ) check_source_git_config(source_git_config) assert source_git_config["patch_generation_patch_id_digits"] == 1
def test_centos_cronie(dist_git_branch, upstream_ref, api_instance_source_git, tmp_path: Path): source_git_path = tmp_path.joinpath("cronie-sg") # create src-git source_git_path.mkdir() create_new_repo(source_git_path, []) sgg = SourceGitGenerator( LocalProject(working_dir=source_git_path), api_instance_source_git.config, "https://github.com/cronie-crond/cronie", upstream_ref=upstream_ref, centos_package="cronie", dist_git_branch=dist_git_branch, ) sgg.create_from_upstream() if dist_git_branch == "c8s": assert CENTOS_DOMAIN in sgg.dist_git.local_project.git_url else: assert CENTOS_STREAM_GITLAB in sgg.dist_git.local_project.git_url # verify it subprocess.check_call(["packit", "srpm"], cwd=source_git_path) srpm_path = list(source_git_path.glob("cronie-*.src.rpm"))[0] assert srpm_path.is_file()
def create_sourcegit_from_upstream( self, upstream_url: Optional[str] = None, upstream_ref: Optional[str] = None, dist_git_path: Optional[Path] = None, dist_git_branch: Optional[str] = None, fedora_package: Optional[str] = None, centos_package: Optional[str] = None, ): """ generate a source-git repo from provided upstream repo and a corresponding package in Fedora/CentOS ecosystem :param upstream_url: upstream repo URL we want to use as a base :param upstream_ref: upstream git-ref to use as a base :param fedora_package: pick up specfile and downstream sources from this fedora package :param centos_package: pick up specfile and downstream sources from this centos package :param dist_git_branch: branch in dist-git to use :param dist_git_path: path to a local clone of a dist-git repo """ sgg = SourceGitGenerator( config=self.config, local_project=self.upstream_local_project, upstream_url=upstream_url, upstream_ref=upstream_ref, dist_git_path=dist_git_path, dist_git_branch=dist_git_branch, fedora_package=fedora_package, centos_package=centos_package, ) sgg.create_from_upstream()
def test_create_from_upstream_not_require_autosetup( hello_source_git_repo, hello_dist_git_repo ): """A source-git repo is properly initialized from a dist-git repo. - No downstream patches. """ spec = Path(hello_dist_git_repo.working_dir, "hello.spec") content = spec.read_text().replace( "%autosetup", "%setup -q -n hello-%{version}\n%autopatch -p1" ) spec.write_text(content) hello_dist_git_repo.git.add("hello.spec") hello_dist_git_repo.git.commit(message="Use %setup") flexmock( PkgTool, sources=download_sources(hello_source_git_repo, hello_dist_git_repo) ) sgg = SourceGitGenerator( config=flexmock(fas_user=None, pkg_tool="fedpkg"), source_git=hello_source_git_repo, dist_git=hello_dist_git_repo, upstream_ref=HELLO_RELEASE, pkg_name="hello", ignore_missing_autosetup=True, ) sgg.create_from_upstream() source_git_config = yaml.safe_load( Path(hello_source_git_repo.working_dir, DISTRO_DIR, SRC_GIT_CONFIG).read_text() ) check_source_git_config(source_git_config) assert source_git_config["patch_generation_patch_id_digits"] == 4 assert ( Path(hello_source_git_repo.working_dir, DISTRO_DIR, ".gitignore").read_text() == """\ # Reset gitignore rules !* """ ) assert not Path(hello_source_git_repo.working_dir, DISTRO_DIR, "sources").exists() assert not Path(hello_source_git_repo.working_dir, DISTRO_DIR, ".git").exists() assert ( "Hello Fedora Linux" in Path(hello_source_git_repo.working_dir, "hello.rs").read_text() ) commit_messsage_lines = hello_source_git_repo.commit("HEAD~1").message.splitlines() assert "Patch-name: turn-into-fedora.patch" in commit_messsage_lines assert "Patch-id: 1" in commit_messsage_lines assert "Patch-status: |" in commit_messsage_lines commit_messsage_lines = hello_source_git_repo.commit("HEAD").message.splitlines() assert "Patch-name: from-git.patch" in commit_messsage_lines assert "Patch-id: 2" in commit_messsage_lines assert "Patch-status: |" in commit_messsage_lines
def test_create_srcgit_requre_populated(api_instance_source_git, tmp_path: Path): """ use requre to create a source-git out of it in a branch with upstream git history - this should only layer downstream changes on top """ # clone dist-git pkg = "python-requre" dist_git_ref = "6b27ffacda06289ca2d546e15b3c96845243005f" dist_git_path = tmp_path.joinpath(pkg) source_git_path = tmp_path.joinpath("requre-sg") FedPKG().clone(pkg, str(dist_git_path), anonymous=True) dg_lp = LocalProject(working_dir=dist_git_path) # check out specific ref subprocess.check_call(["git", "reset", "--hard", dist_git_ref], cwd=dist_git_path) # add a patch in there spec = Specfile(dist_git_path / f"{pkg}.spec", sources_dir=dist_git_path) patch_name = "hello.patch" patch_path = dist_git_path.joinpath(patch_name) patch_path.write_text(REQURE_PATCH) patch = PatchMetadata(name=patch_name, path=patch_path, present_in_specfile=False) spec.add_patch(patch) dg_lp.stage() dg_lp.commit("add the hello patch") subprocess.check_call(["fedpkg", "prep"], cwd=dist_git_path) # create src-git source_git_path.mkdir() subprocess.check_call([ "git", "clone", "https://github.com/packit/requre", str(source_git_path) ]) subprocess.check_call( ["git", "checkout", "-B", "source-git-0.4.0", "0.4.0"], cwd=source_git_path) sgg = SourceGitGenerator( LocalProject(working_dir=source_git_path), api_instance_source_git.config, dist_git_path=dist_git_path, ) sgg.create_from_upstream() # verify it subprocess.check_call(["packit", "srpm"], cwd=source_git_path) srpm_path = list( source_git_path.glob("python-requre-0.4.0-2.*.src.rpm"))[0] assert srpm_path.is_file()
def test_distgit_cloning(api_instance_source_git, fedora_package, centos_package, branch, tmp_path: Path): sgg = SourceGitGenerator( api_instance_source_git.upstream_local_project, api_instance_source_git.config, # yes, this is the upstream repo f"https://src.fedoraproject.org/rpms/{UNIVERSAL_PACKAGE_NAME}", fedora_package=fedora_package, centos_package=centos_package, dist_git_branch=branch, tmpdir=tmp_path, ) sgg._get_dist_git() assert tmp_path.joinpath(UNIVERSAL_PACKAGE_NAME, ".git").is_dir()
def test_create_from_upstream_with_patch(hello_source_git_repo, hello_dist_git_repo): """A source-git repo is properly initialized from a dist-git repo. - A few downstream patches. """ flexmock(PkgTool, sources=download_sources(hello_source_git_repo, hello_dist_git_repo)) sgg = SourceGitGenerator( config=flexmock(fas_user=None, pkg_tool="fedpkg"), source_git=hello_source_git_repo, dist_git=hello_dist_git_repo, upstream_ref=HELLO_RELEASE, pkg_name="hello", ) sgg.create_from_upstream() source_git_config = yaml.safe_load( Path(hello_source_git_repo.working_dir, DISTRO_DIR, SRC_GIT_CONFIG).read_text()) check_source_git_config(source_git_config) assert source_git_config["patch_generation_patch_id_digits"] == 4 assert (Path(hello_source_git_repo.working_dir, DISTRO_DIR, ".gitignore").read_text() == """\ # Reset gitignore rules !* """) assert not Path(hello_source_git_repo.working_dir, DISTRO_DIR, "sources").exists() assert not Path(hello_source_git_repo.working_dir, DISTRO_DIR, ".git").exists() assert ("Hello Fedora Linux" in Path(hello_source_git_repo.working_dir, "hello.rs").read_text()) commit_messsage_lines = hello_source_git_repo.commit( "HEAD~2").message.splitlines() assert "Patch-name: turn-into-fedora.patch" in commit_messsage_lines assert "Patch-id: 1" in commit_messsage_lines assert "Patch-status: |" in commit_messsage_lines assert (f"From-dist-git-commit: {hello_dist_git_repo.head.commit.hexsha}" in commit_messsage_lines) commit_messsage_lines = hello_source_git_repo.commit( "HEAD~1").message.splitlines() assert "Patch-name: from-git.patch" in commit_messsage_lines assert "Patch-id: 2" in commit_messsage_lines assert "Patch-status: |" in commit_messsage_lines assert (f"From-dist-git-commit: {hello_dist_git_repo.head.commit.hexsha}" in commit_messsage_lines)
def test_centos_conf(cronie, tmp_path: Path): """ make sure the centos-specific configuration is correct """ source_git_path = tmp_path.joinpath("cronie-sg") # create src-git source_git_path.mkdir() create_new_repo(source_git_path, []) sgg = SourceGitGenerator( LocalProject(working_dir=source_git_path), Config(), dist_git_path=cronie, upstream_ref="cronie-1.5.2", centos_package="cronie", ) dg = sgg.dist_git assert isinstance(dg, CentOS8DistGit) flexmock( DistGit, download_upstream_archive=lambda: cronie / "SOURCES" / "cronie-1.5.2.tar.gz", ) assert sgg.primary_archive == cronie / "SOURCES" / "cronie-1.5.2.tar.gz" assert dg.absolute_source_dir == cronie / "SOURCES" assert dg.absolute_specfile_dir == cronie / "SPECS" assert dg.absolute_specfile_path == cronie / "SPECS" / "cronie.spec"
def test_run_prep(api_instance_source_git, fedora_package, centos_package, branch, tmp_path: Path): sgg = SourceGitGenerator( api_instance_source_git.upstream_local_project, api_instance_source_git.config, f"https://github.com/containers/{fedora_package}", fedora_package=fedora_package, centos_package=centos_package, dist_git_branch=branch, tmpdir=tmp_path, ) assert sgg.primary_archive.exists() # making sure this is downloaded sgg._run_prep() build_dir = sgg.dist_git.local_project.working_dir.joinpath("BUILD") assert build_dir.exists() project_dir = next(build_dir.glob("fuse-overlayfs-*")) assert project_dir.joinpath(".git")
def test_centos_cronie(api_instance_source_git, tmp_path: Path): source_git_path = tmp_path.joinpath("cronie-sg") # create src-git source_git_path.mkdir() create_new_repo(source_git_path, []) sgg = SourceGitGenerator( LocalProject(working_dir=source_git_path), api_instance_source_git.config, "https://github.com/cronie-crond/cronie", upstream_ref="cronie-1.5.2", centos_package="cronie", ) sgg.create_from_upstream() # verify it subprocess.check_call(["packit", "srpm"], cwd=source_git_path) srpm_path = list(source_git_path.glob("cronie-1.5.2-*.src.rpm"))[0] assert srpm_path.is_file()
def test_dist_git_not_pristine(hello_source_git_repo, hello_dist_git_repo, change): """Initialization fails if the dist-git working directory is not pristine, has changes and/or untracked files, in order to avoid tracking files in source-git which are not part of the dist-git repo and history. """ change(Path(hello_dist_git_repo.working_dir, "hello.spec")) sgg = SourceGitGenerator( config=flexmock(), source_git=hello_source_git_repo, dist_git=hello_dist_git_repo, upstream_ref=HELLO_RELEASE, pkg_name="hello", ) with pytest.raises(PackitException) as ex: sgg.create_from_upstream() assert "is not pristine" in str(ex.value)
def test_not_using_autosetup(hello_source_git_repo, hello_dist_git_repo): """Initializing a source-git repo for packages which don't use %autosetup in their specfile is currently not supported. """ spec = Path(hello_dist_git_repo.working_dir, "hello.spec") content = spec.read_text().replace("%autosetup", "%setup") spec.write_text(content) hello_dist_git_repo.git.add("hello.spec") hello_dist_git_repo.git.commit(message="Use %setup") sgg = SourceGitGenerator( config=flexmock(), source_git=hello_source_git_repo, dist_git=hello_dist_git_repo, upstream_ref=HELLO_RELEASE, ) with pytest.raises(PackitException) as ex: sgg.create_from_upstream() assert "not using %autosetup" in str(ex.value)
def test_upstream_ref_not_at_head(hello_source_git_repo, hello_dist_git_repo): """Initializing a source-git repo fails, if the upstream_ref which should be the starting point of the downstream changes is not at the HEAD of the source-git repo. """ readme = Path(hello_source_git_repo.working_dir, "README.md") with open(readme, "a") as fp: fp.write("\nSome new thing\n") hello_source_git_repo.git.add("README.md") hello_source_git_repo.git.commit(message="Add a new thing") sgg = SourceGitGenerator( config=flexmock(), source_git=hello_source_git_repo, dist_git=hello_dist_git_repo, upstream_ref=HELLO_RELEASE, ) with pytest.raises(PackitException) as ex: sgg.create_from_upstream() assert "not pointing to the current HEAD" in str(ex.value)
def init_source_git( self, dist_git: git.Repo, source_git: git.Repo, upstream_ref: str, upstream_url: Optional[str] = None, upstream_remote: Optional[str] = None, pkg_tool: Optional[str] = None, pkg_name: Optional[str] = None, ignore_missing_autosetup: bool = False, ): """ Initialize a source-git repo from dist-git, that is: add configuration, packaging files needed by the distribution and transform the distribution patches into Git commits. Args: dist_git: Dist-git repository to be used for initialization. source_git: Git repository to be initialized as a source-git repo. upstream_ref: Upstream ref which is going to be the starting point of the source-git history. This can be a branch, tag or commit sha. It is expected that the current HEAD and this ref point to the same commit. upstream_url: Git URL to be saved in the source-git configuration. upstream_remote: Name of the remote from which the fetch URL is taken as the Git URL of the upstream project to be saved in the source-git configuration. pkg_tool: Packaging tool to be used to interact with the dist-git repo. pkg_name: Name of the package in dist-git. ignore_missing_autosetup: Do not require %autosetup to be used in the %prep section of specfile. """ sgg = SourceGitGenerator( config=self.config, dist_git=dist_git, source_git=source_git, upstream_ref=upstream_ref, upstream_url=upstream_url, upstream_remote=upstream_remote, pkg_tool=pkg_tool, pkg_name=pkg_name, ignore_missing_autosetup=ignore_missing_autosetup, ) sgg.create_from_upstream()
def test_fetch_upstream_ref(api_instance_source_git, tmp_path: Path): tag = "1.0.0" s = tmp_path.joinpath("s") u = tmp_path.joinpath("u") u.mkdir() create_new_repo(Path(s), []) initiate_git_repo(u, tag=tag) sgg = SourceGitGenerator( LocalProject(working_dir=s), api_instance_source_git.config, str(u), upstream_ref=tag, centos_package="x", ) sgg._pull_upstream_ref() assert s.joinpath(".git").is_dir() assert sgg.local_project.ref == "main" assert sgg.local_project.working_dir.joinpath("hops").read_text() == "Cascade\n" assert sgg.local_project.git_repo.head.commit.message == "commit with data\n"