Skip to content

Commit 04cb397

Browse files
chore: add labels with context info (#518)
so it will be easy to collect statistics about PRs with context
1 parent cdddf13 commit 04cb397

4 files changed

Lines changed: 71 additions & 18 deletions

File tree

autosynth/change_pusher.py

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
import json
1716
import os
18-
17+
import subprocess
18+
import tempfile
19+
import typing
20+
import uuid
1921
from abc import ABC, abstractmethod
22+
2023
from autosynth import git, github
2124
from autosynth.log import logger
22-
import subprocess
23-
import uuid
24-
import tempfile
25+
26+
27+
class AbstractPullRequest(ABC):
28+
"""Abstractly, manipulates an existing pull request."""
29+
30+
@abstractmethod
31+
def add_labels(self, labels: typing.Sequence[str]) -> None:
32+
"""Adds labels to an existing pull request."""
33+
pass
2534

2635

2736
class AbstractChangePusher(ABC):
@@ -30,15 +39,37 @@ class AbstractChangePusher(ABC):
3039
@abstractmethod
3140
def push_changes(
3241
self, commit_count: int, branch: str, pr_title: str, synth_log: str = ""
33-
) -> None:
34-
"""Creates a pull request from commits in current working directory."""
42+
) -> AbstractPullRequest:
43+
"""Creates a pull request from commits in current working directory.
44+
45+
Arguments:
46+
commit_count {int} -- How many commits are in this pull request?
47+
branch {str} -- The name of the local branch to push.
48+
pr_title {str} -- The title for the pull request.
49+
50+
Keyword Arguments:
51+
synth_log {str} -- The full log of the call to synth. (default: {""})
52+
53+
Returns:
54+
A pull request.
55+
"""
3556
pass
3657

3758
@abstractmethod
3859
def check_if_pr_already_exists(self, branch) -> bool:
3960
pass
4061

4162

63+
class PullRequest(AbstractPullRequest):
64+
def __init__(self, gh: github.GitHub, pr: typing.Dict[str, typing.Any]):
65+
self._gh = gh
66+
self._pr = pr
67+
68+
def add_labels(self, labels: typing.Sequence[str]) -> None:
69+
"""Adds labels to an existing pull request."""
70+
self._gh.update_pull_labels(self._pr, add=labels)
71+
72+
4273
class ChangePusher(AbstractChangePusher):
4374
"""Actually pushes changes to github."""
4475

@@ -49,7 +80,7 @@ def __init__(self, repository: str, gh: github.GitHub, synth_path: str):
4980

5081
def push_changes(
5182
self, commit_count: int, branch: str, pr_title: str, synth_log: str = ""
52-
) -> None:
83+
) -> AbstractPullRequest:
5384
git.push_changes(branch)
5485

5586
pr = self._gh.create_pull_request(
@@ -64,7 +95,8 @@ def push_changes(
6495
api_label = self._gh.get_api_label(self._repository, self._synth_path)
6596

6697
if api_label:
67-
self._gh.update_pull_labels(json.loads(pr), add=[api_label])
98+
self._gh.update_pull_labels(pr, add=[api_label])
99+
return PullRequest(self._gh, pr)
68100

69101
def check_if_pr_already_exists(self, branch) -> bool:
70102
repo = self._repository
@@ -87,13 +119,12 @@ def __init__(self, inner_change_pusher: AbstractChangePusher):
87119

88120
def push_changes(
89121
self, commit_count: int, branch: str, pr_title: str, synth_log: str = ""
90-
) -> None:
122+
) -> AbstractPullRequest:
91123
if commit_count < 2:
92124
# Only one change, no need to squash.
93-
self.inner_change_pusher.push_changes(
125+
return self.inner_change_pusher.push_changes(
94126
commit_count, branch, pr_title, synth_log
95127
)
96-
return
97128

98129
subprocess.check_call(["git", "checkout", branch]) # Probably redundant.
99130
with tempfile.NamedTemporaryFile() as message_file:
@@ -111,7 +142,7 @@ def push_changes(
111142
subprocess.check_call(["git", "checkout", "-b", branch])
112143
subprocess.check_call(["git", "merge", "--squash", temp_branch])
113144
subprocess.check_call(["git", "commit", "-F", message_file.name])
114-
self.inner_change_pusher.push_changes(1, branch, pr_title, synth_log)
145+
return self.inner_change_pusher.push_changes(1, branch, pr_title, synth_log)
115146

116147
def check_if_pr_already_exists(self, branch) -> bool:
117148
return self.inner_change_pusher.check_if_pr_already_exists(branch)

autosynth/github.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from typing import Generator, Sequence, Dict, Optional
1717

1818
import requests
19-
19+
import typing
2020

2121
_GITHUB_ROOT: str = "https://api.github.com"
2222

@@ -50,7 +50,7 @@ def list_pull_requests(self, repository: str, **kwargs) -> Sequence[Dict]:
5050

5151
def create_pull_request(
5252
self, repository: str, branch: str, title: str, body: str = None
53-
) -> str:
53+
) -> typing.Dict[str, typing.Any]:
5454
url = f"{_GITHUB_ROOT}/repos/{repository}/pulls"
5555
response = self.session.post(
5656
url,

autosynth/synth.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,15 @@ def push_changes(self, change_pusher: AbstractChangePusher) -> None:
283283
pr_title = _compose_pr_title(
284284
self.count_commits_with_context(), self._synth_path, self.source_name
285285
)
286-
change_pusher.push_changes(self.commit_count, self.branch, pr_title)
286+
pr = change_pusher.push_changes(self.commit_count, self.branch, pr_title)
287+
# Add a label to make it easy to collect statistics about commits with context.
288+
if self.count_commits_with_context() == 0:
289+
label = "context: none"
290+
elif self.count_commits_with_context() == self.commit_count:
291+
label = "context: full"
292+
else:
293+
label = "context: partial"
294+
pr.add_labels([label])
287295

288296

289297
def _compose_pr_title(

tests/test_synth.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
import autosynth.abstract_source
2828
import autosynth.synth
2929
from autosynth import git
30-
from autosynth.change_pusher import AbstractChangePusher, SquashingChangePusher
30+
from autosynth.change_pusher import (
31+
AbstractChangePusher,
32+
SquashingChangePusher,
33+
AbstractPullRequest,
34+
)
3135
from autosynth.synthesizer import AbstractSynthesizer
3236
from integration_tests import util
3337
import json
@@ -163,11 +167,16 @@ def test_synthesize_loop_with_empty_change_history():
163167
assert 0 == commit_count
164168

165169

170+
class MockPullRequest(AbstractPullRequest):
171+
def add_labels(self, labels: typing.Sequence[str]) -> None:
172+
pass
173+
174+
166175
class MockChangePusher(AbstractChangePusher):
167176
def push_changes(
168177
self, commit_count: int, branch: str, pr_title: str = "", synth_log: str = ""
169178
) -> None:
170-
pass
179+
return MockPullRequest()
171180

172181
def check_if_pr_already_exists(self, branch) -> bool:
173182
return False
@@ -235,12 +244,14 @@ def test_synthesize_loop_with_realistic_change_history_multiple_prs(
235244
"test-source1",
236245
"[CHANGE ME] Re-generated to pick up changes from source1.",
237246
),
247+
call.push_changes().add_labels(["context: partial"]),
238248
call.check_if_pr_already_exists("test-source2"),
239249
call.push_changes(
240250
3,
241251
"test-source2",
242252
"[CHANGE ME] Re-generated to pick up changes from source2.",
243253
),
254+
call.push_changes().add_labels(["context: partial"]),
244255
]
245256
assert golden_calls == calls
246257

@@ -262,13 +273,15 @@ def test_synthesize_loop_with_realistic_change_history_squash_prs(
262273
"[CHANGE ME] Re-generated to pick up changes from source1.",
263274
"",
264275
),
276+
call.push_changes().add_labels(["context: partial"]),
265277
call.check_if_pr_already_exists("test-source2"),
266278
call.push_changes(
267279
1,
268280
"test-source2",
269281
"[CHANGE ME] Re-generated to pick up changes from source2.",
270282
"",
271283
),
284+
call.push_changes().add_labels(["context: partial"]),
272285
]
273286
assert golden_calls == calls
274287

@@ -426,6 +439,7 @@ def test_synthesize_loop_uses_single_commit_title_for_pr_title(
426439
call.check_if_pr_already_exists("test-source1"),
427440
call.check_if_pr_already_exists("test-source2"),
428441
call.push_changes(1, "test-source2", "Wrote a to a.txt."),
442+
call.push_changes().add_labels(["context: full"]),
429443
]
430444
assert golden_calls == calls
431445

0 commit comments

Comments
 (0)