Skip to content

Commit 19226c2

Browse files
feat: update maintainers from ignored packages in the view
1 parent 3223d22 commit 19226c2

File tree

6 files changed

+30
-38
lines changed

6 files changed

+30
-38
lines changed

src/shared/github.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,32 +68,14 @@ def cvss_details() -> str:
6868
return ""
6969

7070
def maintainers() -> str:
71-
# Get all maintainer github_ids from currently active packages
72-
active_package_maintainer_ids = {
73-
maintainer["github_id"]
74-
for package in cached_suggestion.payload["packages"].values()
75-
for maintainer in package["maintainers"]
76-
if "github_id" in maintainer
77-
}
78-
79-
# Filter active maintainers to only those still in active packages
80-
filtered_active_maintainers = [
81-
maintainer
82-
for maintainer in cached_suggestion.payload["categorized_maintainers"][
83-
"active"
84-
]
85-
if maintainer["github_id"] in active_package_maintainer_ids
86-
]
71+
maintainers = cached_suggestion.payload["categorized_maintainers"]
8772

8873
# We need to query for the latest username of each maintainer, because
8974
# those might have changed since they were written out in Nixpkgs; since
9075
# we have the user id (which is stable), we can ask the GitHub API
9176
maintainers_list = [
9277
get_maintainer_username(maintainer, github)
93-
for maintainer in (
94-
filtered_active_maintainers
95-
+ cached_suggestion.payload["categorized_maintainers"]["added"]
96-
)
78+
for maintainer in (maintainers["active"] + maintainers["added"])
9779
if "github_id" in maintainer and "github" in maintainer
9880
]
9981

src/shared/listeners/cache_suggestions.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,6 @@ def cache_new_suggestions(suggestion: CVEDerivationClusterProposal) -> None:
195195
)
196196
package_edits = list(suggestion.package_edits.all())
197197
packages = apply_package_edits(original_packages, package_edits)
198-
# FIXME(@fricklerhandwerk): We should just pass `packages`, but a tangled legacy view is still using this seemingly internal function and wants to pass a dict.
199-
categorized_maintainers = categorize_maintainers(
200-
original_packages, maintainers_edits
201-
)
202198

203199
only_relevant_data = CachedSuggestion(
204200
pk=suggestion.pk,
@@ -211,7 +207,7 @@ def cache_new_suggestions(suggestion: CVEDerivationClusterProposal) -> None:
211207
original_packages=packages,
212208
packages=packages,
213209
metrics=[to_dict(m) for m in prefetched_metrics],
214-
categorized_maintainers=categorized_maintainers,
210+
categorized_maintainers=categorize_maintainers(packages, maintainers_edits),
215211
)
216212

217213
_, created = CachedSuggestions.objects.update_or_create(
@@ -425,19 +421,17 @@ def maintainers_list(packages: dict, edits: list[MaintainersEdit]) -> list[dict]
425421

426422

427423
def categorize_maintainers(
428-
original_packages: dict[str, CachedSuggestion.Package],
424+
packages: dict[str, CachedSuggestion.Package],
429425
maintainers_edits: list[MaintainersEdit],
430426
) -> CachedSuggestion.CategorizedMaintainers:
431427
"""
432-
Categorize maintainers associated the packages of a suggestion.
428+
Categorize maintainers associated to the packages of a suggestion.
433429
"""
434430
# Collect all original maintainers from packages (deduplicated by github_id)
435431
original_maintainers_dict: dict[int, dict] = {}
436-
for package in original_packages.values():
437-
for maintainer_dict in package.maintainers:
438-
github_id = maintainer_dict["github_id"]
439-
if github_id not in original_maintainers_dict:
440-
original_maintainers_dict[github_id] = maintainer_dict
432+
for package in packages.values():
433+
for maintainer in package.maintainers:
434+
original_maintainers_dict[maintainer["github_id"]] = maintainer
441435

442436
original_maintainers = list(original_maintainers_dict.values())
443437

src/webview/suggestions/views/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ class ForbiddenOperationError(Exception):
113113
def __init__(self, response: HttpResponse) -> None:
114114
self.error = response
115115

116+
# FIXME(@fricklerhandwerk): This conflates access control with database queries and bypasses the standard Django mechanism of overriding the respective view methods.
117+
# The main problem here is that it results in very inefficient queries, as we can't express fetching related data in one go.
118+
# A minor problem for now is obscured and coarse-grained access control, but there's no user story at the moment for which it's in the way.
116119
def _check_access_rights_and_get_suggestion(
117120
self, request: HttpRequest, suggestion_id: int
118121
) -> tuple[CVEDerivationClusterProposal, SuggestionContext]:

src/webview/suggestions/views/packages.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
from django.db import transaction
44
from django.http import HttpRequest, HttpResponse
55

6-
from shared.listeners.cache_suggestions import apply_package_edits
6+
from shared.listeners.cache_suggestions import (
7+
CachedSuggestion,
8+
apply_package_edits,
9+
categorize_maintainers,
10+
)
711
from shared.models.linkage import (
812
CVEDerivationClusterProposal,
9-
PackageEdit,
1013
)
1114
from webview.suggestions.context.builders import (
15+
get_maintainer_list_context,
1216
get_package_list_context,
1317
)
1418

@@ -40,11 +44,19 @@ def post(
4044
try:
4145
with transaction.atomic():
4246
self._perform_operation(suggestion, package_attr)
43-
new_active_packages = apply_package_edits(
47+
suggestion.cached.payload["packages"] = apply_package_edits(
4448
suggestion.cached.payload["original_packages"],
4549
suggestion.package_edits.all(),
4650
)
47-
suggestion.cached.payload["packages"] = new_active_packages
51+
suggestion.cached.payload["categorized_maintainers"] = (
52+
categorize_maintainers(
53+
{
54+
k: CachedSuggestion.Package.model_validate(v)
55+
for k, v in suggestion.cached.payload["packages"].items()
56+
},
57+
suggestion.maintainers_edits.all(),
58+
).model_dump()
59+
)
4860
suggestion.cached.save()
4961
except Exception:
5062
return self._handle_error(
@@ -55,6 +67,9 @@ def post(
5567

5668
# Refresh the package list context and activity log
5769
suggestion_context.package_list_context = get_package_list_context(suggestion)
70+
suggestion_context.maintainer_list_context = get_maintainer_list_context(
71+
suggestion
72+
)
5873
suggestion_context.activity_log = fetch_activity_log(suggestion.pk)
5974

6075
# Handle response based on request type

src/webview/templates/suggestions/components/maintainers_list.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
<!-- Active maintainers -->
1212
<div class="row gap spread wrap baseline">
1313
<h2 class="heading dimmed">Package maintainers</h2>
14-
{% if data.editable and user|is_maintainer_or_admin %}<p class="dimmed">Maintainers of ignored packages won't be notified.</p>{% endif %}
1514
</div>
1615
{% if data.active %}
1716
<ul id="maintainers-list-{{ data.suggestion_id }}-active" class="column gap-small">

src/webview/tests/test_maintainers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ def test_add_maintainer_from_invalid_github_handle_returns_error(
135135
expect(error).to_be_visible()
136136

137137

138-
@pytest.mark.xfail(reason="Not implemented")
139138
@pytest.mark.parametrize(
140139
"ignore_maintainer",
141140
[True, False],

0 commit comments

Comments
 (0)