mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-05-05 04:33:50 +00:00
Compare commits
2 Commits
2f421e9923
...
25df9e488b
Author | SHA1 | Date | |
---|---|---|---|
25df9e488b | |||
883e54543f |
@ -17,7 +17,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from pathlib import Path
|
||||
from sqlite3 import Connection
|
||||
|
||||
from ahriman.core.database.operations.operations import Operations
|
||||
@ -46,13 +45,7 @@ class DependenciesOperations(Operations):
|
||||
|
||||
def run(connection: Connection) -> list[Dependencies]:
|
||||
return [
|
||||
Dependencies(
|
||||
row["package_base"],
|
||||
{
|
||||
Path(path): packages
|
||||
for path, packages in row["dependencies"].items()
|
||||
}
|
||||
)
|
||||
Dependencies(row["package_base"], row["dependencies"])
|
||||
for row in connection.execute(
|
||||
"""
|
||||
select package_base, dependencies from package_dependencies
|
||||
|
@ -108,7 +108,7 @@ class UpdateHandler(PackageInfo, Cleaner):
|
||||
filesystem = extract_files(required_packages)
|
||||
|
||||
for path, packages in dependencies.paths.items():
|
||||
found = filesystem.get(path, set())
|
||||
found = filesystem.get(Path(path), set())
|
||||
if found.intersection(packages):
|
||||
continue
|
||||
|
||||
|
@ -76,45 +76,17 @@ class Watcher(LazyLogging):
|
||||
for package, status in self.client.package_get(None)
|
||||
}
|
||||
|
||||
def logs_get(self, package_base: str, limit: int = -1, offset: int = 0) -> list[tuple[float, str]]:
|
||||
def package_add(self, package: Package, status: BuildStatusEnum) -> None:
|
||||
"""
|
||||
extract logs for the package base
|
||||
update package
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
|
||||
offset(int, optional): records offset (Default value = 0)
|
||||
|
||||
Returns:
|
||||
list[tuple[float, str]]: package logs
|
||||
package(Package): package description
|
||||
status(BuildStatusEnum): new build status
|
||||
"""
|
||||
_ = self.package_get(package_base)
|
||||
return self.client.package_logs_get(package_base, limit, offset)
|
||||
|
||||
def logs_remove(self, package_base: str, version: str | None) -> None:
|
||||
"""
|
||||
remove package related logs
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
version(str): package version
|
||||
"""
|
||||
self.client.package_logs_remove(package_base, version)
|
||||
|
||||
def logs_update(self, log_record_id: LogRecordId, created: float, message: str) -> None:
|
||||
"""
|
||||
make new log record into database
|
||||
|
||||
Args:
|
||||
log_record_id(LogRecordId): log record id
|
||||
created(float): log created timestamp
|
||||
message(str): log message
|
||||
"""
|
||||
if self._last_log_record_id != log_record_id:
|
||||
# there is new log record, so we remove old ones
|
||||
self.logs_remove(log_record_id.package_base, log_record_id.version)
|
||||
self._last_log_record_id = log_record_id
|
||||
self.client.package_logs_add(log_record_id, created, message)
|
||||
with self._lock:
|
||||
self._known[package.base] = (package, BuildStatus(status))
|
||||
self.client.package_add(package, status)
|
||||
|
||||
def package_changes_get(self, package_base: str) -> Changes:
|
||||
"""
|
||||
@ -129,6 +101,17 @@ class Watcher(LazyLogging):
|
||||
_ = self.package_get(package_base)
|
||||
return self.client.package_changes_get(package_base)
|
||||
|
||||
def package_changes_set(self, package_base: str, changes: Changes) -> None:
|
||||
"""
|
||||
update package changes
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
changes(Changes): package changes
|
||||
"""
|
||||
_ = self.package_get(package_base)
|
||||
self.client.package_changes_set(package_base, changes)
|
||||
|
||||
def package_dependencies_get(self, package_base: str) -> Dependencies:
|
||||
"""
|
||||
retrieve package dependencies
|
||||
@ -175,34 +158,47 @@ class Watcher(LazyLogging):
|
||||
except KeyError:
|
||||
raise UnknownPackageError(package_base) from None
|
||||
|
||||
def package_remove(self, package_base: str) -> None:
|
||||
def package_logs_get(self, package_base: str, limit: int = -1, offset: int = 0) -> list[tuple[float, str]]:
|
||||
"""
|
||||
remove package base from known list if any
|
||||
extract logs for the package base
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
"""
|
||||
with self._lock:
|
||||
self._known.pop(package_base, None)
|
||||
self.client.package_remove(package_base)
|
||||
self.logs_remove(package_base, None)
|
||||
limit(int, optional): limit records to the specified count, -1 means unlimited (Default value = -1)
|
||||
offset(int, optional): records offset (Default value = 0)
|
||||
|
||||
def package_update(self, package_base: str, status: BuildStatusEnum, package: Package | None) -> None:
|
||||
Returns:
|
||||
list[tuple[float, str]]: package logs
|
||||
"""
|
||||
update package status and description
|
||||
_ = self.package_get(package_base)
|
||||
return self.client.package_logs_get(package_base, limit, offset)
|
||||
|
||||
def package_logs_remove(self, package_base: str, version: str | None) -> None:
|
||||
"""
|
||||
remove package related logs
|
||||
|
||||
Args:
|
||||
package_base(str): package base to update
|
||||
status(BuildStatusEnum): new build status
|
||||
package(Package | None): optional package description. In case if not set current properties will be used
|
||||
package_base(str): package base
|
||||
version(str): package version
|
||||
"""
|
||||
if package is None:
|
||||
package, _ = self.package_get(package_base)
|
||||
with self._lock:
|
||||
self._known[package_base] = (package, BuildStatus(status))
|
||||
self.client.package_set(package_base, status)
|
||||
self.client.package_logs_remove(package_base, version)
|
||||
|
||||
def patches_get(self, package_base: str, variable: str | None) -> list[PkgbuildPatch]:
|
||||
def package_logs_update(self, log_record_id: LogRecordId, created: float, message: str) -> None:
|
||||
"""
|
||||
make new log record into database
|
||||
|
||||
Args:
|
||||
log_record_id(LogRecordId): log record id
|
||||
created(float): log created timestamp
|
||||
message(str): log message
|
||||
"""
|
||||
if self._last_log_record_id != log_record_id:
|
||||
# there is new log record, so we remove old ones
|
||||
self.package_logs_remove(log_record_id.package_base, log_record_id.version)
|
||||
self._last_log_record_id = log_record_id
|
||||
self.client.package_logs_add(log_record_id, created, message)
|
||||
|
||||
def package_patches_get(self, package_base: str, variable: str | None) -> list[PkgbuildPatch]:
|
||||
"""
|
||||
get patches for the package
|
||||
|
||||
@ -217,7 +213,7 @@ class Watcher(LazyLogging):
|
||||
# so here we skip checking if package exists or not
|
||||
return self.client.package_patches_get(package_base, variable)
|
||||
|
||||
def patches_remove(self, package_base: str, variable: str) -> None:
|
||||
def package_patches_remove(self, package_base: str, variable: str) -> None:
|
||||
"""
|
||||
remove package patch
|
||||
|
||||
@ -227,7 +223,7 @@ class Watcher(LazyLogging):
|
||||
"""
|
||||
self.client.package_patches_remove(package_base, variable)
|
||||
|
||||
def patches_update(self, package_base: str, patch: PkgbuildPatch) -> None:
|
||||
def package_patches_update(self, package_base: str, patch: PkgbuildPatch) -> None:
|
||||
"""
|
||||
update package patch
|
||||
|
||||
@ -237,6 +233,31 @@ class Watcher(LazyLogging):
|
||||
"""
|
||||
self.client.package_patches_add(package_base, patch)
|
||||
|
||||
def package_remove(self, package_base: str) -> None:
|
||||
"""
|
||||
remove package base from known list if any
|
||||
|
||||
Args:
|
||||
package_base(str): package base
|
||||
"""
|
||||
with self._lock:
|
||||
self._known.pop(package_base, None)
|
||||
self.client.package_remove(package_base)
|
||||
self.package_logs_remove(package_base, None)
|
||||
|
||||
def package_update(self, package_base: str, status: BuildStatusEnum) -> None:
|
||||
"""
|
||||
update package status
|
||||
|
||||
Args:
|
||||
package_base(str): package base to update
|
||||
status(BuildStatusEnum): new build status
|
||||
"""
|
||||
package, _ = self.package_get(package_base)
|
||||
with self._lock:
|
||||
self._known[package_base] = (package, BuildStatus(status))
|
||||
self.client.package_set(package_base, status)
|
||||
|
||||
def status_update(self, status: BuildStatusEnum) -> None:
|
||||
"""
|
||||
update service status
|
||||
|
@ -18,7 +18,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
from dataclasses import dataclass, field, fields
|
||||
from pathlib import Path
|
||||
from typing import Any, Self
|
||||
|
||||
from ahriman.core.util import dataclass_view, filter_json
|
||||
@ -31,11 +30,11 @@ class Dependencies:
|
||||
|
||||
Attributes:
|
||||
package_base(str): package base
|
||||
paths(dict[Path, list[str]]): map of the paths used by this package to set of packages in which they were found
|
||||
paths(dict[str, list[str]]): map of the paths used by this package to set of packages in which they were found
|
||||
"""
|
||||
|
||||
package_base: str
|
||||
paths: dict[Path, list[str]] = field(default_factory=dict)
|
||||
paths: dict[str, list[str]] = field(default_factory=dict)
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, dump: dict[str, Any]) -> Self:
|
||||
|
@ -99,7 +99,7 @@ class PackageArchive:
|
||||
"""
|
||||
dependencies, roots = self.depends_on_paths()
|
||||
|
||||
result: dict[Path, list[str]] = {}
|
||||
result: dict[str, list[str]] = {}
|
||||
for package, (directories, files) in self.installed_packages().items():
|
||||
if package in self.package.packages:
|
||||
continue # skip package itself
|
||||
@ -108,7 +108,7 @@ class PackageArchive:
|
||||
required_by.extend(library for library in files if library.name in dependencies)
|
||||
|
||||
for path in required_by:
|
||||
result.setdefault(path, []).append(package)
|
||||
result.setdefault(str(path), []).append(package)
|
||||
|
||||
return Dependencies(self.package.base, result)
|
||||
|
||||
|
@ -113,6 +113,6 @@ class ChangesView(StatusViewGuard, BaseView):
|
||||
raise HTTPBadRequest(reason=str(ex))
|
||||
|
||||
changes = Changes(last_commit_sha, change)
|
||||
self.service().client.package_changes_set(package_base, changes)
|
||||
self.service().package_changes_set(package_base, changes)
|
||||
|
||||
raise HTTPNoContent
|
||||
|
@ -70,7 +70,7 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
"""
|
||||
package_base = self.request.match_info["package"]
|
||||
version = self.request.query.get("version")
|
||||
self.service().logs_remove(package_base, version)
|
||||
self.service().package_logs_remove(package_base, version)
|
||||
|
||||
raise HTTPNoContent
|
||||
|
||||
@ -104,7 +104,7 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
|
||||
try:
|
||||
_, status = self.service().package_get(package_base)
|
||||
logs = self.service().logs_get(package_base)
|
||||
logs = self.service().package_logs_get(package_base)
|
||||
except UnknownPackageError:
|
||||
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
|
||||
|
||||
@ -150,6 +150,6 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
except Exception as ex:
|
||||
raise HTTPBadRequest(reason=str(ex))
|
||||
|
||||
self.service().logs_update(LogRecordId(package_base, version), created, record)
|
||||
self.service().package_logs_update(LogRecordId(package_base, version), created, record)
|
||||
|
||||
raise HTTPNoContent
|
||||
|
@ -152,7 +152,10 @@ class PackageView(StatusViewGuard, BaseView):
|
||||
raise HTTPBadRequest(reason=str(ex))
|
||||
|
||||
try:
|
||||
self.service().package_update(package_base, status, package)
|
||||
if package is None:
|
||||
self.service().package_update(package_base, status)
|
||||
else:
|
||||
self.service().package_add(package, status)
|
||||
except UnknownPackageError:
|
||||
raise HTTPBadRequest(reason=f"Package {package_base} is unknown, but no package body set")
|
||||
|
||||
|
@ -63,7 +63,7 @@ class PatchView(StatusViewGuard, BaseView):
|
||||
"""
|
||||
package_base = self.request.match_info["package"]
|
||||
variable = self.request.match_info["patch"]
|
||||
self.service().patches_remove(package_base, variable)
|
||||
self.service().package_patches_remove(package_base, variable)
|
||||
|
||||
raise HTTPNoContent
|
||||
|
||||
@ -95,7 +95,7 @@ class PatchView(StatusViewGuard, BaseView):
|
||||
package_base = self.request.match_info["package"]
|
||||
variable = self.request.match_info["patch"]
|
||||
|
||||
patches = self.service().patches_get(package_base, variable)
|
||||
patches = self.service().package_patches_get(package_base, variable)
|
||||
|
||||
selected = next((patch for patch in patches if patch.key == variable), None)
|
||||
if selected is None:
|
||||
|
@ -63,7 +63,7 @@ class PatchesView(StatusViewGuard, BaseView):
|
||||
Response: 200 with package patches on success
|
||||
"""
|
||||
package_base = self.request.match_info["package"]
|
||||
patches = self.service().patches_get(package_base, None)
|
||||
patches = self.service().package_patches_get(package_base, None)
|
||||
|
||||
response = [patch.view() for patch in patches]
|
||||
return json_response(response)
|
||||
@ -101,6 +101,6 @@ class PatchesView(StatusViewGuard, BaseView):
|
||||
except Exception as ex:
|
||||
raise HTTPBadRequest(reason=str(ex))
|
||||
|
||||
self.service().patches_update(package_base, PkgbuildPatch(key, value))
|
||||
self.service().package_patches_update(package_base, PkgbuildPatch(key, value))
|
||||
|
||||
raise HTTPNoContent
|
||||
|
@ -69,7 +69,7 @@ class LogsView(StatusViewGuard, BaseView):
|
||||
package_base = self.request.match_info["package"]
|
||||
limit, offset = self.page()
|
||||
try:
|
||||
logs = self.service().logs_get(package_base, limit, offset)
|
||||
logs = self.service().package_logs_get(package_base, limit, offset)
|
||||
except UnknownPackageError:
|
||||
raise HTTPNotFound(reason=f"Package {package_base} is unknown")
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
from ahriman.core.database import SQLite
|
||||
from ahriman.models.dependencies import Dependencies
|
||||
from ahriman.models.package import Package
|
||||
@ -10,11 +8,11 @@ def test_dependencies_insert_get(database: SQLite, package_ahriman: Package) ->
|
||||
"""
|
||||
must insert and get dependencies
|
||||
"""
|
||||
dependencies = Dependencies(package_ahriman.base, {Path("usr/lib/python3.11/site-packages"): ["python"]})
|
||||
dependencies = Dependencies(package_ahriman.base, {"usr/lib/python3.11/site-packages": ["python"]})
|
||||
database.dependencies_insert(dependencies)
|
||||
assert database.dependencies_get(package_ahriman.base) == [dependencies]
|
||||
|
||||
dependencies2 = Dependencies(package_ahriman.base, {Path("usr/lib/python3.11/site-packages"): ["python3"]})
|
||||
dependencies2 = Dependencies(package_ahriman.base, {"usr/lib/python3.11/site-packages": ["python3"]})
|
||||
database.dependencies_insert(dependencies2, RepositoryId("i686", database._repository_id.name))
|
||||
assert database.dependencies_get() == [dependencies]
|
||||
assert database.dependencies_get(package_ahriman.base) == [dependencies]
|
||||
@ -27,11 +25,11 @@ def test_dependencies_insert_remove(database: SQLite, package_ahriman: Package,
|
||||
"""
|
||||
must remove dependencies for the package
|
||||
"""
|
||||
dependencies1 = Dependencies(package_ahriman.base, {Path("usr"): ["python"]})
|
||||
dependencies1 = Dependencies(package_ahriman.base, {"usr": ["python"]})
|
||||
database.dependencies_insert(dependencies1)
|
||||
dependencies2 = Dependencies(package_python_schedule.base, {Path("usr"): ["filesystem"]})
|
||||
dependencies2 = Dependencies(package_python_schedule.base, {"usr": ["filesystem"]})
|
||||
database.dependencies_insert(dependencies2)
|
||||
dependencies3 = Dependencies(package_ahriman.base, {Path("usr"): ["python3"]})
|
||||
dependencies3 = Dependencies(package_ahriman.base, {"usr": ["python3"]})
|
||||
database.dependencies_insert(dependencies3, RepositoryId("i686", database._repository_id.name))
|
||||
|
||||
assert database.dependencies_get() == [dependencies1, dependencies2]
|
||||
@ -51,9 +49,9 @@ def test_dependencies_insert_remove_full(database: SQLite, package_ahriman: Pack
|
||||
"""
|
||||
must remove all dependencies for the repository
|
||||
"""
|
||||
database.dependencies_insert(Dependencies(package_ahriman.base, {Path("usr"): ["python"]}))
|
||||
database.dependencies_insert(Dependencies(package_python_schedule.base, {Path("usr"): ["filesystem"]}))
|
||||
database.dependencies_insert(Dependencies(package_ahriman.base, {Path("usr"): ["python3"]}),
|
||||
database.dependencies_insert(Dependencies(package_ahriman.base, {"usr": ["python"]}))
|
||||
database.dependencies_insert(Dependencies(package_python_schedule.base, {"usr": ["filesystem"]}))
|
||||
database.dependencies_insert(Dependencies(package_ahriman.base, {"usr": ["python3"]}),
|
||||
RepositoryId("i686", database._repository_id.name))
|
||||
|
||||
database.dependencies_remove(None)
|
||||
|
@ -155,10 +155,10 @@ def test_updates_dependencies(update_handler: UpdateHandler, package_ahriman: Pa
|
||||
return_value=[package_ahriman, package_python_schedule])
|
||||
dependencies = {
|
||||
package_ahriman.base: [
|
||||
Dependencies(package_ahriman.base, {Path("usr/lib/python3.11/site-packages"): ["python"]})
|
||||
Dependencies(package_ahriman.base, {"usr/lib/python3.11/site-packages": ["python"]})
|
||||
],
|
||||
package_python_schedule.base: [
|
||||
Dependencies(package_python_schedule.base, {Path("usr/lib/python3.12/site-packages"): ["python"]})
|
||||
Dependencies(package_python_schedule.base, {"usr/lib/python3.12/site-packages": ["python"]})
|
||||
],
|
||||
}
|
||||
mocker.patch("ahriman.core.status.local_client.LocalClient.package_dependencies_get",
|
||||
@ -190,7 +190,7 @@ def test_updates_dependencies_partial(update_handler: UpdateHandler, package_ahr
|
||||
"""
|
||||
mocker.patch("ahriman.core.repository.update_handler.UpdateHandler.packages", return_value=[package_ahriman])
|
||||
dependencies = [
|
||||
Dependencies(package_ahriman.base, {Path("usr"): ["filesystem", "python"]}),
|
||||
Dependencies(package_ahriman.base, {"usr": ["filesystem", "python"]}),
|
||||
]
|
||||
mocker.patch("ahriman.core.database.SQLite.dependencies_get", return_value=dependencies)
|
||||
mocker.patch("ahriman.core.alpm.pacman.Pacman.files", return_value={
|
||||
|
@ -0,0 +1,10 @@
|
||||
from ahriman.models.dependencies import Dependencies
|
||||
from ahriman.models.package import Package
|
||||
|
||||
|
||||
def test_from_json_view(package_ahriman: Package) -> None:
|
||||
"""
|
||||
must construct and serialize dependencies to json
|
||||
"""
|
||||
dependencies = Dependencies(package_ahriman.base, {"/usr/bin/python3": ["python"]})
|
||||
assert Dependencies.from_json(dependencies.view()) == dependencies
|
@ -51,6 +51,14 @@ def test_from_env() -> None:
|
||||
assert PkgbuildPatch.from_env("KEY") == PkgbuildPatch("KEY", "")
|
||||
|
||||
|
||||
def test_from_json_view() -> None:
|
||||
"""
|
||||
must correctly serialize to json
|
||||
"""
|
||||
patch = PkgbuildPatch("key", "value")
|
||||
assert PkgbuildPatch.from_json(patch.view()) == patch
|
||||
|
||||
|
||||
def test_parse() -> None:
|
||||
"""
|
||||
must parse string correctly
|
||||
@ -124,13 +132,6 @@ def test_serialize_list() -> None:
|
||||
assert PkgbuildPatch("key", ["val'ue", "val\"ue2"]).serialize() == """key=('val'"'"'ue' 'val"ue2')"""
|
||||
|
||||
|
||||
def test_view() -> None:
|
||||
"""
|
||||
must correctly serialize to json
|
||||
"""
|
||||
assert PkgbuildPatch("key", "value").view() == {"key": "key", "value": "value"}
|
||||
|
||||
|
||||
def test_write(mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must write serialized value to the file
|
||||
|
Loading…
x
Reference in New Issue
Block a user