mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-04-24 15:27:17 +00:00
patch support
This commit is contained in:
parent
bee97df87f
commit
c1f174ed79
@ -23,7 +23,7 @@ import shutil
|
||||
from pathlib import Path
|
||||
from typing import Callable, Iterable, List, Set
|
||||
|
||||
from ahriman.core.build_tools.task import Task
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.repository.repository import Repository
|
||||
from ahriman.core.tree import Tree
|
||||
@ -112,9 +112,9 @@ class Application:
|
||||
|
||||
def add_manual(src: str) -> Path:
|
||||
package = Package.load(src, self.repository.pacman, self.configuration.get("alpm", "aur_url"))
|
||||
path = self.repository.paths.manual / package.base
|
||||
Task.fetch(path, package.git_url)
|
||||
return path
|
||||
Sources.load(self.repository.paths.manual_for(package.base), package.git_url,
|
||||
self.repository.paths.patches_for(package.base))
|
||||
return self.repository.paths.manual_for(package.base)
|
||||
|
||||
def add_archive(src: Path) -> None:
|
||||
dst = self.repository.paths.packages / src.name
|
||||
@ -238,7 +238,7 @@ class Application:
|
||||
process_update(packages)
|
||||
|
||||
# process manual packages
|
||||
tree = Tree.load(updates)
|
||||
tree = Tree.load(updates, self.repository.paths)
|
||||
for num, level in enumerate(tree.levels()):
|
||||
self.logger.info("processing level #%i %s", num, [package.base for package in level])
|
||||
packages = self.repository.process_build(level)
|
||||
|
83
src/ahriman/core/build_tools/sources.py
Normal file
83
src/ahriman/core/build_tools/sources.py
Normal file
@ -0,0 +1,83 @@
|
||||
#
|
||||
# Copyright (c) 2021 ahriman team.
|
||||
#
|
||||
# This file is part of ahriman
|
||||
# (see https://github.com/arcan1s/ahriman).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.util import check_output
|
||||
|
||||
|
||||
class Sources:
|
||||
"""
|
||||
helper to download package sources (PKGBUILD etc)
|
||||
"""
|
||||
|
||||
_check_output = check_output
|
||||
|
||||
@staticmethod
|
||||
def fetch(local_path: Path, remote: str, branch: str = "master") -> None:
|
||||
"""
|
||||
either clone repository or update it to origin/`branch`
|
||||
:param local_path: local path to fetch
|
||||
:param remote: remote target (from where to fetch)
|
||||
:param branch: branch name to checkout, master by default
|
||||
"""
|
||||
logger = logging.getLogger("build_details")
|
||||
# local directory exists and there is .git directory
|
||||
if (local_path / ".git").is_dir():
|
||||
logger.info("update HEAD to remote to %s", local_path)
|
||||
Sources._check_output("git", "fetch", "origin", branch, exception=None, cwd=local_path, logger=logger)
|
||||
else:
|
||||
logger.info("clone remote %s to %s", remote, local_path)
|
||||
Sources._check_output("git", "clone", remote, str(local_path), exception=None, logger=logger)
|
||||
# and now force reset to our branch
|
||||
Sources._check_output("git", "checkout", "--force", branch, exception=None, cwd=local_path, logger=logger)
|
||||
Sources._check_output("git", "reset", "--hard", f"origin/{branch}",
|
||||
exception=None, cwd=local_path, logger=logger)
|
||||
|
||||
@staticmethod
|
||||
def load(local_path: Path, remote: str, patch_path: Path) -> None:
|
||||
"""
|
||||
fetch sources from remote and apply patches
|
||||
:param local_path: local path to fetch
|
||||
:param remote: remote target (from where to fetch)
|
||||
:param patch_path: path to directory with package patches
|
||||
"""
|
||||
Sources.fetch(local_path, remote)
|
||||
Sources.patch(local_path, patch_path)
|
||||
|
||||
@staticmethod
|
||||
def patch(local_path: Path, patch_path: Path) -> None:
|
||||
"""
|
||||
apply patches if any
|
||||
:param local_path: local path to directory with git sources
|
||||
:param patch_path: path to directory with package patches
|
||||
"""
|
||||
# check if even there are patches
|
||||
if not patch_path.is_dir():
|
||||
return # no patches provided
|
||||
logger = logging.getLogger("build_details")
|
||||
# find everything that looks like patch and sort it
|
||||
patches = sorted(patch_path.glob("*.patch"))
|
||||
logger.info("found %s patches", patches)
|
||||
for patch in patches:
|
||||
logger.info("apply patch %s", patch.name)
|
||||
Sources._check_output("git", "apply", "--ignore-space-change", "--ignore-whitespace", str(patch),
|
||||
exception=None, cwd=local_path, logger=logger)
|
@ -23,6 +23,7 @@ import shutil
|
||||
from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.core.configuration import Configuration
|
||||
from ahriman.core.exceptions import BuildFailed
|
||||
from ahriman.core.util import check_output
|
||||
@ -58,38 +59,6 @@ class Task:
|
||||
self.makepkg_flags = configuration.getlist("build", "makepkg_flags", fallback=[])
|
||||
self.makechrootpkg_flags = configuration.getlist("build", "makechrootpkg_flags", fallback=[])
|
||||
|
||||
@property
|
||||
def cache_path(self) -> Path:
|
||||
"""
|
||||
:return: path to cached packages
|
||||
"""
|
||||
return self.paths.cache / self.package.base
|
||||
|
||||
@property
|
||||
def git_path(self) -> Path:
|
||||
"""
|
||||
:return: path to clone package from git
|
||||
"""
|
||||
return self.paths.sources / self.package.base
|
||||
|
||||
@staticmethod
|
||||
def fetch(local: Path, remote: str, branch: str = "master") -> None:
|
||||
"""
|
||||
either clone repository or update it to origin/`branch`
|
||||
:param local: local path to fetch
|
||||
:param remote: remote target (from where to fetch)
|
||||
:param branch: branch name to checkout, master by default
|
||||
"""
|
||||
logger = logging.getLogger("build_details")
|
||||
# local directory exists and there is .git directory
|
||||
if (local / ".git").is_dir():
|
||||
Task._check_output("git", "fetch", "origin", branch, exception=None, cwd=local, logger=logger)
|
||||
else:
|
||||
Task._check_output("git", "clone", remote, str(local), exception=None, logger=logger)
|
||||
# and now force reset to our branch
|
||||
Task._check_output("git", "checkout", "--force", branch, exception=None, cwd=local, logger=logger)
|
||||
Task._check_output("git", "reset", "--hard", f"origin/{branch}", exception=None, cwd=local, logger=logger)
|
||||
|
||||
def build(self) -> List[Path]:
|
||||
"""
|
||||
run package build
|
||||
@ -104,13 +73,13 @@ class Task:
|
||||
Task._check_output(
|
||||
*command,
|
||||
exception=BuildFailed(self.package.base),
|
||||
cwd=self.git_path,
|
||||
cwd=self.paths.sources_for(self.package.base),
|
||||
logger=self.build_logger)
|
||||
|
||||
# well it is not actually correct, but we can deal with it
|
||||
packages = Task._check_output("makepkg", "--packagelist",
|
||||
exception=BuildFailed(self.package.base),
|
||||
cwd=self.git_path,
|
||||
cwd=self.paths.sources_for(self.package.base),
|
||||
logger=self.build_logger).splitlines()
|
||||
return [Path(package) for package in packages]
|
||||
|
||||
@ -119,8 +88,8 @@ class Task:
|
||||
fetch package from git
|
||||
:param path: optional local path to fetch. If not set default path will be used
|
||||
"""
|
||||
git_path = path or self.git_path
|
||||
if self.cache_path.is_dir():
|
||||
git_path = path or self.paths.sources_for(self.package.base)
|
||||
if self.paths.cache_for(self.package.base).is_dir():
|
||||
# no need to clone whole repository, just copy from cache first
|
||||
shutil.copytree(self.cache_path, git_path)
|
||||
return self.fetch(git_path, self.package.git_url)
|
||||
shutil.copytree(self.paths.cache_for(self.package.base), git_path)
|
||||
Sources.load(git_path, self.package.git_url, self.paths.patches_for(self.package.base))
|
||||
|
@ -25,8 +25,9 @@ import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Iterable, List, Set, Type
|
||||
|
||||
from ahriman.core.build_tools.task import Task
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
class Leaf:
|
||||
@ -53,15 +54,16 @@ class Leaf:
|
||||
return self.package.packages.keys()
|
||||
|
||||
@classmethod
|
||||
def load(cls: Type[Leaf], package: Package) -> Leaf:
|
||||
def load(cls: Type[Leaf], package: Package, paths: RepositoryPaths) -> Leaf:
|
||||
"""
|
||||
load leaf from package with dependencies
|
||||
:param package: package properties
|
||||
:param paths: repository paths instance
|
||||
:return: loaded class
|
||||
"""
|
||||
clone_dir = Path(tempfile.mkdtemp())
|
||||
try:
|
||||
Task.fetch(clone_dir, package.git_url)
|
||||
Sources.load(clone_dir, package.git_url, paths.patches_for(package.base))
|
||||
dependencies = Package.dependencies(clone_dir)
|
||||
finally:
|
||||
shutil.rmtree(clone_dir, ignore_errors=True)
|
||||
@ -93,13 +95,14 @@ class Tree:
|
||||
self.leaves = leaves
|
||||
|
||||
@classmethod
|
||||
def load(cls: Type[Tree], packages: Iterable[Package]) -> Tree:
|
||||
def load(cls: Type[Tree], packages: Iterable[Package], paths: RepositoryPaths) -> Tree:
|
||||
"""
|
||||
load tree from packages
|
||||
:param packages: packages list
|
||||
:param paths: repository paths instance
|
||||
:return: loaded class
|
||||
"""
|
||||
return cls([Leaf.load(package) for package in packages])
|
||||
return cls([Leaf.load(package, paths) for package in packages])
|
||||
|
||||
def levels(self) -> List[List[Package]]:
|
||||
"""
|
||||
|
@ -231,22 +231,18 @@ class Package:
|
||||
if not self.is_vcs:
|
||||
return self.version
|
||||
|
||||
from ahriman.core.build_tools.task import Task
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
|
||||
clone_dir = paths.cache / self.base
|
||||
logger = logging.getLogger("build_details")
|
||||
Task.fetch(clone_dir, self.git_url)
|
||||
Sources.load(paths.cache_for(self.base), self.git_url, paths.patches_for(self.base))
|
||||
|
||||
try:
|
||||
# update pkgver first
|
||||
Package._check_output("makepkg", "--nodeps", "--nobuild", exception=None, cwd=clone_dir, logger=logger)
|
||||
Package._check_output("makepkg", "--nodeps", "--nobuild",
|
||||
exception=None, cwd=paths.cache_for(self.base), logger=logger)
|
||||
# generate new .SRCINFO and put it to parser
|
||||
srcinfo_source = Package._check_output(
|
||||
"makepkg",
|
||||
"--printsrcinfo",
|
||||
exception=None,
|
||||
cwd=clone_dir,
|
||||
logger=logger)
|
||||
srcinfo_source = Package._check_output("makepkg", "--printsrcinfo",
|
||||
exception=None, cwd=paths.cache_for(self.base), logger=logger)
|
||||
srcinfo, errors = parse_srcinfo(srcinfo_source)
|
||||
if errors:
|
||||
raise InvalidPackageInfo(errors)
|
||||
|
@ -64,6 +64,13 @@ class RepositoryPaths:
|
||||
"""
|
||||
return self.root / "packages" / self.architecture
|
||||
|
||||
@property
|
||||
def patches(self) -> Path:
|
||||
"""
|
||||
:return: directory for source patches
|
||||
"""
|
||||
return self.root / "patches"
|
||||
|
||||
@property
|
||||
def repository(self) -> Path:
|
||||
"""
|
||||
@ -92,6 +99,14 @@ class RepositoryPaths:
|
||||
if path.is_dir()
|
||||
}
|
||||
|
||||
def cache_for(self, package_base: str) -> Path:
|
||||
"""
|
||||
get cache path for specific package base
|
||||
:param package_base: package base name
|
||||
:return: full path to directory for specified package base cache
|
||||
"""
|
||||
return self.cache / package_base
|
||||
|
||||
def create_tree(self) -> None:
|
||||
"""
|
||||
create ahriman working tree
|
||||
@ -100,5 +115,30 @@ class RepositoryPaths:
|
||||
self.chroot.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
self.manual.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
self.packages.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
self.patches.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
self.repository.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
self.sources.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
|
||||
def manual_for(self, package_base: str) -> Path:
|
||||
"""
|
||||
get manual path for specific package base
|
||||
:param package_base: package base name
|
||||
:return: full path to directory for specified package base manual updates
|
||||
"""
|
||||
return self.manual / package_base
|
||||
|
||||
def patches_for(self, package_base: str) -> Path:
|
||||
"""
|
||||
get patches path for specific package base
|
||||
:param package_base: package base name
|
||||
:return: full path to directory for specified package base patches
|
||||
"""
|
||||
return self.patches / package_base
|
||||
|
||||
def sources_for(self, package_base: str) -> Path:
|
||||
"""
|
||||
get sources path for specific package base
|
||||
:param package_base: package base name
|
||||
:return: full path to directory for specified package base sources
|
||||
"""
|
||||
return self.sources / package_base
|
||||
|
@ -124,10 +124,10 @@ def test_add_manual(application: Application, package_ahriman: Package, mocker:
|
||||
"""
|
||||
mocker.patch("ahriman.application.application.Application._known_packages", return_value=set())
|
||||
mocker.patch("ahriman.models.package.Package.load", return_value=package_ahriman)
|
||||
fetch_mock = mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
load_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
|
||||
application.add([package_ahriman.base], PackageSource.AUR, True)
|
||||
fetch_mock.assert_called_once()
|
||||
load_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_add_manual_with_dependencies(application: Application, package_ahriman: Package,
|
||||
@ -137,7 +137,7 @@ def test_add_manual_with_dependencies(application: Application, package_ahriman:
|
||||
"""
|
||||
mocker.patch("ahriman.application.application.Application._known_packages", return_value=set())
|
||||
mocker.patch("ahriman.models.package.Package.load", return_value=package_ahriman)
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
dependencies_mock = mocker.patch("ahriman.models.package.Package.dependencies")
|
||||
|
||||
application.add([package_ahriman.base], PackageSource.AUR, False)
|
||||
|
107
tests/ahriman/core/build_tools/test_sources.py
Normal file
107
tests/ahriman/core/build_tools/test_sources.py
Normal file
@ -0,0 +1,107 @@
|
||||
import pytest
|
||||
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest import mock
|
||||
|
||||
from ahriman.core.build_tools.sources import Sources
|
||||
|
||||
|
||||
def test_fetch_existing(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must fetch new package via clone command
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
local = Path("local")
|
||||
Sources.fetch(local, "remote", "master")
|
||||
check_output_mock.assert_has_calls([
|
||||
mock.call("git", "fetch", "origin", "master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "checkout", "--force", "master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "reset", "--hard", "origin/master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
])
|
||||
|
||||
|
||||
def test_fetch_new(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must fetch new package via clone command
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=False)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
local = Path("local")
|
||||
Sources.fetch(local, "remote", "master")
|
||||
check_output_mock.assert_has_calls([
|
||||
mock.call("git", "clone", "remote", str(local),
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "checkout", "--force", "master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "reset", "--hard", "origin/master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
])
|
||||
|
||||
|
||||
def test_load(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must load packages sources correctly
|
||||
"""
|
||||
fetch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.fetch")
|
||||
patch_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.patch")
|
||||
|
||||
Sources.load(Path("local"), "remote", Path("patches"))
|
||||
fetch_mock.assert_called_with(Path("local"), "remote")
|
||||
patch_mock.assert_called_with(Path("local"), Path("patches"))
|
||||
|
||||
|
||||
def test_patches(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must apply patches if any
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
glob_mock = mocker.patch("pathlib.Path.glob", return_value=[Path("01.patch"), Path("02.patch")])
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
local = Path("local")
|
||||
Sources.patch(local, Path("patches"))
|
||||
glob_mock.assert_called_once()
|
||||
check_output_mock.assert_has_calls([
|
||||
mock.call("git", "apply", "--ignore-space-change", "--ignore-whitespace", "01.patch",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "apply", "--ignore-space-change", "--ignore-whitespace", "02.patch",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
])
|
||||
|
||||
|
||||
def test_patches_no_dir(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must not fail if no patches directory exists
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=False)
|
||||
glob_mock = mocker.patch("pathlib.Path.glob")
|
||||
|
||||
Sources.patch(Path("local"), Path("patches"))
|
||||
glob_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_patches_no_patches(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must not fail if no patches exist
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
mocker.patch("pathlib.Path.glob", return_value=[])
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.sources.Sources._check_output")
|
||||
|
||||
Sources.patch(Path("local"), Path("patches"))
|
||||
check_output_mock.assert_not_called()
|
@ -1,56 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from pathlib import Path
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest import mock
|
||||
|
||||
from ahriman.core.build_tools.task import Task
|
||||
|
||||
|
||||
def test_fetch_existing(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must fetch new package via clone command
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.task.Task._check_output")
|
||||
|
||||
local = Path("local")
|
||||
Task.fetch(local, "remote", "master")
|
||||
check_output_mock.assert_has_calls([
|
||||
mock.call("git", "fetch", "origin", "master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "checkout", "--force", "master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "reset", "--hard", "origin/master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
])
|
||||
|
||||
|
||||
def test_fetch_new(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must fetch new package via clone command
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=False)
|
||||
check_output_mock = mocker.patch("ahriman.core.build_tools.task.Task._check_output")
|
||||
|
||||
local = Path("local")
|
||||
Task.fetch(local, "remote", "master")
|
||||
check_output_mock.assert_has_calls([
|
||||
mock.call("git", "clone", "remote", str(local),
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "checkout", "--force", "master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int)),
|
||||
mock.call("git", "reset", "--hard", "origin/master",
|
||||
exception=pytest.helpers.anyvar(int),
|
||||
cwd=local, logger=pytest.helpers.anyvar(int))
|
||||
])
|
||||
|
||||
|
||||
def test_build(task_ahriman: Task, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must build package
|
||||
@ -65,7 +17,7 @@ def test_init_with_cache(task_ahriman: Task, mocker: MockerFixture) -> None:
|
||||
must copy tree instead of fetch
|
||||
"""
|
||||
mocker.patch("pathlib.Path.is_dir", return_value=True)
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
copytree_mock = mocker.patch("shutil.copytree")
|
||||
|
||||
task_ahriman.init(None)
|
||||
|
@ -2,6 +2,7 @@ from pytest_mock import MockerFixture
|
||||
|
||||
from ahriman.core.tree import Leaf, Tree
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
def test_leaf_is_root_empty(leaf_ahriman: Leaf) -> None:
|
||||
@ -34,25 +35,25 @@ def test_leaf_is_root_true(leaf_ahriman: Leaf, leaf_python_schedule: Leaf) -> No
|
||||
assert not leaf_ahriman.is_root([leaf_python_schedule])
|
||||
|
||||
|
||||
def test_leaf_load(package_ahriman: Package, mocker: MockerFixture) -> None:
|
||||
def test_leaf_load(package_ahriman: Package, repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must load with dependencies
|
||||
"""
|
||||
tempdir_mock = mocker.patch("tempfile.mkdtemp")
|
||||
fetch_mock = mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
load_mock = mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
dependencies_mock = mocker.patch("ahriman.models.package.Package.dependencies", return_value={"ahriman-dependency"})
|
||||
rmtree_mock = mocker.patch("shutil.rmtree")
|
||||
|
||||
leaf = Leaf.load(package_ahriman)
|
||||
leaf = Leaf.load(package_ahriman, repository_paths)
|
||||
assert leaf.package == package_ahriman
|
||||
assert leaf.dependencies == {"ahriman-dependency"}
|
||||
tempdir_mock.assert_called_once()
|
||||
fetch_mock.assert_called_once()
|
||||
load_mock.assert_called_once()
|
||||
dependencies_mock.assert_called_once()
|
||||
rmtree_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_tree_levels(leaf_ahriman: Leaf, leaf_python_schedule: Leaf, mocker: MockerFixture) -> None:
|
||||
def test_tree_levels(leaf_ahriman: Leaf, leaf_python_schedule: Leaf) -> None:
|
||||
"""
|
||||
must generate correct levels in the simples case
|
||||
"""
|
||||
@ -65,14 +66,15 @@ def test_tree_levels(leaf_ahriman: Leaf, leaf_python_schedule: Leaf, mocker: Moc
|
||||
assert second == [leaf_ahriman.package]
|
||||
|
||||
|
||||
def test_tree_load(package_ahriman: Package, package_python_schedule: Package, mocker: MockerFixture) -> None:
|
||||
def test_tree_load(package_ahriman: Package, package_python_schedule: Package,
|
||||
repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must package list
|
||||
"""
|
||||
mocker.patch("tempfile.mkdtemp")
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
mocker.patch("ahriman.models.package.Package.dependencies")
|
||||
mocker.patch("shutil.rmtree")
|
||||
|
||||
tree = Tree.load([package_ahriman, package_python_schedule])
|
||||
tree = Tree.load([package_ahriman, package_python_schedule], repository_paths)
|
||||
assert len(tree.leaves) == 2
|
||||
|
@ -244,7 +244,7 @@ def test_actual_version_vcs(package_tpacpi_bat_git: Package, repository_paths: R
|
||||
"""
|
||||
srcinfo = (resource_path_root / "models" / "package_tpacpi-bat-git_srcinfo").read_text()
|
||||
mocker.patch("ahriman.models.package.Package._check_output", return_value=srcinfo)
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
|
||||
assert package_tpacpi_bat_git.actual_version(repository_paths) == "3.1.r13.g4959b52-1"
|
||||
|
||||
@ -255,7 +255,7 @@ def test_actual_version_srcinfo_failed(package_tpacpi_bat_git: Package, reposito
|
||||
must return same version in case if exception occurred
|
||||
"""
|
||||
mocker.patch("ahriman.models.package.Package._check_output", side_effect=Exception())
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
|
||||
assert package_tpacpi_bat_git.actual_version(repository_paths) == package_tpacpi_bat_git.version
|
||||
|
||||
@ -268,7 +268,7 @@ def test_actual_version_vcs_failed(package_tpacpi_bat_git: Package, repository_p
|
||||
mocker.patch("pathlib.Path.read_text", return_value="")
|
||||
mocker.patch("ahriman.models.package.parse_srcinfo", return_value=({"packages": {}}, ["an error"]))
|
||||
mocker.patch("ahriman.models.package.Package._check_output")
|
||||
mocker.patch("ahriman.core.build_tools.task.Task.fetch")
|
||||
mocker.patch("ahriman.core.build_tools.sources.Sources.load")
|
||||
|
||||
assert package_tpacpi_bat_git.actual_version(repository_paths) == package_tpacpi_bat_git.version
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
from pytest_mock import MockerFixture
|
||||
from unittest import mock
|
||||
|
||||
from ahriman.models.package import Package
|
||||
from ahriman.models.repository_paths import RepositoryPaths
|
||||
|
||||
|
||||
@ -13,6 +14,15 @@ def test_known_architectures(repository_paths: RepositoryPaths, mocker: MockerFi
|
||||
iterdir_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_cache_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must return correct path for cache directory
|
||||
"""
|
||||
path = repository_paths.cache_for(package_ahriman.base)
|
||||
assert path.name == package_ahriman.base
|
||||
assert path.parent == repository_paths.cache
|
||||
|
||||
|
||||
def test_create_tree(repository_paths: RepositoryPaths, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must create whole tree
|
||||
@ -20,7 +30,9 @@ def test_create_tree(repository_paths: RepositoryPaths, mocker: MockerFixture) -
|
||||
paths = {
|
||||
prop
|
||||
for prop in dir(repository_paths)
|
||||
if not prop.startswith("_") and prop not in ("architecture", "create_tree", "known_architectures", "root")
|
||||
if not prop.startswith("_")
|
||||
and not prop.endswith("_for")
|
||||
and prop not in ("architecture", "create_tree", "known_architectures", "root")
|
||||
}
|
||||
mkdir_mock = mocker.patch("pathlib.Path.mkdir")
|
||||
|
||||
@ -30,3 +42,30 @@ def test_create_tree(repository_paths: RepositoryPaths, mocker: MockerFixture) -
|
||||
mock.call(mode=0o755, parents=True, exist_ok=True)
|
||||
for _ in paths
|
||||
])
|
||||
|
||||
|
||||
def test_manual_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must return correct path for manual directory
|
||||
"""
|
||||
path = repository_paths.manual_for(package_ahriman.base)
|
||||
assert path.name == package_ahriman.base
|
||||
assert path.parent == repository_paths.manual
|
||||
|
||||
|
||||
def test_patches_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must return correct path for patches directory
|
||||
"""
|
||||
path = repository_paths.patches_for(package_ahriman.base)
|
||||
assert path.name == package_ahriman.base
|
||||
assert path.parent == repository_paths.patches
|
||||
|
||||
|
||||
def test_sources_for(repository_paths: RepositoryPaths, package_ahriman: Package) -> None:
|
||||
"""
|
||||
must return correct path for sources directory
|
||||
"""
|
||||
path = repository_paths.sources_for(package_ahriman.base)
|
||||
assert path.name == package_ahriman.base
|
||||
assert path.parent == repository_paths.sources
|
||||
|
Loading…
Reference in New Issue
Block a user