Skip to content

Commit 6a26402

Browse files
committed
api.views: create base pull request view (bug 2002628)
1 parent ac53729 commit 6a26402

2 files changed

Lines changed: 46 additions & 36 deletions

File tree

src/lando/api/views.py

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -203,16 +203,31 @@ class hg2gitCommitMapView(CommitMapBaseView):
203203
scm = SCMType.HG
204204

205205

206-
class LandingJobPullRequestAPIView(View):
206+
class PullRequestAPIView(View):
207+
"""Set various common attributes for views that extend this one."""
208+
209+
target_repo: Repo
210+
client: GitHubAPIClient
211+
pull_request: PullRequest
212+
213+
def dispatch(
214+
self, request: WSGIRequest, repo_name: str, pull_number: int, *args, **kwargs
215+
) -> JsonResponse:
216+
self.target_repo = Repo.objects.get(name=repo_name)
217+
self.client = GitHubAPIClient(self.target_repo.url)
218+
self.pull_request = self.client.build_pull_request(pull_number)
219+
return super().dispatch(request, repo_name, pull_number, *args, **kwargs)
220+
221+
222+
class LandingJobPullRequestAPIView(PullRequestAPIView):
207223
"""Handle pull request landing jobs in the API."""
208224

209225
def get(
210226
self, request: WSGIRequest, repo_name: int, pull_number: int
211227
) -> JsonResponse:
212228
"""Return the status of a pull request based on landing job counts."""
213229

214-
target_repo = Repo.objects.get(name=repo_name)
215-
landing_jobs = get_jobs_for_pull(target_repo, pull_number)
230+
landing_jobs = get_jobs_for_pull(self.target_repo, pull_number)
216231
landing_jobs_by_status = defaultdict(list)
217232
for landing_job in landing_jobs:
218233
landing_jobs_by_status[landing_job.status].append(landing_job.id)
@@ -245,14 +260,11 @@ class Form(forms.Form):
245260
# TODO: use this for verification later, see bug 1996571.
246261
# base_ref = forms.CharField()
247262

248-
target_repo = Repo.objects.get(name=repo_name)
249-
client = GitHubAPIClient(target_repo.url)
250263
ldap_username = request.user.email
251-
pull_request = client.build_pull_request(pull_number)
252264

253-
blockers = generate_warnings_and_blockers(target_repo, pull_request, request)[
254-
"blockers"
255-
]
265+
blockers = generate_warnings_and_blockers(
266+
self.target_repo, self.pull_request, request
267+
)["blockers"]
256268

257269
if blockers:
258270
# Pull request has blockers that prevent it from landing.
@@ -264,22 +276,22 @@ class Form(forms.Form):
264276
return JsonResponse(form.errors, 400)
265277

266278
job = LandingJob.objects.create(
267-
target_repo=target_repo,
279+
target_repo=self.target_repo,
268280
requester_email=ldap_username,
269281
is_pull_request_job=True,
270282
)
271-
author_name, author_email = pull_request.author
283+
author_name, author_email = self.pull_request.author
272284

273-
reviews_summary = pull_request.reviews_summary
285+
reviews_summary = self.pull_request.reviews_summary
274286
reviewers = [
275287
u
276288
for u in reviews_summary
277-
if reviews_summary.get(u) == pull_request.Review.APPROVED
289+
if reviews_summary.get(u) == self.pull_request.Review.APPROVED
278290
]
279291
approvals = []
280292

281293
commit_message = replace_reviewers(
282-
pull_request.commit_message, reviewers, approvals
294+
self.pull_request.commit_message, reviewers, approvals
283295
)
284296

285297
patch_data = {
@@ -289,10 +301,10 @@ class Form(forms.Form):
289301
"timestamp": int(datetime.now().timestamp()),
290302
}
291303
revision = Revision.objects.create(
292-
pull_number=pull_request.number,
293-
pull_head_sha=pull_request.head_sha,
294-
pull_base_sha=pull_request.base_sha,
295-
patches=pull_request.patch,
304+
pull_number=self.pull_request.number,
305+
pull_head_sha=self.pull_request.head_sha,
306+
pull_base_sha=self.pull_request.base_sha,
307+
patches=self.pull_request.patch,
296308
patch_data=patch_data,
297309
)
298310
add_revisions_to_job([revision], job)
@@ -302,14 +314,13 @@ class Form(forms.Form):
302314
return JsonResponse({"id": job.id}, status=201)
303315

304316

305-
class PullRequestChecksAPIView(APIView):
306-
def get(self, request: WSGIRequest, repo_name: str, number: int) -> JsonResponse:
307-
target_repo = Repo.objects.get(name=repo_name)
308-
client = GitHubAPIClient(target_repo.url)
309-
pull_request = client.build_pull_request(number)
317+
class PullRequestChecksAPIView(PullRequestAPIView):
318+
def get(
319+
self, request: WSGIRequest, repo_name: str, pull_number: int
320+
) -> JsonResponse:
310321
try:
311322
warnings_and_blockers = generate_warnings_and_blockers(
312-
target_repo, pull_request, request
323+
self.target_repo, self.pull_request, request
313324
)
314325
except PullRequest.StaleMetadataException as exc:
315326
# The StaleMetadataException error message is safe for user consumption.
@@ -318,7 +329,7 @@ def get(self, request: WSGIRequest, repo_name: str, number: int) -> JsonResponse
318329

319330

320331
@method_decorator(csrf_exempt, name="dispatch")
321-
class PullRequestTryPushAPIView(APIView):
332+
class PullRequestTryPushAPIView(PullRequestAPIView):
322333
@method_decorator(require_authenticated_user)
323334
def post(
324335
self, request: WSGIRequest, repo_name: str, pull_number: int
@@ -328,33 +339,32 @@ def post(
328339
except Repo.DoesNotExist:
329340
return JsonResponse({"errors": ["Try repo does not exist"]}, status=500)
330341

331-
target_repo = Repo.objects.get(name=repo_name)
332-
client = GitHubAPIClient(target_repo.url)
333342
ldap_username = request.user.email
334-
pull_request = client.build_pull_request(pull_number)
335343

336344
job = LandingJob.objects.create(
337-
target_repo=target_repo,
345+
target_repo=self.target_repo,
338346
is_handed_over=False,
339347
is_pull_request_job=True,
340348
handover_repo=try_repo,
341349
requester_email=ldap_username,
342350
)
343-
author_name, author_email = pull_request.author
351+
author_name, author_email = self.pull_request.author
344352
try:
345-
timestamp = int(datetime.fromisoformat(pull_request.updated_at).timestamp())
353+
timestamp = int(
354+
datetime.fromisoformat(self.pull_request.updated_at).timestamp()
355+
)
346356
except ValueError:
347357
timestamp = int(datetime.now().timestamp())
348358
patch_data = {
349359
"author_name": author_name,
350360
"author_email": author_email,
351-
"commit_message": pull_request.commit_message,
361+
"commit_message": self.pull_request.commit_message,
352362
"timestamp": timestamp,
353363
}
354364
revision = Revision.objects.create(
355-
pull_number=pull_request.number,
356-
pull_head_sha=pull_request.head_sha,
357-
patches=pull_request.patch,
365+
pull_number=self.pull_request.number,
366+
pull_head_sha=self.pull_request.head_sha,
367+
patches=self.pull_request.patch,
358368
patch_data=patch_data,
359369
)
360370
add_revisions_to_job([revision], job)

src/lando/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
name="api-try-job-pull-request",
128128
),
129129
path(
130-
"api/pulls/<str:repo_name>/<int:number>/checks",
130+
"api/pulls/<str:repo_name>/<int:pull_number>/checks",
131131
PullRequestChecksAPIView.as_view(),
132132
name="api-pull-request-checks",
133133
),

0 commit comments

Comments
 (0)