Skip to content

Commit

Permalink
[feat] Add --allow-missing option to skip missing issues, fix #4
Browse files Browse the repository at this point in the history
  • Loading branch information
slarse committed Oct 6, 2019
1 parent 7d5c1af commit a2a4efd
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
34 changes: 27 additions & 7 deletions repobee_feedback/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,18 @@


def callback(args: argparse.Namespace, api: plug.API) -> None:
repo_names = plug.generate_repo_names(args.students, args.master_repo_names)
repo_names = plug.generate_repo_names(
args.students, args.master_repo_names
)
if "multi_issues_file" in args and args.multi_issues_file is not None:
issues_file = pathlib.Path(args.multi_issues_file).resolve()
all_issues = _parse_multi_issues_file(issues_file)
else:
issues_dir = pathlib.Path(args.issues_dir).resolve()
all_issues = _collect_issues(repo_names, issues_dir)
issues = _extract_expected_issues(all_issues, repo_names)
issues = _extract_expected_issues(
all_issues, repo_names, args.allow_missing
)
for repo_name, issue in issues:
open_issue = args.batch_mode or _ask_for_open(
issue, repo_name, args.truncation_length
Expand Down Expand Up @@ -92,6 +96,12 @@ def create_extension_command(self):
"be an #ISSUE# line."
),
)
parser.add_argument(
"--allow-missing",
help="Emit a warning (instead of crashing) on missing issues.",
action="store_true",
default=False,
)
return plug.ExtensionCommand(
parser=parser,
name="issue-feedback",
Expand Down Expand Up @@ -121,13 +131,15 @@ def _ask_for_open(issue: plug.Issue, repo_name: str, trunc_len: int) -> bool:
)
)
return (
input('Open issue "{}" in repo {}? (y/n) '.format(issue.title, repo_name))
input(
'Open issue "{}" in repo {}? (y/n) '.format(issue.title, repo_name)
)
== "y"
)


def _extract_expected_issues(
repos_and_issues, repo_names
repos_and_issues, repo_names, allow_missing
) -> List[Tuple[str, plug.Issue]]:
expected_repo_names = set(repo_names)
expected_repos_and_issues = [
Expand All @@ -139,7 +151,11 @@ def _extract_expected_issues(
(repo_name for repo_name, _ in expected_repos_and_issues)
)
if missing_repos:
raise plug.PlugError("Missing issues for: " + ", ".join(missing_repos))
msg = "Missing issues for: " + ", ".join(missing_repos)
if allow_missing:
LOGGER.warning(msg)
else:
raise plug.PlugError(msg)

return expected_repos_and_issues

Expand All @@ -164,11 +180,15 @@ def _read_issue(issue_path: pathlib.Path) -> plug.Issue:
def _parse_multi_issues_file(
issues_file: pathlib.Path
) -> Iterable[Tuple[str, plug.Issue]]:
with open(str(issues_file), mode="r", encoding=sys.getdefaultencoding()) as file:
with open(
str(issues_file), mode="r", encoding=sys.getdefaultencoding()
) as file:
lines = list(file.readlines())

if not lines or not re.match(BEGIN_ISSUE_PATTERN, lines[0], re.IGNORECASE):
raise plug.PlugError("first line of multi issues file not #ISSUE# line")
raise plug.PlugError(
"first line of multi issues file not #ISSUE# line"
)

issue_blocks = _extract_issue_blocks(lines)
return list(_extract_issues(issue_blocks, lines))
Expand Down
23 changes: 23 additions & 0 deletions tests/test_feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def parsed_args_issues_dir(tmp_path):
issues_dir=str(tmp_path),
multi_issues_file=None,
truncation_length=50,
allow_missing=False,
)


Expand All @@ -74,6 +75,7 @@ def parsed_args_multi_issues_file(with_multi_issues_file):
issues_dir=None,
multi_issues_file=str(issues_file),
truncation_length=50,
allow_missing=False,
)


Expand Down Expand Up @@ -165,6 +167,27 @@ def test_aborts_if_issue_is_missing(
assert repo_without_issue in str(exc_info.value)
assert not api_mock.open_issue.called

def test_ignores_missing_issue_if_allow_missing(
self, with_issues, parsed_args_issues_dir, api_mock, tmp_path
):
"""Test that missing issues are ignored if --allow-mising is set."""
repo_without_issue = plug.generate_repo_name(
STUDENT_TEAM_NAMES[-1], MASTER_REPO_NAMES[0]
)
(tmp_path / "{}.md".format(repo_without_issue)).unlink()
expected_calls = [
mock.call(issue.title, issue.body, [repo_name])
for repo_name, issue in with_issues
if repo_name != repo_without_issue
]
args_dict = vars(parsed_args_issues_dir)
args_dict["allow_missing"] = True
args = argparse.Namespace(**args_dict)

feedback.callback(args=args, api=api_mock)

api_mock.open_issue.assert_has_calls(expected_calls, any_order=True)

def test_opens_nothing_if_open_prompt_returns_false(
self, with_issues, parsed_args_issues_dir, api_mock
):
Expand Down

0 comments on commit a2a4efd

Please sign in to comment.