mirror of
https://github.com/mvt-project/mvt.git
synced 2026-09-03 00:21:07 +02:00
Each console script imports its CLI module before Click can answer a shell completion request, and the completion scripts run the program on every keystroke. Importing mvt.ios.cli or mvt.android.cli took ~230 ms, of which building the command tree needed almost nothing: cli_plugins imported one constant from module_loader, which pulled in MVTModule, the indicators, the pydantic settings, requests and rich; the command implementations pulled in the same, and the iOS CLI imported iOSbackup (pycryptodome) for decrypt-backup. The two platform CLI modules now only build the command tree: each command imports what it runs when it is invoked. cli_plugins owns the custom command prefix instead of importing it from module_loader, and exec_or_profile() loads the settings when it runs. Completion of mvt-ios and mvt-android drops from ~260 ms to ~85 ms per keystroke on a clean install, and every command starts that much sooner. A test fails as soon as a CLI module imports the module machinery again.
29 lines
1.2 KiB
Python
29 lines
1.2 KiB
Python
# Mobile Verification Toolkit (MVT)
|
|
# Copyright (c) 2021-2026 The MVT Authors.
|
|
# Use of this software is governed by the MVT License 1.1 that can be found at
|
|
# https://license.mvt.re/1.1/
|
|
|
|
import pytest
|
|
|
|
from .plugin_fixtures import run_isolated_python
|
|
|
|
# Importing a platform CLI must only build its command tree: the console
|
|
# scripts import it before Click can answer a shell completion request, which
|
|
# the completion scripts make on every keystroke. Every command imports what
|
|
# it runs when it is invoked. Each of these costs tens of milliseconds to
|
|
# import and is the sign that a command implementation is imported too early.
|
|
HEAVY_MODULES = ("pydantic", "requests", "Crypto", "mvt.common.module")
|
|
|
|
|
|
@pytest.mark.parametrize("cli_module", ("mvt.ios.cli", "mvt.android.cli"))
|
|
def test_importing_a_cli_does_not_import_the_module_machinery(cli_module, tmp_path):
|
|
result = run_isolated_python(
|
|
"import sys\n"
|
|
f"import {cli_module}\n"
|
|
f"print(','.join(name for name in {HEAVY_MODULES!r} if name in sys.modules))\n",
|
|
home=tmp_path / "home",
|
|
)
|
|
|
|
assert result.returncode == 0, result.stderr
|
|
assert result.stdout.strip() == "", f"{cli_module} imported {result.stdout.strip()}"
|