feat(cli): manim-slides checkhealth (#458)

* feat(cli): `manim-slides checkhealth`

Closes #457

* chore(fmt): auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore(tests): implement some basic tests

* chore(docs): document changes

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Jérome Eertmans
2024-08-27 12:23:24 +02:00
committed by GitHub
parent 5b6f5eb1e4
commit c047da67b1
8 changed files with 139 additions and 24 deletions

View File

@ -73,22 +73,22 @@ body:
description: |
Please copy and paste the output of `python --version`.
Make sure to activate your virtual environment first (if any).
This will be automatically formatted into code, so no need for backticks.
placeholder: Python 3.11.8
validations:
required: false
required: true
- type: textarea
id: venv
attributes:
label: Python environment
description: |
Please copy and paste the output of `pip freeze`.
Please copy and paste the output of `manim-slides checkhealth`.
Make sure to activate your virtual environment first (if any).
This will be automatically formatted into code, so no need for backticks.
If Manim Slides installation failed, enter 'N/A' instead.
render: shell
validations:
required: false
required: true
- type: dropdown
id: platform

View File

@ -10,6 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
(unreleased)=
## [Unreleased](https://github.com/jeertmans/manim-slides/compare/v5.1.7...HEAD)
(unreleased-added)=
### Added
- Added `manim-slides checkhealth` command to easily obtain important information
for debug purposes.
[#458](https://github.com/jeertmans/manim-slides/pull/458)
(unreleased-chore)=
### Chore

View File

@ -5,6 +5,7 @@ import requests
from click_default_group import DefaultGroup
from .__version__ import __version__
from .checkhealth import checkhealth
from .convert import convert
from .logger import logger
from .present import list_scenes, present
@ -63,6 +64,7 @@ def cli(notify_outdated_version: bool) -> None:
cli.add_command(convert)
cli.add_command(checkhealth)
cli.add_command(init)
cli.add_command(list_scenes)
cli.add_command(present)

View File

@ -0,0 +1,39 @@
import sys
import click
from .__version__ import __version__
@click.command()
def checkhealth() -> None:
"""Check Manim Slides' installation."""
click.echo(f"Manim Slides version: {__version__}")
click.echo(f"Python executable: {sys.executable}")
click.echo("Manim bindings:")
click.echo(f"Modules: {sys.modules.keys()}")
try:
from manim import __version__ as manimce_version
click.echo(f"\tmanim (version: {manimce_version})")
except ImportError:
click.secho("\tmanim not found", bold=True)
try:
from manimlib import __version__ as manimlib_version
click.echo(f"\tmanimgl (version: {manimlib_version})")
except ImportError:
click.secho("\tmanimgl not found", bold=True)
try:
from qtpy import API, QT_VERSION
click.echo(f"Qt API: {API} (version: {QT_VERSION})")
except ImportError:
click.secho(
"No Qt API found, some Manim Slides commands will not be available",
bold=True,
)

View File

@ -33,6 +33,7 @@ dependencies = [
"rtoml==0.9.0;sys_platform=='win32' and python_version<'3.13'",
"rtoml>=0.9.0;sys_platform!='win32' or python_version>='3.13'",
"tqdm>=4.64.1",
"pytest-missing-modules>=0.1.0",
]
description = "Tool for live presentations using manim"
dynamic = ["readme", "version"]
@ -217,6 +218,7 @@ isort = {known-first-party = ["manim_slides", "tests"]}
dev-dependencies = [
"bump-my-version>=0.20.3",
"pre-commit>=3.5.0",
"setuptools>=73.0.1",
]
managed = true

View File

@ -7,7 +7,6 @@
# all-features: true
# with-sources: false
# generate-hashes: false
# universal: false
-e file:.
alabaster==1.0.0
@ -49,12 +48,6 @@ click-default-group==1.2.4
# via manim-slides
cloup==3.0.5
# via manim
colorama==0.4.6
# via click
# via ipython
# via pytest
# via sphinx
# via tqdm
colour==0.1.5
# via manimgl
comm==0.2.2
@ -198,6 +191,7 @@ nodeenv==1.9.1
numpy==1.24.0
# via --override (workspace)
# via contourpy
# via ipython
# via isosurfaces
# via manim
# via manim-slides
@ -205,6 +199,7 @@ numpy==1.24.0
# via mapbox-earcut
# via matplotlib
# via moderngl-window
# via networkx
# via pyrr
# via scipy
packaging==24.1
@ -220,6 +215,8 @@ pandocfilters==1.5.1
# via nbconvert
parso==0.8.4
# via jedi
pexpect==4.9.0
# via ipython
pillow==10.4.0
# via manim
# via manim-slides
@ -243,6 +240,8 @@ prompt-toolkit==3.0.47
# via questionary
psutil==6.0.0
# via ipykernel
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.3
# via stack-data
pycairo==1.26.1
@ -294,11 +293,14 @@ pytest==8.3.2
# via manim-slides
# via pytest-cov
# via pytest-env
# via pytest-missing-modules
# via pytest-qt
pytest-cov==5.0.0
# via manim-slides
pytest-env==1.1.3
# via manim-slides
pytest-missing-modules==0.1.0
# via manim-slides
pytest-qt==4.4.0
# via manim-slides
python-dateutil==2.9.0.post0
@ -308,9 +310,6 @@ python-dotenv==1.0.1
# via pydantic-settings
python-pptx==1.0.2
# via manim-slides
pywin32==306
# via jupyter-core
# via plumbum
pyyaml==6.0.2
# via manimgl
# via myst-parser
@ -347,6 +346,7 @@ scipy==1.14.1
screeninfo==0.8.1
# via manim
# via manimgl
setuptools==73.0.1
shiboken6==6.7.2
# via pyside6
# via pyside6-addons

View File

@ -7,7 +7,6 @@
# all-features: true
# with-sources: false
# generate-hashes: false
# universal: false
-e file:.
alabaster==1.0.0
@ -42,12 +41,6 @@ click-default-group==1.2.4
# via manim-slides
cloup==3.0.5
# via manim
colorama==0.4.6
# via click
# via ipython
# via pytest
# via sphinx
# via tqdm
colour==0.1.5
# via manimgl
comm==0.2.2
@ -183,6 +176,7 @@ networkx==3.3
numpy==1.24.0
# via --override (workspace)
# via contourpy
# via ipython
# via isosurfaces
# via manim
# via manim-slides
@ -190,6 +184,7 @@ numpy==1.24.0
# via mapbox-earcut
# via matplotlib
# via moderngl-window
# via networkx
# via pyrr
# via scipy
packaging==24.1
@ -205,6 +200,8 @@ pandocfilters==1.5.1
# via nbconvert
parso==0.8.4
# via jedi
pexpect==4.9.0
# via ipython
pillow==10.4.0
# via manim
# via manim-slides
@ -225,6 +222,8 @@ prompt-toolkit==3.0.47
# via ipython
psutil==6.0.0
# via ipykernel
ptyprocess==0.7.0
# via pexpect
pure-eval==0.2.3
# via stack-data
pycairo==1.26.1
@ -272,11 +271,14 @@ pytest==8.3.2
# via manim-slides
# via pytest-cov
# via pytest-env
# via pytest-missing-modules
# via pytest-qt
pytest-cov==5.0.0
# via manim-slides
pytest-env==1.1.3
# via manim-slides
pytest-missing-modules==0.1.0
# via manim-slides
pytest-qt==4.4.0
# via manim-slides
python-dateutil==2.9.0.post0
@ -284,9 +286,6 @@ python-dateutil==2.9.0.post0
# via matplotlib
python-pptx==1.0.2
# via manim-slides
pywin32==306
# via jupyter-core
# via plumbum
pyyaml==6.0.2
# via manimgl
# via myst-parser

66
tests/test_checkhealth.py Normal file
View File

@ -0,0 +1,66 @@
import importlib.util
import sys
from itertools import chain, combinations
import pytest
from click.testing import CliRunner
from pytest_missing_modules.plugin import MissingModulesContextGenerator
from manim_slides.__version__ import __version__
from manim_slides.checkhealth import checkhealth
MANIM_NOT_INSTALLED = importlib.util.find_spec("manim") is None
MANIMGL_NOT_INSTALLED = importlib.util.find_spec("manimlib") is None
PYQT6_NOT_INSTALLED = importlib.util.find_spec("PyQt6") is None
PYSIDE6_NOT_INSTALLED = importlib.util.find_spec("PySide6") is None
@pytest.mark.filterwarnings("ignore:Selected binding 'pyqt6' could not be found")
@pytest.mark.parametrize(
"names",
list(
chain.from_iterable(
combinations(("manim", "manimlib", "PyQt6", "PySide6"), r=r)
for r in range(0, 5)
)
),
)
def test_checkhealth(
names: tuple[str, ...], missing_modules: MissingModulesContextGenerator
) -> None:
runner = CliRunner()
manim_missing = "manim" in names or MANIM_NOT_INSTALLED
manimlib_missing = "manimlib" in names or MANIMGL_NOT_INSTALLED
pyqt6_missing = "PyQt6" in names or PYQT6_NOT_INSTALLED
pyside6_missing = "PySide6" in names or PYSIDE6_NOT_INSTALLED
if "qtpy" in sys.modules:
del sys.modules["qtpy"] # Avoid using cached module
with missing_modules(*names):
result = runner.invoke(
checkhealth,
env={"QT_API": "pyqt6", "FORCE_QT_API": "1"},
)
assert result.exit_code == 0
assert f"Manim Slides version: {__version__}" in result.output
assert sys.executable in result.output
if manim_missing:
assert "manim not found" in result.output
else:
assert "manim (version:" in result.output
if manimlib_missing:
assert "manimgl not found" in result.output
else:
assert "manimgl (version:" in result.output
if pyqt6_missing and pyside6_missing:
assert "No Qt API found" in result.output
elif pyqt6_missing:
assert "Qt API: pyside6 (version:" in result.output
else:
assert "Qt API: pyqt6 (version:" in result.output