Skip to content

Commit

Permalink
Merge pull request #111 from discord-modmail/scripts-wrapper
Browse files Browse the repository at this point in the history
scripts: add wrapper to run scripts by invoking the scripts module
  • Loading branch information
onerandomusername committed Nov 14, 2021
2 parents 92356fd + 5a2a2e3 commit 7c7a589
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 4 deletions.
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pytest-xdist = { version = "^2.3.0", extras = ["psutil"] }
mkdocs = ">=1.1.2,<2.0.0"
mkdocs-material = ">=7.1.9,<8.0.0"
mkdocs-markdownextradata-plugin = ">=0.1.7,<0.2.0"
# Scripts
click = "^8.0.3"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down Expand Up @@ -88,5 +90,6 @@ flake8 = { cmd = "python -m flake8", help = "Lints code with flake8" }
lint = { cmd = "pre-commit run --all-files", help = "Checks all files for CI errors" }
precommit = { cmd = "pre-commit install --install-hooks", help = "Installs the precommit hook" }
report = { cmd = "coverage report", help = "Show coverage report from previously run tests." }
scripts = { cmd = 'python -m scripts', help = 'Run the scripts wrapper cli.' }
test = { cmd = "pytest -n auto --dist loadfile", help = "Runs tests and save results to a coverage report" }
test_mocks = { cmd = 'pytest tests/test_mocks.py', help = 'Runs the tests on the mock files. They are excluded from the main test suite.' }
Empty file added scripts/__init__.py
Empty file.
68 changes: 68 additions & 0 deletions scripts/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
Script wrapper for scripts.
This allows scripts to be invoked through the scripts module.
The exposed interface is just running the internal files.
Whatever interface they have, is what is shown.
"""

import functools
import runpy
import sys

import click


# key: alias
# value: tuple of module name, help description
commands: "dict[str, tuple[str, str | None]]" = {
"export_req": ("scripts.export_requirements", "Export requirements to requirements.txt"),
}


def run_script(module_name: str, *args, **kwargs) -> None:
"""
Run the provided module, with the provided args and kwargs.
The provided defaults are what makes the environment nearly the same as if module was invoked directly.
"""
kwargs.setdefault("run_name", "__main__")
kwargs.setdefault("alter_sys", True)
runpy.run_module(module_name, **kwargs)


@click.group()
@click.help_option("-h", "--help")
def cli() -> None:
"""
Custom scripts which help modmail development.
All custom scripts should be listed below as a command, with a description.
In addition, some built in modules may be listed below as well.
If a custom script is not shown below please open an issue.
"""
pass


def main(cmd: str = None) -> None:
"""Add the commands and run the cli."""
if cmd is None:
cmd = []
for k, v in commands.items():
func = functools.partial(run_script, v[0])
cli.add_command(click.Command(k, help=v[1], callback=func))
cli.main(cmd, standalone_mode=False)


if __name__ == "__main__":
try:
cmd = [sys.argv[1]]
sys.argv.pop(1) # pop the first arg out of sys.argv since its being used to get the name
except IndexError:
cmd = []
try:
main(cmd)
except click.ClickException as e:
e.show()
sys.exit()

0 comments on commit 7c7a589

Please sign in to comment.