Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ probably want the following:
uv run ./manage.py loaddata devel/fixtures/*.json
uv run ./manage.py loaddata mirrors/fixtures/*.json
uv run ./manage.py loaddata releng/fixtures/*.json
uv run ./manage.py loaddata todolists/fixtures/*.json
7. Use the following commands to start a service instance

uv run ./manage.py runserver
Expand Down
4 changes: 4 additions & 0 deletions templates/todolists/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ <h3>Filter Todo List Packages</h3>
<th>Name</th>
<th>Current Version</th>
<th>Staging Version</th>
<th>Testing Version</th>
<th>Maintainers</th>
<th>Status</th>
<th>Last Touched By</th>
Expand All @@ -96,6 +97,9 @@ <h3>Filter Todo List Packages</h3>
{% with staging=pkg.staging %}
<td>{% if staging %}{% pkg_details_link staging staging.full_version %}{% endif %}</td>
{% endwith %}
{% with testing=pkg.testing %}
<td>{% if testing %}{% pkg_details_link testing testing.full_version %}{% endif %}</td>
{% endwith %}
<td>{{ pkg.maintainers|join:', ' }}</td>
<td>
{% if perms.todolists.change_todolistpackage %}
Expand Down
158 changes: 158 additions & 0 deletions todolists/fixtures/todolist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
[
{
"model": "auth.user",
"pk": 1,
"fields": {
"username": "developer",
"first_name": "Test",
"last_name": "Developer",
"email": "developer@archlinux.org",
"password": "pbkdf2_sha256$1000000$5mOVHaWggfkqKGsKsVpWH8$kS2tNunBSv+rrDohZXeuP9L/kX8oDe09vzab+m3WQXo=",
"is_staff": true,
"is_active": true,
"is_superuser": true,
"date_joined": "2024-01-01T00:00:00Z",
"last_login": null,
"groups": [],
"user_permissions": []
}
},
{
"model": "main.package",
"pk": 6,
"fields": {
"repo": 3,
"arch": 3,
"pkgname": "linux",
"pkgbase": "linux",
"pkgver": "6.9.1",
"pkgrel": "2",
"epoch": 0,
"pkgdesc": "The Linux kernel and modules",
"url": "https://www.kernel.org/",
"filename": "linux-6.9.1-2-x86_64.pkg.tar.zst",
"compressed_size": 72000000,
"installed_size": 91000000,
"build_date": "2024-05-20T10:00:00Z",
"last_update": "2024-05-20T10:00:00Z",
"files_last_update": null,
"created": "2024-05-20T10:00:00Z",
"packager_str": "Test Developer <developer@archlinux.org>",
"packager": null,
"signature_bytes": null,
"flag_date": null
}
},
{
"model": "main.package",
"pk": 7,
"fields": {
"repo": 16,
"arch": 3,
"pkgname": "systemd",
"pkgbase": "systemd",
"pkgver": "256.1",
"pkgrel": "1",
"epoch": 0,
"pkgdesc": "system and service manager",
"url": "https://www.github.com/systemd/systemd",
"filename": "systemd-256.1-1-x86_64.pkg.tar.zst",
"compressed_size": 4100000,
"installed_size": 19000000,
"build_date": "2024-05-22T08:00:00Z",
"last_update": "2024-05-22T08:00:00Z",
"files_last_update": null,
"created": "2024-05-22T08:00:00Z",
"packager_str": "Test Developer <developer@archlinux.org>",
"packager": null,
"signature_bytes": null,
"flag_date": null
}
},
{
"model": "todolists.todolist",
"pk": 1,
"fields": {
"slug": "glibc-2-40-rebuild",
"name": "glibc 2.40 rebuild",
"description": "Rebuild of packages affected by the glibc 2.40 soname bump.",
"creator": 1,
"created": "2024-05-20T09:00:00Z",
"kind": 0,
"last_modified": "2024-05-22T08:00:00Z",
"raw": "linux\ncoreutils\npacman\nsystemd"
}
},
{
"model": "todolists.todolistpackage",
"pk": 1,
"fields": {
"todolist": 1,
"pkg": 1,
"pkgname": "linux",
"pkgbase": "linux",
"arch": 3,
"repo": 1,
"created": "2024-05-20T09:00:00Z",
"last_modified": "2024-05-20T09:00:00Z",
"removed": null,
"status": 0,
"user": null,
"comments": null
}
},
{
"model": "todolists.todolistpackage",
"pk": 2,
"fields": {
"todolist": 1,
"pkg": 2,
"pkgname": "coreutils",
"pkgbase": "coreutils",
"arch": 3,
"repo": 1,
"created": "2024-05-20T09:00:00Z",
"last_modified": "2024-05-21T14:30:00Z",
"removed": null,
"status": 1,
"user": 1,
"comments": null
}
},
{
"model": "todolists.todolistpackage",
"pk": 3,
"fields": {
"todolist": 1,
"pkg": 4,
"pkgname": "pacman",
"pkgbase": "pacman",
"arch": 3,
"repo": 1,
"created": "2024-05-20T09:00:00Z",
"last_modified": "2024-05-22T10:00:00Z",
"removed": null,
"status": 2,
"user": 1,
"comments": null
}
},
{
"model": "todolists.todolistpackage",
"pk": 4,
"fields": {
"todolist": 1,
"pkg": 5,
"pkgname": "systemd",
"pkgbase": "systemd",
"arch": 3,
"repo": 1,
"created": "2024-05-20T09:00:00Z",
"last_modified": "2024-05-20T09:00:00Z",
"removed": null,
"status": 0,
"user": null,
"comments": null
}
}
]
103 changes: 103 additions & 0 deletions todolists/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import pytest
from django.utils.timezone import now

from main.models import Package, Repo
from todolists.models import TodolistPackage
from todolists.utils import attach_staging, attach_testing


def make_package(pkgname, repo, arch):
return Package.objects.create(
pkgname=pkgname,
pkgbase=pkgname,
pkgver='1.0',
pkgrel='1',
epoch=0,
pkgdesc='Test package',
url='https://example.com',
filename=f'{pkgname}-1.0-1-x86_64.pkg.tar.zst',
compressed_size=1000,
installed_size=2000,
build_date=now(),
last_update=now(),
created=now(),
packager_str='Test Packager',
repo=repo,
arch=arch,
)


@pytest.fixture
def stable_pkg(repos, package):
return Package.objects.get(pkgname='linux')


@pytest.fixture
def todolist_with_linux(todolist, stable_pkg, user):
arch = stable_pkg.arch
repo = stable_pkg.repo
tlpkg = TodolistPackage.objects.create(
todolist=todolist,
pkg=stable_pkg,
pkgname=stable_pkg.pkgname,
pkgbase=stable_pkg.pkgbase,
arch=arch,
repo=repo,
user=user,
)
yield todolist
tlpkg.delete()


def test_attach_testing_no_testing_pkg(todolist_with_linux):
todolist = todolist_with_linux
attach_testing(todolist.packages(), todolist.pk)
for pkg in todolist.packages():
assert pkg.testing is None


def test_attach_testing_finds_testing_pkg(todolist_with_linux):
todolist = todolist_with_linux
stable_pkg = Package.objects.get(pkgname='linux', repo__testing=False, repo__staging=False)
testing_repo = Repo.objects.get(name='Core-Testing')

testing_pkg = make_package('linux', testing_repo, stable_pkg.arch)
try:
attach_testing(todolist.packages(), todolist.pk)
for pkg in todolist.packages():
if pkg.pkgname == 'linux':
assert pkg.testing is not None
assert pkg.testing.repo.testing is True
finally:
testing_pkg.delete()


def test_attach_testing_ignores_staging_repos(todolist_with_linux):
todolist = todolist_with_linux
stable_pkg = Package.objects.get(pkgname='linux', repo__testing=False, repo__staging=False)
staging_repo = Repo.objects.get(name='Core-Staging')

staging_pkg = make_package('linux', staging_repo, stable_pkg.arch)
try:
attach_testing(todolist.packages(), todolist.pk)
for pkg in todolist.packages():
if pkg.pkgname == 'linux':
assert pkg.testing is None
finally:
staging_pkg.delete()


def test_attach_staging_still_works(todolist_with_linux):
todolist = todolist_with_linux
stable_pkg = Package.objects.get(pkgname='linux', repo__testing=False, repo__staging=False)
staging_repo = Repo.objects.get(name='Core-Staging')

staging_pkg = make_package('linux', staging_repo, stable_pkg.arch)
try:
attach_staging(todolist.packages(), todolist.pk)
for pkg in todolist.packages():
if pkg.pkgname == 'linux':
assert pkg.staging is not None
assert pkg.staging.repo.staging is True
finally:
staging_pkg.delete()
35 changes: 24 additions & 11 deletions todolists/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,34 @@ def get_annotated_todolists(incomplete_only=False):
return lists


def attach_staging(packages, list_id):
'''Look for any staging version of the packages provided and attach them
to the 'staging' attribute on each package if found.'''
def _attach_repo_version(packages, list_id, kind):
'''Look for related packages in repos flagged by kind and attach them.

kind is a Repo boolean field name used as repo__{kind}=True. Only
'staging' and 'testing' are used; they set package.staging or
package.testing for the todolist templates.
'''
pkgnames = TodolistPackage.objects.filter(
todolist_id=list_id).values('pkgname')
staging_pkgs = Package.objects.normal().filter(repo__staging=True,
pkgname__in=pkgnames)
# now build a lookup dict to attach to the correct package
lookup = {(p.pkgname, p.arch): p for p in staging_pkgs}
related_pkgs = Package.objects.normal().filter(
**{f'repo__{kind}': True},
pkgname__in=pkgnames,
)
lookup = {(p.pkgname, p.arch): p for p in related_pkgs}

annotated = []
for package in packages:
in_staging = lookup.get((package.pkgname, package.arch), None)
package.staging = in_staging
setattr(package, kind, lookup.get((package.pkgname, package.arch)))


def attach_staging(packages, list_id):
'''Look for any staging version of the packages provided and attach them
to the 'staging' attribute on each package if found.'''
_attach_repo_version(packages, list_id, 'staging')


return annotated
def attach_testing(packages, list_id):
'''Look for any testing version of the packages provided and attach them
to the 'testing' attribute on each package if found.'''
_attach_repo_version(packages, list_id, 'testing')

# vim: set ts=4 sw=4 et:
3 changes: 2 additions & 1 deletion todolists/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from packages.utils import PackageJSONEncoder, attach_maintainers

from .models import Todolist, TodolistPackage
from .utils import attach_staging, get_annotated_todolists
from .utils import attach_staging, attach_testing, get_annotated_todolists


class TodoListForm(forms.ModelForm):
Expand Down Expand Up @@ -65,6 +65,7 @@ def view(request, slug):
# so accessing maintainers in the template is now cheap
attach_maintainers(todolist.packages())
attach_staging(todolist.packages(), todolist.pk)
attach_testing(todolist.packages(), todolist.pk)
arches = {tp.arch for tp in todolist.packages()}
repos = {tp.repo for tp in todolist.packages()}
context = {
Expand Down
Loading