diff --git a/src/onepm/base.py b/src/onepm/base.py index 06b4cbe..d3c9d84 100644 --- a/src/onepm/base.py +++ b/src/onepm/base.py @@ -5,6 +5,7 @@ import shutil import subprocess import sys +from pathlib import Path from typing import Any, Iterable, NoReturn @@ -32,9 +33,9 @@ def __init__(self) -> None: self.command = self.get_command() @staticmethod - def find_executable(name: str) -> str: + def find_executable(name: str, path: str | Path | None = None) -> str: # TODO: to keep it simple, only search in PATH(no alias/shell function) - executable = shutil.which(name) + executable = shutil.which(name, path=path) if not executable: raise Exception(f"{name} is not found in PATH, did you install it?") return executable diff --git a/src/onepm/pip.py b/src/onepm/pip.py index a8fa59d..e6bcbcf 100644 --- a/src/onepm/pip.py +++ b/src/onepm/pip.py @@ -79,4 +79,13 @@ def uninstall(self, *args: str) -> NoReturn: self.execute("uninstall", *args) def run(self, *args: str) -> NoReturn: - self._execute_command(list(args)) + if len(args) == 0: + raise Exception("Please specify a command to run.") + command, *rest = args + venv = self._ensure_virtualenv() + bin_dir = "Scripts" if sys.platform == "win32" else "bin" + path = os.getenv("PATH", "") + command = self.find_executable( + command, os.pathsep.join([os.path.join(venv, bin_dir), path]) + ) + self._execute_command([command, *rest]) diff --git a/tests/test_pip.py b/tests/test_pip.py index 88b2857..96336d6 100644 --- a/tests/test_pip.py +++ b/tests/test_pip.py @@ -11,7 +11,14 @@ @pytest.fixture def venv(monkeypatch): + @staticmethod + def mock_find_executable(name: str, path: str | None = None) -> str: + return name + monkeypatch.setenv("VIRTUAL_ENV", "foo") + monkeypatch.setattr( + "onepm.base.PackageManager.find_executable", mock_find_executable + ) def test_pip_detect_activated_venv(venv, project):