mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-09-08 01:39:56 +00:00
Compare commits
5 Commits
7f223ecc0a
...
11c8b3f637
Author | SHA1 | Date | |
---|---|---|---|
11c8b3f637 | |||
3e5dbbd6cd | |||
f41e44895d | |||
765bbf486f | |||
a3c54afb82 |
@ -24,6 +24,13 @@
|
|||||||
<datalist id="package-add-known-packages-dlist"></datalist>
|
<datalist id="package-add-known-packages-dlist"></datalist>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-3 col-form-label"></label>
|
||||||
|
<div class="col-9">
|
||||||
|
<input id="package-add-refresh-input" type="checkbox" class="form-check-input" value="" checked>
|
||||||
|
<label for="package-add-refresh-input" class="form-check-label">refresh pacman databases</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<button id="package-add-variable-button" type="button" class="form-control btn btn-light rounded" onclick="packageAddVariableInputCreate()"><i class="bi bi-plus"></i> add environment variable </button>
|
<button id="package-add-variable-button" type="button" class="form-control btn btn-light rounded" onclick="packageAddVariableInputCreate()"><i class="bi bi-plus"></i> add environment variable </button>
|
||||||
@ -50,6 +57,8 @@
|
|||||||
|
|
||||||
const packageAddVariablesDiv = document.getElementById("package-add-variables-div");
|
const packageAddVariablesDiv = document.getElementById("package-add-variables-div");
|
||||||
|
|
||||||
|
const packageAddRefreshInput = document.getElementById("package-add-refresh-input");
|
||||||
|
|
||||||
function packageAddVariableInputCreate() {
|
function packageAddVariableInputCreate() {
|
||||||
const variableInput = document.createElement("div");
|
const variableInput = document.createElement("div");
|
||||||
variableInput.classList.add("input-group");
|
variableInput.classList.add("input-group");
|
||||||
@ -103,12 +112,13 @@
|
|||||||
packages = packages ?? packageAddInput.value;
|
packages = packages ?? packageAddInput.value;
|
||||||
patches = patches ?? patchesParse();
|
patches = patches ?? patchesParse();
|
||||||
repository = repository ?? getRepositorySelector(packageAddRepositoryInput);
|
repository = repository ?? getRepositorySelector(packageAddRepositoryInput);
|
||||||
|
const parameters = Object.assign({}, {refresh: packageAddRefreshInput.checked}, patches);
|
||||||
|
|
||||||
if (packages) {
|
if (packages) {
|
||||||
bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
|
bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
|
||||||
const onSuccess = update => `Packages ${update} have been added`;
|
const onSuccess = update => `Packages ${update} have been added`;
|
||||||
const onFailure = error => `Package addition failed: ${error}`;
|
const onFailure = error => `Package addition failed: ${error}`;
|
||||||
doPackageAction("/api/v1/service/add", [packages], repository, onSuccess, onFailure, patches);
|
doPackageAction("/api/v1/service/add", [packages], repository, onSuccess, onFailure, parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,18 +133,18 @@ class Application(ApplicationPackages, ApplicationRepository):
|
|||||||
if not process_dependencies or not packages:
|
if not process_dependencies or not packages:
|
||||||
return packages
|
return packages
|
||||||
|
|
||||||
def missing_dependencies(source: Iterable[Package]) -> dict[str, str | None]:
|
def missing_dependencies(sources: Iterable[Package]) -> dict[str, str | None]:
|
||||||
# append list of known packages with packages which are in current sources
|
# append list of known packages with packages which are in current sources
|
||||||
satisfied_packages = known_packages | {
|
satisfied_packages = known_packages | {
|
||||||
single
|
single
|
||||||
for package in source
|
for source in sources
|
||||||
for single in package.packages_full
|
for single in source.packages_full
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dependency: package.packager
|
dependency: source.packager
|
||||||
for package in source
|
for source in sources
|
||||||
for dependency in package.depends_build
|
for dependency in source.depends_build
|
||||||
if dependency not in satisfied_packages
|
if dependency not in satisfied_packages
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ class Application(ApplicationPackages, ApplicationRepository):
|
|||||||
# there is local cache, load package from it
|
# there is local cache, load package from it
|
||||||
leaf = Package.from_build(source_dir, self.repository.architecture, packager)
|
leaf = Package.from_build(source_dir, self.repository.architecture, packager)
|
||||||
else:
|
else:
|
||||||
leaf = Package.from_aur(package_name, packager)
|
leaf = Package.from_aur(package_name, packager, include_provides=True)
|
||||||
portion[leaf.base] = leaf
|
portion[leaf.base] = leaf
|
||||||
|
|
||||||
# register package in the database
|
# register package in the database
|
||||||
|
@ -255,3 +255,19 @@ class Pacman(LazyLogging):
|
|||||||
result.update(trim_package(provides) for provides in package.provides)
|
result.update(trim_package(provides) for provides in package.provides)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def provided_by(self, package_name: str) -> Generator[Package, None, None]:
|
||||||
|
"""
|
||||||
|
search through databases and emit packages which provides the ``package_name``
|
||||||
|
|
||||||
|
Args:
|
||||||
|
package_name(str): package name to search
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
Package: list of packages which were returned by the query
|
||||||
|
"""
|
||||||
|
def is_package_provided(package: Package) -> bool:
|
||||||
|
return package_name in package.provides
|
||||||
|
|
||||||
|
for database in self.handle.get_syncdbs():
|
||||||
|
yield from filter(is_package_provided, database.search(package_name))
|
||||||
|
@ -97,20 +97,17 @@ class AUR(Remote):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AURPackage]: response parsed to package list
|
list[AURPackage]: response parsed to package list
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
PackageInfoError: if multiple arguments are passed
|
||||||
"""
|
"""
|
||||||
query: list[tuple[str, str]] = [
|
if len(args) != 1:
|
||||||
("type", request_type),
|
raise PackageInfoError("AUR API requires exactly one argument to search")
|
||||||
("v", self.DEFAULT_RPC_VERSION),
|
|
||||||
]
|
|
||||||
|
|
||||||
arg_query = "arg[]" if len(args) > 1 else "arg"
|
url = f"{self.DEFAULT_RPC_URL}/v{self.DEFAULT_RPC_VERSION}/{request_type}/{args[0]}"
|
||||||
for arg in args:
|
query = list(kwargs.items())
|
||||||
query.append((arg_query, arg))
|
|
||||||
|
|
||||||
for key, value in kwargs.items():
|
response = self.make_request("GET", url, params=query)
|
||||||
query.append((key, value))
|
|
||||||
|
|
||||||
response = self.make_request("GET", self.DEFAULT_RPC_URL, params=query)
|
|
||||||
return self.parse_response(response.json())
|
return self.parse_response(response.json())
|
||||||
|
|
||||||
def package_info(self, package_name: str, *, pacman: Pacman | None) -> AURPackage:
|
def package_info(self, package_name: str, *, pacman: Pacman | None) -> AURPackage:
|
||||||
@ -133,15 +130,36 @@ class AUR(Remote):
|
|||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise UnknownPackageError(package_name) from None
|
raise UnknownPackageError(package_name) from None
|
||||||
|
|
||||||
def package_search(self, *keywords: str, pacman: Pacman | None) -> list[AURPackage]:
|
def package_provided_by(self, package_name: str, *, pacman: Pacman | None) -> list[AURPackage]:
|
||||||
|
"""
|
||||||
|
get package list which provide the specified package name
|
||||||
|
|
||||||
|
Args:
|
||||||
|
package_name(str): package name to search
|
||||||
|
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[AURPackage]: list of packages which match the criteria
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
package
|
||||||
|
# search api provides reduced models
|
||||||
|
for stub in self.package_search(package_name, pacman=pacman, search_by="provides")
|
||||||
|
# verity that found package actually provides it
|
||||||
|
if package_name in (package := self.package_info(stub.package_base, pacman=pacman)).provides
|
||||||
|
]
|
||||||
|
|
||||||
|
def package_search(self, *keywords: str, pacman: Pacman | None, search_by: str | None) -> list[AURPackage]:
|
||||||
"""
|
"""
|
||||||
search package in AUR web
|
search package in AUR web
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*keywords(str): keywords to search
|
*keywords(str): keywords to search
|
||||||
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
||||||
|
search_by(str | None): search by keywords
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AURPackage]: list of packages which match the criteria
|
list[AURPackage]: list of packages which match the criteria
|
||||||
"""
|
"""
|
||||||
return self.aur_request("search", *keywords, by="name-desc")
|
search_by = search_by or "name-desc"
|
||||||
|
return self.aur_request("search", *keywords, by=search_by)
|
||||||
|
@ -127,15 +127,17 @@ class Official(Remote):
|
|||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise UnknownPackageError(package_name) from None
|
raise UnknownPackageError(package_name) from None
|
||||||
|
|
||||||
def package_search(self, *keywords: str, pacman: Pacman | None) -> list[AURPackage]:
|
def package_search(self, *keywords: str, pacman: Pacman | None, search_by: str | None) -> list[AURPackage]:
|
||||||
"""
|
"""
|
||||||
search package in AUR web
|
search package in AUR web
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*keywords(str): keywords to search
|
*keywords(str): keywords to search
|
||||||
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
||||||
|
search_by(str | None): search by keywords
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AURPackage]: list of packages which match the criteria
|
list[AURPackage]: list of packages which match the criteria
|
||||||
"""
|
"""
|
||||||
return self.arch_request(*keywords, by="q")
|
search_by = search_by or "q"
|
||||||
|
return self.arch_request(*keywords, by=search_by)
|
||||||
|
@ -59,3 +59,22 @@ class OfficialSyncdb(Official):
|
|||||||
return next(AURPackage.from_pacman(package) for package in pacman.package(package_name))
|
return next(AURPackage.from_pacman(package) for package in pacman.package(package_name))
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise UnknownPackageError(package_name) from None
|
raise UnknownPackageError(package_name) from None
|
||||||
|
|
||||||
|
def package_provided_by(self, package_name: str, *, pacman: Pacman | None) -> list[AURPackage]:
|
||||||
|
"""
|
||||||
|
get package list which provide the specified package name
|
||||||
|
|
||||||
|
Args:
|
||||||
|
package_name(str): package name to search
|
||||||
|
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[AURPackage]: list of packages which match the criteria
|
||||||
|
"""
|
||||||
|
if pacman is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return [
|
||||||
|
AURPackage.from_pacman(package)
|
||||||
|
for package in pacman.provided_by(package_name)
|
||||||
|
]
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from ahriman.core.alpm.pacman import Pacman
|
from ahriman.core.alpm.pacman import Pacman
|
||||||
|
from ahriman.core.exceptions import UnknownPackageError
|
||||||
from ahriman.core.http import SyncHttpClient
|
from ahriman.core.http import SyncHttpClient
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
@ -41,22 +42,36 @@ class Remote(SyncHttpClient):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def info(cls, package_name: str, *, pacman: Pacman | None = None) -> AURPackage:
|
def info(cls, package_name: str, *, pacman: Pacman | None = None, include_provides: bool = False) -> AURPackage:
|
||||||
"""
|
"""
|
||||||
get package info by its name
|
get package info by its name. If ``include_provides`` is set to ``True``, then, in addition, this method
|
||||||
|
will perform search by :attr:`ahriman.models.aur_package.AURPackage.provides` and return first package found.
|
||||||
|
Note, however, that in this case some implementation might not provide this method and search result will might
|
||||||
|
not be stable
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
package_name(str): package name to search
|
package_name(str): package name to search
|
||||||
pacman(Pacman | None, optional): alpm wrapper instance, required for official repositories search
|
pacman(Pacman | None, optional): alpm wrapper instance, required for official repositories search
|
||||||
(Default value = None)
|
(Default value = None)
|
||||||
|
include_provides(bool, optional): search by provides if no exact match found (Default value = False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
AURPackage: package which match the package name
|
AURPackage: package which match the package name
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
UnknownPackageError: if requested package not found
|
||||||
"""
|
"""
|
||||||
return cls().package_info(package_name, pacman=pacman)
|
instance = cls()
|
||||||
|
try:
|
||||||
|
return instance.package_info(package_name, pacman=pacman)
|
||||||
|
except UnknownPackageError:
|
||||||
|
if include_provides and (provided_by := instance.package_provided_by(package_name, pacman=pacman)):
|
||||||
|
return next(iter(provided_by))
|
||||||
|
raise
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def multisearch(cls, *keywords: str, pacman: Pacman | None = None) -> list[AURPackage]:
|
def multisearch(cls, *keywords: str, pacman: Pacman | None = None,
|
||||||
|
search_by: str | None = None) -> list[AURPackage]:
|
||||||
"""
|
"""
|
||||||
search in remote repository by using API with multiple words. This method is required in order to handle
|
search in remote repository by using API with multiple words. This method is required in order to handle
|
||||||
https://bugs.archlinux.org/task/49133. In addition, short words will be dropped
|
https://bugs.archlinux.org/task/49133. In addition, short words will be dropped
|
||||||
@ -65,6 +80,7 @@ class Remote(SyncHttpClient):
|
|||||||
*keywords(str): search terms, e.g. "ahriman", "is", "cool"
|
*keywords(str): search terms, e.g. "ahriman", "is", "cool"
|
||||||
pacman(Pacman | None, optional): alpm wrapper instance, required for official repositories search
|
pacman(Pacman | None, optional): alpm wrapper instance, required for official repositories search
|
||||||
(Default value = None)
|
(Default value = None)
|
||||||
|
search_by(str | None, optional): search by keywords (Default value = None)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AURPackage]: list of packages each of them matches all search terms
|
list[AURPackage]: list of packages each of them matches all search terms
|
||||||
@ -72,7 +88,7 @@ class Remote(SyncHttpClient):
|
|||||||
instance = cls()
|
instance = cls()
|
||||||
packages: dict[str, AURPackage] = {}
|
packages: dict[str, AURPackage] = {}
|
||||||
for term in filter(lambda word: len(word) >= 3, keywords):
|
for term in filter(lambda word: len(word) >= 3, keywords):
|
||||||
portion = instance.search(term, pacman=pacman)
|
portion = instance.package_search(term, pacman=pacman, search_by=search_by)
|
||||||
packages = {
|
packages = {
|
||||||
package.name: package # not mistake to group them by name
|
package.name: package # not mistake to group them by name
|
||||||
for package in portion
|
for package in portion
|
||||||
@ -114,7 +130,7 @@ class Remote(SyncHttpClient):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def search(cls, *keywords: str, pacman: Pacman | None = None) -> list[AURPackage]:
|
def search(cls, *keywords: str, pacman: Pacman | None = None, search_by: str | None = None) -> list[AURPackage]:
|
||||||
"""
|
"""
|
||||||
search package in AUR web
|
search package in AUR web
|
||||||
|
|
||||||
@ -122,11 +138,12 @@ class Remote(SyncHttpClient):
|
|||||||
*keywords(str): search terms, e.g. "ahriman", "is", "cool"
|
*keywords(str): search terms, e.g. "ahriman", "is", "cool"
|
||||||
pacman(Pacman | None, optional): alpm wrapper instance, required for official repositories search
|
pacman(Pacman | None, optional): alpm wrapper instance, required for official repositories search
|
||||||
(Default value = None)
|
(Default value = None)
|
||||||
|
search_by(str | None, optional): search by keywords (Default value = None)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AURPackage]: list of packages which match the criteria
|
list[AURPackage]: list of packages which match the criteria
|
||||||
"""
|
"""
|
||||||
return cls().package_search(*keywords, pacman=pacman)
|
return cls().package_search(*keywords, pacman=pacman, search_by=search_by)
|
||||||
|
|
||||||
def package_info(self, package_name: str, *, pacman: Pacman | None) -> AURPackage:
|
def package_info(self, package_name: str, *, pacman: Pacman | None) -> AURPackage:
|
||||||
"""
|
"""
|
||||||
@ -144,13 +161,28 @@ class Remote(SyncHttpClient):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def package_search(self, *keywords: str, pacman: Pacman | None) -> list[AURPackage]:
|
def package_provided_by(self, package_name: str, *, pacman: Pacman | None) -> list[AURPackage]:
|
||||||
|
"""
|
||||||
|
get package list which provide the specified package name
|
||||||
|
|
||||||
|
Args:
|
||||||
|
package_name(str): package name to search
|
||||||
|
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[AURPackage]: list of packages which match the criteria
|
||||||
|
"""
|
||||||
|
del package_name, pacman
|
||||||
|
return []
|
||||||
|
|
||||||
|
def package_search(self, *keywords: str, pacman: Pacman | None, search_by: str | None) -> list[AURPackage]:
|
||||||
"""
|
"""
|
||||||
search package in AUR web
|
search package in AUR web
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*keywords(str): keywords to search
|
*keywords(str): keywords to search
|
||||||
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
pacman(Pacman | None): alpm wrapper instance, required for official repositories search
|
||||||
|
search_by(str | None): search by keywords
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[AURPackage]: list of packages which match the criteria
|
list[AURPackage]: list of packages which match the criteria
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import requests
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from typing import Any, IO, Literal
|
from typing import Any, IO, Literal
|
||||||
@ -70,7 +71,10 @@ class SyncHttpClient(LazyLogging):
|
|||||||
request.Session: created session object
|
request.Session: created session object
|
||||||
"""
|
"""
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
session.headers["User-Agent"] = f"ahriman/{__version__}"
|
python_version = ".".join(map(str, sys.version_info[:3])) # just major.minor.patch
|
||||||
|
session.headers["User-Agent"] = f"ahriman/{__version__}" \
|
||||||
|
f"{requests.utils.default_user_agent()}" \
|
||||||
|
f"python/{python_version}"
|
||||||
|
|
||||||
return session
|
return session
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ class Leaf:
|
|||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
dependencies(set[str]): list of package dependencies
|
dependencies(set[str]): list of package dependencies
|
||||||
|
items(list[str]): list of packages in this leaf including provides
|
||||||
package(Package): leaf package properties
|
package(Package): leaf package properties
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -42,17 +43,9 @@ class Leaf:
|
|||||||
package(Package): package properties
|
package(Package): package properties
|
||||||
"""
|
"""
|
||||||
self.package = package
|
self.package = package
|
||||||
|
# store frequently used properties
|
||||||
self.dependencies = package.depends_build
|
self.dependencies = package.depends_build
|
||||||
|
self.items = self.package.packages_full
|
||||||
@property
|
|
||||||
def items(self) -> Iterable[str]:
|
|
||||||
"""
|
|
||||||
extract all packages from the leaf
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Iterable[str]: packages containing in this leaf
|
|
||||||
"""
|
|
||||||
return self.package.packages.keys()
|
|
||||||
|
|
||||||
def is_dependency(self, packages: Iterable[Leaf]) -> bool:
|
def is_dependency(self, packages: Iterable[Leaf]) -> bool:
|
||||||
"""
|
"""
|
||||||
|
@ -136,7 +136,8 @@ def check_output(*args: str, exception: Exception | Callable[[int, list[str], st
|
|||||||
} | environment
|
} | environment
|
||||||
|
|
||||||
with subprocess.Popen(args, cwd=cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
with subprocess.Popen(args, cwd=cwd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
user=user, env=full_environment, text=True, encoding="utf8", bufsize=1) as process:
|
user=user, env=full_environment, text=True, encoding="utf8", errors="backslashreplace",
|
||||||
|
bufsize=1) as process:
|
||||||
if input_data is not None:
|
if input_data is not None:
|
||||||
input_channel = get_io(process, "stdin")
|
input_channel = get_io(process, "stdin")
|
||||||
input_channel.write(input_data)
|
input_channel.write(input_data)
|
||||||
|
@ -213,18 +213,19 @@ class Package(LazyLogging):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_aur(cls, name: str, packager: str | None = None) -> Self:
|
def from_aur(cls, name: str, packager: str | None = None, *, include_provides: bool = False) -> Self:
|
||||||
"""
|
"""
|
||||||
construct package properties from AUR page
|
construct package properties from AUR page
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name(str): package name (either base or normal name)
|
name(str): package name (either base or normal name)
|
||||||
packager(str | None, optional): packager to be used for this build (Default value = None)
|
packager(str | None, optional): packager to be used for this build (Default value = None)
|
||||||
|
include_provides(bool, optional): search by provides if no exact match found (Default value = False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Self: package properties
|
Self: package properties
|
||||||
"""
|
"""
|
||||||
package = AUR.info(name)
|
package = AUR.info(name, include_provides=include_provides)
|
||||||
|
|
||||||
remote = RemoteSource(
|
remote = RemoteSource(
|
||||||
source=PackageSource.AUR,
|
source=PackageSource.AUR,
|
||||||
@ -310,7 +311,8 @@ class Package(LazyLogging):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_official(cls, name: str, pacman: Pacman, packager: str | None = None, *, use_syncdb: bool = True) -> Self:
|
def from_official(cls, name: str, pacman: Pacman, packager: str | None = None, *, use_syncdb: bool = True,
|
||||||
|
include_provides: bool = False) -> Self:
|
||||||
"""
|
"""
|
||||||
construct package properties from official repository page
|
construct package properties from official repository page
|
||||||
|
|
||||||
@ -319,11 +321,13 @@ class Package(LazyLogging):
|
|||||||
pacman(Pacman): alpm wrapper instance
|
pacman(Pacman): alpm wrapper instance
|
||||||
packager(str | None, optional): packager to be used for this build (Default value = None)
|
packager(str | None, optional): packager to be used for this build (Default value = None)
|
||||||
use_syncdb(bool, optional): use pacman databases instead of official repositories RPC (Default value = True)
|
use_syncdb(bool, optional): use pacman databases instead of official repositories RPC (Default value = True)
|
||||||
|
include_provides(bool, optional): search by provides if no exact match found (Default value = False)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Self: package properties
|
Self: package properties
|
||||||
"""
|
"""
|
||||||
package = OfficialSyncdb.info(name, pacman=pacman) if use_syncdb else Official.info(name)
|
impl = OfficialSyncdb if use_syncdb else Official
|
||||||
|
package = impl.info(name, pacman=pacman, include_provides=include_provides)
|
||||||
|
|
||||||
remote = RemoteSource(
|
remote = RemoteSource(
|
||||||
source=PackageSource.Repository,
|
source=PackageSource.Repository,
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
|
from typing import Any
|
||||||
from unittest.mock import MagicMock, call as MockCall
|
from unittest.mock import MagicMock, call as MockCall
|
||||||
|
|
||||||
from ahriman.application.application import Application
|
from ahriman.application.application import Application
|
||||||
@ -73,6 +75,10 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
|
|||||||
mock.packages_full = [package_base]
|
mock.packages_full = [package_base]
|
||||||
return mock
|
return mock
|
||||||
|
|
||||||
|
def get_package(name: str | Path, *args: Any, **kwargs: Any) -> Package:
|
||||||
|
name = name if isinstance(name, str) else name.name
|
||||||
|
return packages[name]
|
||||||
|
|
||||||
package_python_schedule.packages = {
|
package_python_schedule.packages = {
|
||||||
package_python_schedule.base: package_python_schedule.packages[package_python_schedule.base]
|
package_python_schedule.base: package_python_schedule.packages[package_python_schedule.base]
|
||||||
}
|
}
|
||||||
@ -87,10 +93,8 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
|
|||||||
}
|
}
|
||||||
|
|
||||||
mocker.patch("pathlib.Path.is_dir", autospec=True, side_effect=lambda p: p.name == "python")
|
mocker.patch("pathlib.Path.is_dir", autospec=True, side_effect=lambda p: p.name == "python")
|
||||||
package_aur_mock = mocker.patch("ahriman.models.package.Package.from_aur",
|
package_aur_mock = mocker.patch("ahriman.models.package.Package.from_aur", side_effect=get_package)
|
||||||
side_effect=lambda *args: packages[args[0]])
|
package_local_mock = mocker.patch("ahriman.models.package.Package.from_build", side_effect=get_package)
|
||||||
package_local_mock = mocker.patch("ahriman.models.package.Package.from_build",
|
|
||||||
side_effect=lambda *args: packages[args[0].name])
|
|
||||||
packages_mock = mocker.patch("ahriman.application.application.Application._known_packages",
|
packages_mock = mocker.patch("ahriman.application.application.Application._known_packages",
|
||||||
return_value={"devtools", "python-build", "python-pytest"})
|
return_value={"devtools", "python-build", "python-pytest"})
|
||||||
status_client_mock = mocker.patch("ahriman.core.status.Client.set_unknown")
|
status_client_mock = mocker.patch("ahriman.core.status.Client.set_unknown")
|
||||||
@ -98,8 +102,8 @@ def test_with_dependencies(application: Application, package_ahriman: Package, p
|
|||||||
result = application.with_dependencies([package_ahriman], process_dependencies=True)
|
result = application.with_dependencies([package_ahriman], process_dependencies=True)
|
||||||
assert {package.base: package for package in result} == packages
|
assert {package.base: package for package in result} == packages
|
||||||
package_aur_mock.assert_has_calls([
|
package_aur_mock.assert_has_calls([
|
||||||
MockCall(package_python_schedule.base, package_ahriman.packager),
|
MockCall(package_python_schedule.base, package_ahriman.packager, include_provides=True),
|
||||||
MockCall("python-installer", package_ahriman.packager),
|
MockCall("python-installer", package_ahriman.packager, include_provides=True),
|
||||||
], any_order=True)
|
], any_order=True)
|
||||||
package_local_mock.assert_has_calls([
|
package_local_mock.assert_has_calls([
|
||||||
MockCall(application.repository.paths.cache_for("python"), "x86_64", package_ahriman.packager),
|
MockCall(application.repository.paths.cache_for("python"), "x86_64", package_ahriman.packager),
|
||||||
|
@ -4,7 +4,7 @@ import requests
|
|||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pytest_mock import MockerFixture
|
from pytest_mock import MockerFixture
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock, call as MockCall
|
||||||
|
|
||||||
from ahriman.core.alpm.remote import AUR
|
from ahriman.core.alpm.remote import AUR
|
||||||
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
|
from ahriman.core.exceptions import PackageInfoError, UnknownPackageError
|
||||||
@ -76,24 +76,18 @@ def test_aur_request(aur: AUR, aur_package_ahriman: AURPackage,
|
|||||||
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.make_request", return_value=response_mock)
|
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.make_request", return_value=response_mock)
|
||||||
|
|
||||||
assert aur.aur_request("info", "ahriman") == [aur_package_ahriman]
|
assert aur.aur_request("info", "ahriman") == [aur_package_ahriman]
|
||||||
request_mock.assert_called_once_with(
|
request_mock.assert_called_once_with("GET", "https://aur.archlinux.org/rpc/v5/info/ahriman", params=[])
|
||||||
"GET", "https://aur.archlinux.org/rpc",
|
|
||||||
params=[("type", "info"), ("v", "5"), ("arg", "ahriman")])
|
|
||||||
|
|
||||||
|
|
||||||
def test_aur_request_multi_arg(aur: AUR, aur_package_ahriman: AURPackage,
|
def test_aur_request_multi_arg(aur: AUR) -> None:
|
||||||
mocker: MockerFixture, resource_path_root: Path) -> None:
|
|
||||||
"""
|
"""
|
||||||
must perform request to AUR with multiple args
|
must raise PackageInfoError if invalid amount of arguments supplied
|
||||||
"""
|
"""
|
||||||
response_mock = MagicMock()
|
with pytest.raises(PackageInfoError):
|
||||||
response_mock.json.return_value = json.loads(_get_response(resource_path_root))
|
aur.aur_request("search", "ahriman", "is", "cool")
|
||||||
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.make_request", return_value=response_mock)
|
|
||||||
|
|
||||||
assert aur.aur_request("search", "ahriman", "is", "cool") == [aur_package_ahriman]
|
with pytest.raises(PackageInfoError):
|
||||||
request_mock.assert_called_once_with(
|
aur.aur_request("search")
|
||||||
"GET", "https://aur.archlinux.org/rpc",
|
|
||||||
params=[("type", "search"), ("v", "5"), ("arg[]", "ahriman"), ("arg[]", "is"), ("arg[]", "cool")])
|
|
||||||
|
|
||||||
|
|
||||||
def test_aur_request_with_kwargs(aur: AUR, aur_package_ahriman: AURPackage,
|
def test_aur_request_with_kwargs(aur: AUR, aur_package_ahriman: AURPackage,
|
||||||
@ -106,9 +100,8 @@ def test_aur_request_with_kwargs(aur: AUR, aur_package_ahriman: AURPackage,
|
|||||||
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.make_request", return_value=response_mock)
|
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.make_request", return_value=response_mock)
|
||||||
|
|
||||||
assert aur.aur_request("search", "ahriman", by="name") == [aur_package_ahriman]
|
assert aur.aur_request("search", "ahriman", by="name") == [aur_package_ahriman]
|
||||||
request_mock.assert_called_once_with(
|
request_mock.assert_called_once_with("GET", "https://aur.archlinux.org/rpc/v5/search/ahriman",
|
||||||
"GET", "https://aur.archlinux.org/rpc",
|
params=[("by", "name")])
|
||||||
params=[("type", "search"), ("v", "5"), ("arg", "ahriman"), ("by", "name")])
|
|
||||||
|
|
||||||
|
|
||||||
def test_aur_request_failed(aur: AUR, mocker: MockerFixture) -> None:
|
def test_aur_request_failed(aur: AUR, mocker: MockerFixture) -> None:
|
||||||
@ -139,17 +132,46 @@ def test_package_info(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerF
|
|||||||
|
|
||||||
def test_package_info_not_found(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
def test_package_info_not_found(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must raise UnknownPackage exception in case if no package was found
|
must raise UnknownPackageError in case if no package was found
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[])
|
mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[])
|
||||||
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
|
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
|
||||||
assert aur.package_info(aur_package_ahriman.name, pacman=None)
|
assert aur.package_info(aur_package_ahriman.name, pacman=None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_provided_by(aur: AUR, aur_package_ahriman: AURPackage, aur_package_akonadi: AURPackage,
|
||||||
|
mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must search for packages which provide required one
|
||||||
|
"""
|
||||||
|
aur_package_ahriman.provides.append(aur_package_ahriman.name)
|
||||||
|
search_mock = mocker.patch("ahriman.core.alpm.remote.AUR.package_search", return_value=[
|
||||||
|
aur_package_ahriman, aur_package_akonadi
|
||||||
|
])
|
||||||
|
info_mock = mocker.patch("ahriman.core.alpm.remote.AUR.package_info", side_effect=[
|
||||||
|
aur_package_ahriman, aur_package_akonadi
|
||||||
|
])
|
||||||
|
|
||||||
|
assert aur.package_provided_by(aur_package_ahriman.name, pacman=None) == [aur_package_ahriman]
|
||||||
|
search_mock.assert_called_once_with(aur_package_ahriman.name, pacman=None, search_by="provides")
|
||||||
|
info_mock.assert_has_calls([
|
||||||
|
MockCall(aur_package_ahriman.name, pacman=None), MockCall(aur_package_akonadi.name, pacman=None)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_package_search(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
def test_package_search(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must make request for search
|
must make request for search
|
||||||
"""
|
"""
|
||||||
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[aur_package_ahriman])
|
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request", return_value=[aur_package_ahriman])
|
||||||
assert aur.package_search(aur_package_ahriman.name, pacman=None) == [aur_package_ahriman]
|
assert aur.package_search(aur_package_ahriman.name, pacman=None, search_by=None) == [aur_package_ahriman]
|
||||||
request_mock.assert_called_once_with("search", aur_package_ahriman.name, by="name-desc")
|
request_mock.assert_called_once_with("search", aur_package_ahriman.name, by="name-desc")
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_search_provides(aur: AUR, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must make request for search with custom field
|
||||||
|
"""
|
||||||
|
request_mock = mocker.patch("ahriman.core.alpm.remote.AUR.aur_request")
|
||||||
|
aur.package_search(aur_package_ahriman.name, pacman=None, search_by="provides")
|
||||||
|
request_mock.assert_called_once_with("search", aur_package_ahriman.name, by="provides")
|
||||||
|
@ -106,7 +106,7 @@ def test_package_info(official: Official, aur_package_akonadi: AURPackage, mocke
|
|||||||
|
|
||||||
def test_package_info_not_found(official: Official, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
def test_package_info_not_found(official: Official, aur_package_ahriman: AURPackage, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must raise UnknownPackage exception in case if no package was found
|
must raise UnknownPackageError in case if no package was found
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.alpm.remote.Official.arch_request", return_value=[])
|
mocker.patch("ahriman.core.alpm.remote.Official.arch_request", return_value=[])
|
||||||
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
|
with pytest.raises(UnknownPackageError, match=aur_package_ahriman.name):
|
||||||
@ -119,5 +119,16 @@ def test_package_search(official: Official, aur_package_akonadi: AURPackage, moc
|
|||||||
"""
|
"""
|
||||||
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request",
|
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request",
|
||||||
return_value=[aur_package_akonadi])
|
return_value=[aur_package_akonadi])
|
||||||
assert official.package_search(aur_package_akonadi.name, pacman=None) == [aur_package_akonadi]
|
assert official.package_search(aur_package_akonadi.name, pacman=None, search_by=None) == [
|
||||||
|
aur_package_akonadi,
|
||||||
|
]
|
||||||
request_mock.assert_called_once_with(aur_package_akonadi.name, by="q")
|
request_mock.assert_called_once_with(aur_package_akonadi.name, by="q")
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_search_name(official: Official, aur_package_akonadi: AURPackage, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must make request for search with custom field
|
||||||
|
"""
|
||||||
|
request_mock = mocker.patch("ahriman.core.alpm.remote.Official.arch_request")
|
||||||
|
official.package_search(aur_package_akonadi.name, pacman=None, search_by="name")
|
||||||
|
request_mock.assert_called_once_with(aur_package_akonadi.name, by="name")
|
||||||
|
@ -16,18 +16,14 @@ def test_package_info(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURP
|
|||||||
mocker.patch("ahriman.models.aur_package.AURPackage.from_pacman", return_value=aur_package_akonadi)
|
mocker.patch("ahriman.models.aur_package.AURPackage.from_pacman", return_value=aur_package_akonadi)
|
||||||
get_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[aur_package_akonadi])
|
get_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[aur_package_akonadi])
|
||||||
|
|
||||||
package = official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman)
|
assert official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman) == aur_package_akonadi
|
||||||
get_mock.assert_called_once_with(aur_package_akonadi.name)
|
get_mock.assert_called_once_with(aur_package_akonadi.name)
|
||||||
assert package == aur_package_akonadi
|
|
||||||
|
|
||||||
|
|
||||||
def test_package_info_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage,
|
def test_package_info_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage) -> None:
|
||||||
mocker: MockerFixture) -> None:
|
|
||||||
"""
|
"""
|
||||||
must raise UnknownPackageError if no pacman set
|
must raise UnknownPackageError if no pacman set
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[aur_package_akonadi])
|
|
||||||
|
|
||||||
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
|
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
|
||||||
official_syncdb.package_info(aur_package_akonadi.name, pacman=None)
|
official_syncdb.package_info(aur_package_akonadi.name, pacman=None)
|
||||||
|
|
||||||
@ -40,3 +36,22 @@ def test_package_info_not_found(official_syncdb: OfficialSyncdb, aur_package_ako
|
|||||||
mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[])
|
mocker.patch("ahriman.core.alpm.pacman.Pacman.package", return_value=[])
|
||||||
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
|
with pytest.raises(UnknownPackageError, match=aur_package_akonadi.name):
|
||||||
assert official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman)
|
assert official_syncdb.package_info(aur_package_akonadi.name, pacman=pacman)
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_provided_by(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage, pacman: Pacman,
|
||||||
|
mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must search by provides in database
|
||||||
|
"""
|
||||||
|
mocker.patch("ahriman.models.aur_package.AURPackage.from_pacman", return_value=aur_package_akonadi)
|
||||||
|
get_mock = mocker.patch("ahriman.core.alpm.pacman.Pacman.provided_by", return_value=[aur_package_akonadi])
|
||||||
|
|
||||||
|
assert official_syncdb.package_provided_by(aur_package_akonadi.name, pacman=pacman) == [aur_package_akonadi]
|
||||||
|
get_mock.assert_called_once_with(aur_package_akonadi.name)
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_provided_by_no_pacman(official_syncdb: OfficialSyncdb, aur_package_akonadi: AURPackage) -> None:
|
||||||
|
"""
|
||||||
|
must return empty list if no pacman set
|
||||||
|
"""
|
||||||
|
assert official_syncdb.package_provided_by(aur_package_akonadi.name, pacman=None) == []
|
||||||
|
@ -5,16 +5,53 @@ from unittest.mock import call as MockCall
|
|||||||
|
|
||||||
from ahriman.core.alpm.pacman import Pacman
|
from ahriman.core.alpm.pacman import Pacman
|
||||||
from ahriman.core.alpm.remote import Remote
|
from ahriman.core.alpm.remote import Remote
|
||||||
|
from ahriman.core.exceptions import UnknownPackageError
|
||||||
from ahriman.models.aur_package import AURPackage
|
from ahriman.models.aur_package import AURPackage
|
||||||
|
|
||||||
|
|
||||||
def test_info(pacman: Pacman, mocker: MockerFixture) -> None:
|
def test_info(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must call info method
|
must call info method
|
||||||
"""
|
"""
|
||||||
info_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_info")
|
info_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_info", return_value=aur_package_ahriman)
|
||||||
Remote.info("ahriman", pacman=pacman)
|
assert Remote.info(aur_package_ahriman.name, pacman=pacman) == aur_package_ahriman
|
||||||
info_mock.assert_called_once_with("ahriman", pacman=pacman)
|
info_mock.assert_called_once_with(aur_package_ahriman.name, pacman=pacman)
|
||||||
|
|
||||||
|
|
||||||
|
def test_info_not_found(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must raise UnknownPackageError if no package found and search by provides is disabled
|
||||||
|
"""
|
||||||
|
mocker.patch("ahriman.core.alpm.remote.Remote.package_info",
|
||||||
|
side_effect=UnknownPackageError(aur_package_ahriman.name))
|
||||||
|
with pytest.raises(UnknownPackageError):
|
||||||
|
Remote.info(aur_package_ahriman.name, pacman=pacman)
|
||||||
|
|
||||||
|
|
||||||
|
def test_info_include_provides(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must perform search through provides list is set
|
||||||
|
"""
|
||||||
|
mocker.patch("ahriman.core.alpm.remote.Remote.package_info",
|
||||||
|
side_effect=UnknownPackageError(aur_package_ahriman.name))
|
||||||
|
provided_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_provided_by",
|
||||||
|
return_value=[aur_package_ahriman])
|
||||||
|
|
||||||
|
assert Remote.info(aur_package_ahriman.name, pacman=pacman, include_provides=True) == aur_package_ahriman
|
||||||
|
provided_mock.assert_called_once_with(aur_package_ahriman.name, pacman=pacman)
|
||||||
|
|
||||||
|
|
||||||
|
def test_info_include_provides_not_found(aur_package_ahriman: AURPackage, pacman: Pacman,
|
||||||
|
mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must raise UnknownPackageError if no package found and search by provides returns empty list
|
||||||
|
"""
|
||||||
|
mocker.patch("ahriman.core.alpm.remote.Remote.package_info",
|
||||||
|
side_effect=UnknownPackageError(aur_package_ahriman.name))
|
||||||
|
mocker.patch("ahriman.core.alpm.remote.Remote.package_provided_by", return_value=[])
|
||||||
|
|
||||||
|
with pytest.raises(UnknownPackageError):
|
||||||
|
Remote.info("ahriman", pacman=pacman, include_provides=True)
|
||||||
|
|
||||||
|
|
||||||
def test_multisearch(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
|
def test_multisearch(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: MockerFixture) -> None:
|
||||||
@ -22,10 +59,13 @@ def test_multisearch(aur_package_ahriman: AURPackage, pacman: Pacman, mocker: Mo
|
|||||||
must search in AUR with multiple words
|
must search in AUR with multiple words
|
||||||
"""
|
"""
|
||||||
terms = ["ahriman", "is", "cool"]
|
terms = ["ahriman", "is", "cool"]
|
||||||
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.search", return_value=[aur_package_ahriman])
|
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search", return_value=[aur_package_ahriman])
|
||||||
|
|
||||||
assert Remote.multisearch(*terms, pacman=pacman) == [aur_package_ahriman]
|
assert Remote.multisearch(*terms, pacman=pacman, search_by="name") == [aur_package_ahriman]
|
||||||
search_mock.assert_has_calls([MockCall("ahriman", pacman=pacman), MockCall("cool", pacman=pacman)])
|
search_mock.assert_has_calls([
|
||||||
|
MockCall("ahriman", pacman=pacman, search_by="name"),
|
||||||
|
MockCall("cool", pacman=pacman, search_by="name"),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def test_multisearch_empty(pacman: Pacman, mocker: MockerFixture) -> None:
|
def test_multisearch_empty(pacman: Pacman, mocker: MockerFixture) -> None:
|
||||||
@ -33,7 +73,7 @@ def test_multisearch_empty(pacman: Pacman, mocker: MockerFixture) -> None:
|
|||||||
must return empty list if no long terms supplied
|
must return empty list if no long terms supplied
|
||||||
"""
|
"""
|
||||||
terms = ["it", "is"]
|
terms = ["it", "is"]
|
||||||
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.search")
|
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search")
|
||||||
|
|
||||||
assert Remote.multisearch(*terms, pacman=pacman) == []
|
assert Remote.multisearch(*terms, pacman=pacman) == []
|
||||||
search_mock.assert_not_called()
|
search_mock.assert_not_called()
|
||||||
@ -43,9 +83,9 @@ def test_multisearch_single(aur_package_ahriman: AURPackage, pacman: Pacman, moc
|
|||||||
"""
|
"""
|
||||||
must search in AUR with one word
|
must search in AUR with one word
|
||||||
"""
|
"""
|
||||||
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.search", return_value=[aur_package_ahriman])
|
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search", return_value=[aur_package_ahriman])
|
||||||
assert Remote.multisearch("ahriman", pacman=pacman) == [aur_package_ahriman]
|
assert Remote.multisearch("ahriman", pacman=pacman) == [aur_package_ahriman]
|
||||||
search_mock.assert_called_once_with("ahriman", pacman=pacman)
|
search_mock.assert_called_once_with("ahriman", pacman=pacman, search_by=None)
|
||||||
|
|
||||||
|
|
||||||
def test_remote_git_url(remote: Remote) -> None:
|
def test_remote_git_url(remote: Remote) -> None:
|
||||||
@ -69,8 +109,8 @@ def test_search(pacman: Pacman, mocker: MockerFixture) -> None:
|
|||||||
must call search method
|
must call search method
|
||||||
"""
|
"""
|
||||||
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search")
|
search_mock = mocker.patch("ahriman.core.alpm.remote.Remote.package_search")
|
||||||
Remote.search("ahriman", pacman=pacman)
|
Remote.search("ahriman", pacman=pacman, search_by="name")
|
||||||
search_mock.assert_called_once_with("ahriman", pacman=pacman)
|
search_mock.assert_called_once_with("ahriman", pacman=pacman, search_by="name")
|
||||||
|
|
||||||
|
|
||||||
def test_package_info(remote: Remote, pacman: Pacman) -> None:
|
def test_package_info(remote: Remote, pacman: Pacman) -> None:
|
||||||
@ -81,9 +121,16 @@ def test_package_info(remote: Remote, pacman: Pacman) -> None:
|
|||||||
remote.package_info("package", pacman=pacman)
|
remote.package_info("package", pacman=pacman)
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_provided_by(remote: Remote, pacman: Pacman) -> None:
|
||||||
|
"""
|
||||||
|
must return empty list for provides method
|
||||||
|
"""
|
||||||
|
assert remote.package_provided_by("package", pacman=pacman) == []
|
||||||
|
|
||||||
|
|
||||||
def test_package_search(remote: Remote, pacman: Pacman) -> None:
|
def test_package_search(remote: Remote, pacman: Pacman) -> None:
|
||||||
"""
|
"""
|
||||||
must raise NotImplemented for missing package search method
|
must raise NotImplemented for missing package search method
|
||||||
"""
|
"""
|
||||||
with pytest.raises(NotImplementedError):
|
with pytest.raises(NotImplementedError):
|
||||||
remote.package_search("package", pacman=pacman)
|
remote.package_search("package", pacman=pacman, search_by=None)
|
||||||
|
@ -282,3 +282,10 @@ def test_packages_with_provides(pacman: Pacman) -> None:
|
|||||||
"""
|
"""
|
||||||
assert "sh" in pacman.packages()
|
assert "sh" in pacman.packages()
|
||||||
assert "mysql" in pacman.packages() # mariadb
|
assert "mysql" in pacman.packages() # mariadb
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_provided_by(pacman: Pacman) -> None:
|
||||||
|
"""
|
||||||
|
must search through the provides lists
|
||||||
|
"""
|
||||||
|
assert list(pacman.provided_by("sh"))
|
||||||
|
@ -195,6 +195,32 @@ def test_tree_levels_sorted() -> None:
|
|||||||
assert third == [leaf2.package, leaf4.package]
|
assert third == [leaf2.package, leaf4.package]
|
||||||
|
|
||||||
|
|
||||||
|
def test_tree_levels_provides() -> None:
|
||||||
|
"""
|
||||||
|
must build tree according to provides list
|
||||||
|
"""
|
||||||
|
leaf1 = Leaf(
|
||||||
|
Package(
|
||||||
|
base="package1",
|
||||||
|
version="1.0.0",
|
||||||
|
remote=RemoteSource(source=PackageSource.AUR),
|
||||||
|
packages={"package1": PackageDescription(depends=["package3"])},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
leaf2 = Leaf(
|
||||||
|
Package(
|
||||||
|
base="package2",
|
||||||
|
version="1.0.0",
|
||||||
|
remote=RemoteSource(source=PackageSource.AUR),
|
||||||
|
packages={"package2": PackageDescription(provides=["package3"])},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
first, second = Tree([leaf1, leaf2]).levels()
|
||||||
|
assert first == [leaf2.package]
|
||||||
|
assert second == [leaf1.package]
|
||||||
|
|
||||||
|
|
||||||
def test_tree_partitions() -> None:
|
def test_tree_partitions() -> None:
|
||||||
"""
|
"""
|
||||||
must divide tree into partitions
|
must divide tree into partitions
|
||||||
|
@ -150,6 +150,13 @@ def test_check_output_empty_line(mocker: MockerFixture) -> None:
|
|||||||
logger_mock.assert_has_calls([MockCall(""), MockCall("hello")])
|
logger_mock.assert_has_calls([MockCall(""), MockCall("hello")])
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_output_encoding_error(resource_path_root: Path) -> None:
|
||||||
|
"""
|
||||||
|
must correctly process unicode encoding error in command output
|
||||||
|
"""
|
||||||
|
assert check_output("cat", str(resource_path_root / "models" / "package_pacman-static_pkgbuild"))
|
||||||
|
|
||||||
|
|
||||||
def test_check_user(repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
def test_check_user(repository_id: RepositoryId, mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must check user correctly
|
must check user correctly
|
||||||
|
@ -167,15 +167,26 @@ def test_from_aur(package_ahriman: Package, aur_package_ahriman: AURPackage, moc
|
|||||||
"""
|
"""
|
||||||
must construct package from aur
|
must construct package from aur
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
|
info_mock = mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
|
||||||
|
|
||||||
package = Package.from_aur(package_ahriman.base, package_ahriman.packager)
|
package = Package.from_aur(package_ahriman.base, package_ahriman.packager)
|
||||||
|
info_mock.assert_called_once_with(package_ahriman.base, include_provides=False)
|
||||||
assert package_ahriman.base == package.base
|
assert package_ahriman.base == package.base
|
||||||
assert package_ahriman.version == package.version
|
assert package_ahriman.version == package.version
|
||||||
assert package_ahriman.packages.keys() == package.packages.keys()
|
assert package_ahriman.packages.keys() == package.packages.keys()
|
||||||
assert package_ahriman.packager == package.packager
|
assert package_ahriman.packager == package.packager
|
||||||
|
|
||||||
|
|
||||||
|
def test_from_aur_include_provides(package_ahriman: Package, aur_package_ahriman: AURPackage,
|
||||||
|
mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must construct package from aur by using provides list
|
||||||
|
"""
|
||||||
|
info_mock = mocker.patch("ahriman.core.alpm.remote.AUR.info", return_value=aur_package_ahriman)
|
||||||
|
Package.from_aur(package_ahriman.base, package_ahriman.packager, include_provides=True)
|
||||||
|
info_mock.assert_called_once_with(package_ahriman.base, include_provides=True)
|
||||||
|
|
||||||
|
|
||||||
def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_path_root: Path) -> None:
|
def test_from_build(package_ahriman: Package, mocker: MockerFixture, resource_path_root: Path) -> None:
|
||||||
"""
|
"""
|
||||||
must construct package from PKGBUILD
|
must construct package from PKGBUILD
|
||||||
@ -269,14 +280,25 @@ def test_from_json_view_3(package_tpacpi_bat_git: Package) -> None:
|
|||||||
assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git
|
assert Package.from_json(package_tpacpi_bat_git.view()) == package_tpacpi_bat_git
|
||||||
|
|
||||||
|
|
||||||
|
def test_from_official_include_provides(package_ahriman: Package, aur_package_ahriman: AURPackage, pacman: Pacman,
|
||||||
|
mocker: MockerFixture) -> None:
|
||||||
|
"""
|
||||||
|
must construct package from official repository
|
||||||
|
"""
|
||||||
|
info_mock = mocker.patch("ahriman.core.alpm.remote.Official.info", return_value=aur_package_ahriman)
|
||||||
|
Package.from_official(package_ahriman.base, pacman, package_ahriman.packager, include_provides=True)
|
||||||
|
info_mock.assert_called_once_with(package_ahriman.base, pacman=pacman, include_provides=True)
|
||||||
|
|
||||||
|
|
||||||
def test_from_official(package_ahriman: Package, aur_package_ahriman: AURPackage, pacman: Pacman,
|
def test_from_official(package_ahriman: Package, aur_package_ahriman: AURPackage, pacman: Pacman,
|
||||||
mocker: MockerFixture) -> None:
|
mocker: MockerFixture) -> None:
|
||||||
"""
|
"""
|
||||||
must construct package from official repository
|
must construct package from official repository
|
||||||
"""
|
"""
|
||||||
mocker.patch("ahriman.core.alpm.remote.Official.info", return_value=aur_package_ahriman)
|
info_mock = mocker.patch("ahriman.core.alpm.remote.Official.info", return_value=aur_package_ahriman)
|
||||||
|
|
||||||
package = Package.from_official(package_ahriman.base, pacman, package_ahriman.packager)
|
package = Package.from_official(package_ahriman.base, pacman, package_ahriman.packager)
|
||||||
|
info_mock.assert_called_once_with(package_ahriman.base, pacman=pacman, include_provides=False)
|
||||||
assert package_ahriman.base == package.base
|
assert package_ahriman.base == package.base
|
||||||
assert package_ahriman.version == package.version
|
assert package_ahriman.version == package.version
|
||||||
assert package_ahriman.packages.keys() == package.packages.keys()
|
assert package_ahriman.packages.keys() == package.packages.keys()
|
||||||
|
Reference in New Issue
Block a user