diff --git a/ryujinx_mako/__main__.py b/ryujinx_mako/__main__.py index b47dfef..2b51f9e 100644 --- a/ryujinx_mako/__main__.py +++ b/ryujinx_mako/__main__.py @@ -3,6 +3,7 @@ import logging from ryujinx_mako import commands from ryujinx_mako._const import SCRIPT_NAME +from ryujinx_mako.commands import Subcommand parser = argparse.ArgumentParser( prog=SCRIPT_NAME, @@ -21,8 +22,9 @@ for subcommand in commands.SUBCOMMANDS: description=subcommand.description(), add_help=True, ) + Subcommand.add_subcommand(subcommand.name(), subcommand(subcommand_parser)) # Keep a reference to the subcommand - subcommands.append(subcommand(subcommand_parser)) + subcommands.append(Subcommand.get_subcommand(subcommand.name())) def run(): diff --git a/ryujinx_mako/commands/_subcommand.py b/ryujinx_mako/commands/_subcommand.py index 1ba3260..00d269c 100644 --- a/ryujinx_mako/commands/_subcommand.py +++ b/ryujinx_mako/commands/_subcommand.py @@ -1,6 +1,7 @@ import logging from abc import ABC, abstractmethod from argparse import ArgumentParser, Namespace +from typing import Any from github import Github from github.Auth import AppAuth @@ -9,6 +10,8 @@ from ryujinx_mako._const import APP_ID, PRIVATE_KEY, INSTALLATION_ID, SCRIPT_NAM class Subcommand(ABC): + _subcommands: dict[str, Any] = {} + @abstractmethod def __init__(self, parser: ArgumentParser): parser.set_defaults(func=self.run) @@ -33,6 +36,16 @@ class Subcommand(ABC): def description() -> str: raise NotImplementedError() + @classmethod + def get_subcommand(cls, name: str): + return cls._subcommands[name] + + @classmethod + def add_subcommand(cls, name: str, subcommand): + if name in cls._subcommands.keys(): + raise ValueError(f"Key '{name}' already exists in {cls}._subcommands") + cls._subcommands[name] = subcommand + class GithubSubcommand(Subcommand, ABC): _github = Github( diff --git a/ryujinx_mako/commands/exec_ryujinx_tasks.py b/ryujinx_mako/commands/exec_ryujinx_tasks.py new file mode 100644 index 0000000..0c69e65 --- /dev/null +++ b/ryujinx_mako/commands/exec_ryujinx_tasks.py @@ -0,0 +1,88 @@ +import json +import os +from argparse import ArgumentParser, Namespace +from pathlib import Path +from typing import Any + +from github.Repository import Repository +from github.WorkflowRun import WorkflowRun + +from ryujinx_mako.commands._subcommand import GithubSubcommand + + +class ExecRyujinxTasks(GithubSubcommand): + @staticmethod + def name() -> str: + return "exec-ryujinx-tasks" + + @staticmethod + def description() -> str: + return "Execute all Ryujinx tasks for a specific event" + + # noinspection PyTypeChecker + def __init__(self, parser: ArgumentParser): + self._workspace: Path = None + self._repo: Repository = None + self._workflow_run: WorkflowRun = None + self._event: dict[str, Any] = None + self._event_name: str = None + + parser.add_argument( + "--event-name", + type=str, + required=True, + help="The name of the event that triggered the workflow run.", + ) + parser.add_argument( + "--event-path", + type=str, + required=True, + help="The path to the file on the runner that contains the full " + "event webhook payload.", + ) + parser.add_argument( + "-w", + "--workspace", + type=Path, + required=False, + default=Path(os.getcwd()), + help="The working directory on the runner." + ) + parser.add_argument( + "repo_path", + type=str, + required=True, + help="The path to a GitHub repository." + ) + parser.add_argument( + "run_id", + type=int, + required=True, + help="The unique identifier of the workflow run.", + ) + super().__init__(parser) + + def update_reviewers(self): + # Prepare update-reviewers + self.logger.info("Task: update-reviewers") + args = Namespace() + args.repo_path = self._repo.full_name + args.pr_number = self._event["number"] + args.config_path = Path(self._workspace, ".github", "reviewers.yml") + # Run task + self.get_subcommand("update-reviewers").run(args) + + def run(self, args: Namespace): + self.logger.info("Executing Ryujinx tasks...") + + self._workspace = args.workspace + self._repo = self.github.get_repo(args.repo_path) + self._workflow_run = self._repo.get_workflow_run(args.run_id) + self._event_name = args.event_name + with open(args.event_path, "r") as file: + self._event = json.load(file) + + if args.event_name == "pull_request": + self.update_reviewers() + + self.logger.info("Finished executing Ryujinx tasks!")