Skip to content

Commit 0a86ac7

Browse files
committed
[fix] Fix crash on finding unexpected repo names in multi issues file, fix #5
1 parent 563257b commit 0a86ac7

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

repobee_feedback/feedback.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@
2424

2525

2626
def callback(args: argparse.Namespace, api: plug.API) -> None:
27-
repo_names = plug.generate_repo_names(args.students, args.master_repo_names)
27+
repo_names = plug.generate_repo_names(
28+
args.students, args.master_repo_names
29+
)
2830
if "multi_issues_file" in args and args.multi_issues_file is not None:
2931
issues_file = pathlib.Path(args.multi_issues_file).resolve()
30-
issues = _parse_multi_issues_file(issues_file)
32+
all_issues = _parse_multi_issues_file(issues_file)
3133
else:
3234
issues_dir = pathlib.Path(args.issues_dir).resolve()
33-
issues = _collect_issues(repo_names, issues_dir)
34-
_raise_on_missing_issue_file(issues, repo_names)
35+
all_issues = _collect_issues(repo_names, issues_dir)
36+
issues = _extract_expected_issues(all_issues, repo_names)
3537
for repo_name, issue in issues:
3638
open_issue = args.batch_mode or _ask_for_open(
3739
issue, repo_name, args.truncation_length
@@ -121,17 +123,31 @@ def _ask_for_open(issue: plug.Issue, repo_name: str, trunc_len: int) -> bool:
121123
)
122124
)
123125
return (
124-
input('Open issue "{}" in repo {}? (y/n) '.format(issue.title, repo_name))
126+
input(
127+
'Open issue "{}" in repo {}? (y/n) '.format(issue.title, repo_name)
128+
)
125129
== "y"
126130
)
127131

128132

129-
def _raise_on_missing_issue_file(repos_and_issues, repo_names):
130-
expected = set(repo_names)
131-
for repo_name, _ in repos_and_issues:
132-
expected.remove(repo_name)
133-
if expected:
134-
raise plug.PlugError("Missing issues for: " + ", ".join(expected))
133+
def _extract_expected_issues(
134+
repos_and_issues, repo_names
135+
) -> List[Tuple[str, plug.Issue]]:
136+
expected_repo_names = set(repo_names)
137+
expected_repos_and_issues = [
138+
(repo_name, issue)
139+
for repo_name, issue in repos_and_issues
140+
if repo_name in expected_repo_names
141+
]
142+
missing_repos = expected_repo_names - set(
143+
(repo_name for repo_name, _ in expected_repos_and_issues)
144+
)
145+
if missing_repos:
146+
raise plug.PlugError(
147+
"Missing issues for: " + ", ".join(expected_repo_names)
148+
)
149+
150+
return expected_repos_and_issues
135151

136152

137153
def _collect_issues(
@@ -154,11 +170,15 @@ def _read_issue(issue_path: pathlib.Path) -> plug.Issue:
154170
def _parse_multi_issues_file(
155171
issues_file: pathlib.Path
156172
) -> Iterable[Tuple[str, plug.Issue]]:
157-
with open(str(issues_file), mode="r", encoding=sys.getdefaultencoding()) as file:
173+
with open(
174+
str(issues_file), mode="r", encoding=sys.getdefaultencoding()
175+
) as file:
158176
lines = list(file.readlines())
159177

160178
if not lines or not re.match(BEGIN_ISSUE_PATTERN, lines[0], re.IGNORECASE):
161-
raise plug.PlugError("first line of multi issues file not #ISSUE# line")
179+
raise plug.PlugError(
180+
"first line of multi issues file not #ISSUE# line"
181+
)
162182

163183
issue_blocks = _extract_issue_blocks(lines)
164184
return list(_extract_issues(issue_blocks, lines))

tests/test_feedback.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,28 @@ def test_opens_issues_from_multi_issues_file(
195195
feedback.callback(args=parsed_args_multi_issues_file, api=api_mock)
196196

197197
api_mock.open_issue.assert_has_calls(expected_calls)
198+
199+
def test_skips_unexpected_issues_in_multi_issues_file(
200+
self, with_multi_issues_file, parsed_args_multi_issues_file, api_mock
201+
):
202+
"""Test that an exception is raised if one or more issues are found
203+
relating to student repos that ar not in prod(master_repo_names, students).
204+
"""
205+
student_teams = parsed_args_multi_issues_file.students
206+
args_dict = vars(parsed_args_multi_issues_file)
207+
args_dict["students"] = student_teams[:-1]
208+
args = argparse.Namespace(**args_dict)
209+
unexpected_repos = plug.generate_repo_names(
210+
student_teams[-1:], MASTER_REPO_NAMES
211+
)
212+
213+
_, repos_and_issues = with_multi_issues_file
214+
expected_calls = [
215+
mock.call(issue.title, issue.body, [repo_name])
216+
for repo_name, issue in repos_and_issues
217+
if repo_name not in unexpected_repos
218+
]
219+
220+
feedback.callback(args=args, api=api_mock)
221+
222+
assert sorted(expected_calls) == sorted(api_mock.open_issue.mock_calls)

0 commit comments

Comments
 (0)