diff --git a/pydantic_pkgr/binprovider.py b/pydantic_pkgr/binprovider.py index 95c25c0..153125e 100755 --- a/pydantic_pkgr/binprovider.py +++ b/pydantic_pkgr/binprovider.py @@ -161,8 +161,8 @@ class BinProvider(BaseModel): PATH: PATHStr = Field(default=str(Path(sys.executable).parent)) # e.g. '/opt/homebrew/bin:/opt/archivebox/bin' INSTALLER_BIN: BinName = 'env' - abspath_handler: ProviderLookupDict = Field(default={'*': 'self.on_get_abspath'}, exclude=True) version_handler: ProviderLookupDict = Field(default={'*': 'self.on_get_version'}, exclude=True) + abspath_handler: ProviderLookupDict = Field(default={'*': 'self.on_get_abspath'}, exclude=True) packages_handler: ProviderLookupDict = Field(default={'*': 'self.on_get_packages'}, exclude=True) install_handler: ProviderLookupDict = Field(default={'*': 'self.on_install'}, exclude=True) @@ -348,8 +348,8 @@ def on_get_abspath(self, bin_name: BinName | HostBinPath, **context) -> HostBinP return None return bin_abspath(bin_name, PATH=self.PATH) - def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, **context) -> SemVer | None: + abspath = abspath or self._abspath_cache.get(bin_name) or self.get_abspath(bin_name, quiet=True) if not abspath: return None @@ -358,7 +358,7 @@ def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, validation_err = None # Attempt 1: $ --version - dash_dash_version_result = self.exec(bin_name=abspath, cmd=['--version']) + dash_dash_version_result = self.exec(bin_name=abspath, cmd=['--version'], timeout=10, quiet=True) dash_dash_version_out = dash_dash_version_result.stdout.strip() try: version = SemVer.parse(dash_dash_version_out) @@ -368,7 +368,7 @@ def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, validation_err = err # Attempt 2: $ -version - dash_version_out = self.exec(bin_name=abspath, cmd=["-version"]).stdout.strip() + dash_version_out = self.exec(bin_name=abspath, cmd=["-version"], timeout=10, quiet=True).stdout.strip() try: version = SemVer.parse(dash_version_out) assert version, f"Could not parse version from $ {bin_name} -version: {dash_version_out}".strip() @@ -377,7 +377,7 @@ def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, validation_err = validation_err or err # Attempt 3: $ -v - dash_v_out = self.exec(bin_name=abspath, cmd=["-v"]).stdout.strip() + dash_v_out = self.exec(bin_name=abspath, cmd=["-v"], timeout=10, quiet=True).stdout.strip() try: version = SemVer.parse(dash_v_out) assert version, f"Could not parse version from $ {bin_name} -v: {dash_v_out}".strip() @@ -455,8 +455,8 @@ def get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, ov try: version = self.call_handler_for_action( bin_name=bin_name, - handler_type='version', default_handler=self.on_get_version, + handler_type='version', overrides=overrides, abspath=abspath, timeout=timeout, diff --git a/pydantic_pkgr/binprovider_apt.py b/pydantic_pkgr/binprovider_apt.py index 26baac1..a5715d8 100755 --- a/pydantic_pkgr/binprovider_apt.py +++ b/pydantic_pkgr/binprovider_apt.py @@ -28,7 +28,7 @@ def load_PATH_from_dpkg_install_location(self): return self PATH = self.PATH - dpkg_install_dirs = self.exec(bin_name=dpkg_abspath, cmd=["-L", "bash"]).stdout.strip().split("\n") + dpkg_install_dirs = self.exec(bin_name=dpkg_abspath, cmd=["-L", "bash"], quiet=True).stdout.strip().split("\n") dpkg_bin_dirs = [path for path in dpkg_install_dirs if path.endswith("/bin")] for bin_dir in dpkg_bin_dirs: if str(bin_dir) not in PATH: diff --git a/pydantic_pkgr/binprovider_brew.py b/pydantic_pkgr/binprovider_brew.py index d7d6e40..11f509f 100755 --- a/pydantic_pkgr/binprovider_brew.py +++ b/pydantic_pkgr/binprovider_brew.py @@ -97,7 +97,7 @@ def on_get_abspath(self, bin_name: BinName | HostBinPath, **context) -> HostBinP # fallback to using brew info to get the Cellar bin path for package in (self.on_get_packages(str(bin_name)) or [str(bin_name)]): try: - info_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['info', '--quiet', package], timeout=5).stdout.strip().split('\n') + info_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['info', '--quiet', package], timeout=5, quiet=True).stdout.strip().split('\n') # /opt/homebrew/Cellar/curl/8.10.0 (530 files, 4MB) cellar_path = [line for line in info_lines if '/Cellar/' in line][0].rsplit(' (', 1)[0] abspath = bin_abspath(bin_name, PATH=f'{cellar_path}/bin') @@ -123,7 +123,7 @@ def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, # fallback to using brew info to get the version package = (self.on_get_packages(str(bin_name)) or [str(bin_name)])[-1] # assume last package in list is the main one try: - version_str = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['info', '--quiet', package], timeout=5).stdout.strip() + version_str = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['info', '--quiet', package], quiet=True, timeout=5).stdout.strip() return SemVer.parse(version_str) except Exception: return None diff --git a/pydantic_pkgr/binprovider_npm.py b/pydantic_pkgr/binprovider_npm.py index 7574f8e..4dd40dc 100755 --- a/pydantic_pkgr/binprovider_npm.py +++ b/pydantic_pkgr/binprovider_npm.py @@ -44,7 +44,7 @@ def load_PATH_from_npm_prefix(self): npm_bin_dirs = {str(self.npm_prefix / 'node_modules/.bin')} else: # find all local and global npm PATHs - npm_local_dir = _CACHED_LOCAL_NPM_PREFIX or self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix']).stdout.strip() + npm_local_dir = _CACHED_LOCAL_NPM_PREFIX or self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix'], quiet=True).stdout.strip() _CACHED_LOCAL_NPM_PREFIX = npm_local_dir # start at npm_local_dir and walk up to $HOME (or /), finding all npm bin dirs along the way @@ -61,7 +61,7 @@ def load_PATH_from_npm_prefix(self): search_dir = search_dir.parent num_hops += 1 - npm_global_dir = _CACHED_GLOBAL_NPM_PREFIX or self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix', '-g']).stdout.strip() + '/bin' # /opt/homebrew/bin + npm_global_dir = _CACHED_GLOBAL_NPM_PREFIX or self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['prefix', '-g'], quiet=True).stdout.strip() + '/bin' # /opt/homebrew/bin _CACHED_GLOBAL_NPM_PREFIX = npm_global_dir npm_bin_dirs.add(npm_global_dir) @@ -115,7 +115,7 @@ def on_get_abspath(self, bin_name: BinName | HostBinPath, **context) -> HostBinP # fallback to using npm show to get alternate binary names based on the package try: package = (self.on_get_packages(str(bin_name)) or [str(bin_name)])[-1] # assume last package in list is the main one - output_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['show', package], timeout=5).stdout.strip().split('\n') + output_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['show', package], timeout=5, quiet=True).stdout.strip().split('\n') bin_name = [line for line in output_lines if line.startswith('bin: ')][0].split('bin: ', 1)[-1].split(', ')[0] abspath = bin_abspath(bin_name, PATH=self.PATH) if abspath: @@ -144,7 +144,7 @@ def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, f'--prefix={self.npm_prefix}' if self.npm_prefix else '--global', '--depth=0', package, - ], timeout=5).stdout.strip() + ], timeout=5, quiet=True).stdout.strip() # /opt/homebrew/lib # └── @postlight/parser@2.2.3 version_str = output_line.split('\n')[1].rsplit('@', 1)[-1] diff --git a/pydantic_pkgr/binprovider_pip.py b/pydantic_pkgr/binprovider_pip.py index 1fc5267..d0e0781 100755 --- a/pydantic_pkgr/binprovider_pip.py +++ b/pydantic_pkgr/binprovider_pip.py @@ -67,7 +67,7 @@ def load_PATH_from_pip_sitepackages(self): elif self.INSTALLER_BIN == "pipx": # restrict PATH to only use global pipx bin path if self.INSTALLER_BIN_ABSPATH and shutil.which(self.INSTALLER_BIN_ABSPATH): - proc = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=["environment"]) # run $ pipx environment + proc = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=["environment"], quiet=True, timeout=5) # run $ pipx environment if proc.returncode == 0: PIPX_BIN_DIR = proc.stdout.strip().split("PIPX_BIN_DIR=")[-1].split("\n", 1)[0] pip_bin_dirs = {PIPX_BIN_DIR} @@ -159,7 +159,7 @@ def on_get_abspath(self, bin_name: BinName | HostBinPath, **context) -> HostBinP # fallback to using pip show to get the site-packages bin path packages = self.on_get_packages(str(bin_name)) or [str(bin_name)] - output_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['show', *packages], timeout=5).stdout.strip().split('\n') + output_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['show', *packages], timeout=5, quiet=True).stdout.strip().split('\n') try: location = [line for line in output_lines if line.startswith('Location: ')][0].split('Location: ', 1)[-1] except IndexError: @@ -185,7 +185,7 @@ def on_get_version(self, bin_name: BinName, abspath: Optional[HostBinPath]=None, # fallback to using pip show to get the version package = (self.on_get_packages(str(bin_name)) or [str(bin_name)])[-1] # assume last package in list is the main one - output_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['show', package], timeout=5).stdout.strip().split('\n') + output_lines = self.exec(bin_name=self.INSTALLER_BIN_ABSPATH, cmd=['show', package], timeout=5, quiet=True).stdout.strip().split('\n') try: version_str = [line for line in output_lines if line.startswith('Version: ')][0].split('Version: ', 1)[-1] return SemVer.parse(version_str) diff --git a/pyproject.toml b/pyproject.toml index 6b88309..72b0ea8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pydantic-pkgr" -version = "0.4.0" +version = "0.4.2" description = "System package manager APIs in strongly typed Python" authors = [ {name = "Nick Sweeting", email = "pydantic-pkgr-pyproject-toml@sweeting.me"},