Repository: repobee/repobee-feedback

Issue:
Auto generate multi-issue file
I'm getting real tired of adding 

#ISSUE#name-task-X#Pass/fail

to a file 15 times so I considered writing a plugin to do that for me but realized I can just add it to the feedback plugin if that's okay with you @slarse 

I'm thinking something like:

`repobee issues feedback create-mi-file`

Comments:

Patch:
diff --git a/repobee_feedback/_generate_multi_issues_file.py b/repobee_feedback/_generate_multi_issues_file.py
new file mode 100644
index 0000000..4f007cb
--- /dev/null
+++ b/repobee_feedback/_generate_multi_issues_file.py
@@ -0,0 +1,62 @@
+"""A helper command to automatically generate a file called issue.md
+wich contains templates of issues for multiple students assignments.
+
+.. module:: _generate_multi_issues_file
+    :synopsis: A helper command to automatically generate a file
+    called issue.md wich contains templates of issues for multiple
+    students assignments.
+
+.. moduleauthor:: Marcelo Freitas
+"""
+import pathlib
+import sys
+from typing import List
+
+import repobee_plug as plug
+from repobee_plug.cli.categorization import Action
+
+MULTI_ISSUES_FILENAME = "issue.md"
+
+GENERATE_MULTI_ISSUES_FILE_ACTION = Action(
+    name="generate-multi-issues-file",
+    category=plug.cli.CoreCommand.issues,
+)
+
+
+class GenerateMultiIssuesFile(plug.Plugin, plug.cli.Command):
+    __settings__ = plug.cli.command_settings(
+        help=(
+            "auto generate multi-issues file"
+            " for the `issues feedback` command"
+        ),
+        description="Will generate a multi-issues file template "
+        "where each pair of student assignment passed "
+        "will become an issue that starts with the line "
+        "#ISSUE#<STUDENT_REPO_NAME>#<ISSUE_TITLE>, followed by its "
+        "body. Title and body should be filled appropriately later.",
+        action=GENERATE_MULTI_ISSUES_FILE_ACTION,
+        base_parsers=[plug.BaseParser.ASSIGNMENTS, plug.BaseParser.STUDENTS],
+    )
+
+    def command(self):
+        content = _generate_multi_issues_file_content(
+            self.args.students, self.args.assignments
+        )
+
+        pathlib.Path(MULTI_ISSUES_FILENAME).write_text(
+            content, encoding=sys.getdefaultencoding()
+        )
+
+        plug.echo(f"Created multi-issues file '{MULTI_ISSUES_FILENAME}'")
+
+
+def _generate_multi_issues_file_content(
+    students: List[str], assignments: List[str]
+) -> str:
+
+    issue_headers = [
+        f"#ISSUE#{repo_name}#<ISSUE-TITLE>\n<ISSUE-BODY>"
+        for repo_name in plug.generate_repo_names(students, assignments)
+    ]
+
+    return "\n\n".join(issue_headers)
diff --git a/repobee_feedback/feedback.py b/repobee_feedback/feedback.py
index f4ceb59..cc6d488 100644
--- a/repobee_feedback/feedback.py
+++ b/repobee_feedback/feedback.py
@@ -15,6 +15,9 @@ from textwrap import indent
 from typing import Iterable, Tuple, List, Mapping
 
 import repobee_plug as plug
+from repobee_feedback._generate_multi_issues_file import (  # noqa: F401
+    GenerateMultiIssuesFile,
+)
 
 PLUGIN_NAME = "feedback"
 


Test patch:
diff --git a/tests/test_generate_multi_issues_file.py b/tests/test_generate_multi_issues_file.py
new file mode 100644
index 0000000..29b2c36
--- /dev/null
+++ b/tests/test_generate_multi_issues_file.py
@@ -0,0 +1,45 @@
+import sys
+
+import repobee
+from repobee_feedback._generate_multi_issues_file import (
+    MULTI_ISSUES_FILENAME,
+    GENERATE_MULTI_ISSUES_FILE_ACTION,
+    GenerateMultiIssuesFile,
+)
+
+
+class TestGenerateMultiIssuesFile:
+    """Tests generation of a multi-issues file"""
+
+    def test_creates_non_empty_output_file(self, tmp_path):
+        students = "alice bob".split()
+        assignments = "task-1 task-2".split()
+        command = [
+            *GENERATE_MULTI_ISSUES_FILE_ACTION.as_name_tuple(),
+            "--students",
+            *students,
+            "--assignments",
+            *assignments,
+        ]
+
+        expected_content = (
+            "#ISSUE#alice-task-1#<ISSUE-TITLE>\n"
+            "<ISSUE-BODY>\n\n"
+            "#ISSUE#bob-task-1#<ISSUE-TITLE>\n"
+            "<ISSUE-BODY>\n\n"
+            "#ISSUE#alice-task-2#<ISSUE-TITLE>\n"
+            "<ISSUE-BODY>\n\n"
+            "#ISSUE#bob-task-2#<ISSUE-TITLE>\n"
+            "<ISSUE-BODY>"
+        )
+
+        repobee.run(
+            command,
+            plugins=[GenerateMultiIssuesFile],
+            workdir=tmp_path,
+        )
+
+        outfile = tmp_path / MULTI_ISSUES_FILENAME
+        content = outfile.read_text(encoding=sys.getdefaultencoding())
+        assert outfile.is_file()
+        assert content == expected_content