refactor(pyghidra_launcher): Improve get_package_version implementation

Refactors the `get_package_version` helper function to use the standard
`importlib.metadata` library instead of a subprocess call to `pip show`.

This change provides several benefits:
- Robustness: Avoids brittle parsing of command-line tool output.
- Performance: Eliminates the overhead of spawning a new process.
- Correctness: The return type hint is corrected to `Optional[str]` to
  accurately reflect that the function can return `None`.
- Simplicity: The unused `python_cmd` parameter has been removed,
  simplifying the function's signature.
This commit is contained in:
jhq223
2025-10-25 18:18:05 +08:00
parent 4e4a14f0d1
commit 8148f6364f

View File

@@ -21,7 +21,8 @@ import subprocess
import sysconfig
from pathlib import Path
from itertools import chain
from typing import List, Dict, Tuple
from importlib import metadata
from typing import List, Dict, Tuple, Optional
def get_application_properties(install_dir: Path) -> Dict[str, str]:
app_properties_path: Path = install_dir / 'Ghidra' / 'application.properties'
@@ -137,16 +138,14 @@ def version_tuple(v: str) -> Tuple[str, ...]:
filled.append(point.zfill(8))
return tuple(filled)
def get_package_version(python_cmd: List[str], package: str) -> str:
version = None
result = subprocess.run(python_cmd + ['-m', 'pip', 'show', package], capture_output=True, text=True)
for line in result.stdout.splitlines():
line = line.strip()
print(line)
key, value = line.split(':', 1)
if key == 'Version':
version = value.strip()
return version
def get_package_version(package: str) -> Optional[str]:
"""
Checks for an installed package version.
"""
try:
return metadata.version(package)
except metadata.PackageNotFoundError:
return None
def get_saved_python_cmd(install_dir: Path, dev: bool) -> List[str]:
user_settings_dir: Path = get_user_settings_dir(install_dir, dev)
@@ -269,7 +268,7 @@ def main() -> None:
# If PyGhidra is not installed in the execution environment, offer to install it
# If it's already installed, offer to upgrade (if applicable)
current_pyghidra_version = get_package_version(python_cmd, 'pyghidra')
current_pyghidra_version = get_package_version('pyghidra')
if current_pyghidra_version is None:
python_cmd = install(install_dir, python_cmd, pip_args, offer_venv)
if not python_cmd:
@@ -289,6 +288,6 @@ def main() -> None:
else:
creation_flags = getattr(subprocess, 'CREATE_NO_WINDOW', 0)
subprocess.Popen(py_args + remaining, creationflags=creation_flags, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if __name__ == "__main__":
main()