def inject_dep( venv_dir: Path, package_name: Optional[str], package_spec: str, pip_args: List[str], *, verbose: bool, include_apps: bool, include_dependencies: bool, force: bool, ) -> bool: if not venv_dir.exists() or not next(venv_dir.iterdir()): raise PipxError(f""" Can't inject {package_spec!r} into nonexistent Virtual Environment {venv_dir.name!r}. Be sure to install the package first with 'pipx install {venv_dir.name}' before injecting into it. """) venv = Venv(venv_dir, verbose=verbose) if not venv.package_metadata: raise PipxError(f""" Can't inject {package_spec!r} into Virtual Environment {venv.name!r}. {venv.name!r} has missing internal pipx metadata. It was likely installed using a pipx version before 0.15.0.0. Please uninstall and install {venv.name!r}, or reinstall-all to fix. """) # package_spec is anything pip-installable, including package_name, vcs spec, # zip file, or tar.gz file. if package_name is None: package_name = package_name_from_spec(package_spec, venv.python, pip_args=pip_args, verbose=verbose) venv.install_package( package=package_name, package_or_url=package_spec, pip_args=pip_args, include_dependencies=include_dependencies, include_apps=include_apps, is_main_package=False, ) if include_apps: run_post_install_actions( venv, package_name, constants.LOCAL_BIN_DIR, venv_dir, include_dependencies, force=force, ) print( f" injected package {bold(package_name)} into venv {bold(venv.name)}") print(f"done! {stars}", file=sys.stderr) # Any failure to install will raise PipxError, otherwise success return True
def inject( venv_dir: Path, package_name: Optional[str], package_spec: str, pip_args: List[str], *, verbose: bool, include_apps: bool, include_dependencies: bool, force: bool, ): if not venv_dir.exists() or not next(venv_dir.iterdir()): raise PipxError( textwrap.dedent(f"""\ Can't inject {package_spec!r} into nonexistent Virtual Environment {str(venv_dir)!r}. Be sure to install the package first with pipx install {venv_dir.name!r} before injecting into it.""")) venv = Venv(venv_dir, verbose=verbose) # package_spec is anything pip-installable, including package_name, vcs spec, # zip file, or tar.gz file. if package_name is None: package_name = package_name_from_spec(package_spec, venv.python, pip_args=pip_args, verbose=verbose) venv.install_package( package=package_name, package_or_url=package_spec, pip_args=pip_args, include_dependencies=include_dependencies, include_apps=include_apps, is_main_package=False, ) if include_apps: run_post_install_actions( venv, package_name, constants.LOCAL_BIN_DIR, venv_dir, include_dependencies, force=force, ) print( f" injected package {bold(package_name)} into venv {bold(venv_dir.name)}" ) print(f"done! {stars}", file=sys.stderr)
def _download_and_run( venv_dir: Path, package_or_url: str, app: str, app_filename: str, app_args: List[str], python: str, pip_args: List[str], venv_args: List[str], use_cache: bool, verbose: bool, ) -> NoReturn: venv = Venv(venv_dir, python=python, verbose=verbose) venv.create_venv(venv_args, pip_args) if venv.pipx_metadata.main_package.package is not None: package_name = venv.pipx_metadata.main_package.package else: package_name = package_name_from_spec(package_or_url, python, pip_args=pip_args, verbose=verbose) venv.install_package( package_name=package_name, package_or_url=package_or_url, pip_args=pip_args, include_dependencies=False, include_apps=True, is_main_package=True, ) if not venv.has_app(app, app_filename): apps = venv.pipx_metadata.main_package.apps raise PipxError(f""" '{app}' executable script not found in package '{package_or_url}'. Available executable scripts: {', '.join(b for b in apps)} """) if not use_cache: # Let future _remove_all_expired_venvs know to remove this (venv_dir / VENV_EXPIRED_FILENAME).touch() venv.run_app(app, app_filename, app_args)
def _download_and_run( venv_dir: Path, package_or_url: str, app: str, app_args: List[str], python: str, pip_args: List[str], venv_args: List[str], verbose: bool, ): venv = Venv(venv_dir, python=python, verbose=verbose) venv.create_venv(venv_args, pip_args) if venv.pipx_metadata.main_package.package is not None: package = venv.pipx_metadata.main_package.package else: package = package_name_from_spec(package_or_url, python, pip_args=pip_args, verbose=verbose) venv.install_package( package=package, package_or_url=package_or_url, pip_args=pip_args, include_dependencies=False, include_apps=True, is_main_package=True, ) if not (venv.bin_path / app).exists(): apps = venv.pipx_metadata.main_package.apps raise PipxError( f"'{app}' executable script not found in package '{package_or_url}'. " "Available executable scripts: " f"{', '.join(b for b in apps)}") return venv.run_app(app, app_args)
def install( venv_dir: Optional[Path], package_name: Optional[str], package_spec: str, local_bin_dir: Path, python: str, pip_args: List[str], venv_args: List[str], verbose: bool, *, force: bool, include_dependencies: bool, suffix: str = "", ): # package_spec is anything pip-installable, including package_name, vcs spec, # zip file, or tar.gz file. if package_name is None: package_name = package_name_from_spec(package_spec, python, pip_args=pip_args, verbose=verbose) if venv_dir is None: venv_container = VenvContainer(constants.PIPX_LOCAL_VENVS) venv_dir = venv_container.get_venv_dir(package_name) if suffix != "": venv_dir = venv_dir.parent / f"{venv_dir.stem}{suffix}" try: exists = venv_dir.exists() and next(venv_dir.iterdir()) except StopIteration: exists = False if exists: if force: print(f"Installing to existing directory {str(venv_dir)!r}") else: print(f"{venv_dir.name!r} already seems to be installed. " f"Not modifying existing installation in {str(venv_dir)!r}. " "Pass '--force' to force installation.") return venv = Venv(venv_dir, python=python, verbose=verbose) try: venv.create_venv(venv_args, pip_args) venv.install_package( package=package_name, package_or_url=package_spec, pip_args=pip_args, include_dependencies=include_dependencies, include_apps=True, is_main_package=True, suffix=suffix, ) run_post_install_actions( venv, package_name, local_bin_dir, venv_dir, include_dependencies, force=force, ) except (Exception, KeyboardInterrupt): print("") venv.remove_venv() raise
def install( venv_dir: Optional[Path], package_name: Optional[str], package_spec: str, local_bin_dir: Path, python: str, pip_args: List[str], venv_args: List[str], verbose: bool, *, force: bool, include_dependencies: bool, suffix: str = "", ) -> ExitCode: """Returns pipx exit code.""" # package_spec is anything pip-installable, including package_name, vcs spec, # zip file, or tar.gz file. if package_name is None: package_name = package_name_from_spec(package_spec, python, pip_args=pip_args, verbose=verbose) if venv_dir is None: venv_container = VenvContainer(constants.PIPX_LOCAL_VENVS) venv_dir = venv_container.get_venv_dir(f"{package_name}{suffix}") try: exists = venv_dir.exists() and bool(next(venv_dir.iterdir())) except StopIteration: exists = False venv = Venv(venv_dir, python=python, verbose=verbose) if exists: if force: print(f"Installing to existing venv {venv.name!r}") else: print( pipx_wrap(f""" {venv.name!r} already seems to be installed. Not modifying existing installation in {str(venv_dir)!r}. Pass '--force' to force installation. """)) return EXIT_CODE_INSTALL_VENV_EXISTS try: venv.create_venv(venv_args, pip_args) venv.install_package( package_name=package_name, package_or_url=package_spec, pip_args=pip_args, include_dependencies=include_dependencies, include_apps=True, is_main_package=True, suffix=suffix, ) run_post_install_actions( venv, package_name, local_bin_dir, venv_dir, include_dependencies, force=force, ) except (Exception, KeyboardInterrupt): print() venv.remove_venv() raise # Any failure to install will raise PipxError, otherwise success return EXIT_CODE_OK
def _download_and_run( venv_dir: Path, package_or_url: str, app: str, app_filename: str, app_args: List[str], python: str, pip_args: List[str], venv_args: List[str], use_cache: bool, verbose: bool, ) -> NoReturn: venv = Venv(venv_dir, python=python, verbose=verbose) venv.create_venv(venv_args, pip_args) if venv.pipx_metadata.main_package.package is not None: package_name = venv.pipx_metadata.main_package.package else: package_name = package_name_from_spec(package_or_url, python, pip_args=pip_args, verbose=verbose) venv.install_package( package_name=package_name, package_or_url=package_or_url, pip_args=pip_args, include_dependencies=False, include_apps=True, is_main_package=True, ) if not venv.has_app(app, app_filename): apps = venv.pipx_metadata.main_package.apps # If there's a single app inside the package, run that by default if app == package_name and len(apps) == 1: app = apps[0] print(f"NOTE: running app {app!r} from {package_name!r}") if WINDOWS: app_filename = f"{app}.exe" logger.info(f"Assuming app is {app_filename!r} (Windows only)") else: app_filename = app else: all_apps = ( f"{a} - usage: 'pipx run --spec {package_name} {a} [arguments?]'" for a in apps) raise PipxError( APP_NOT_FOUND_ERROR_MESSAGE.format( app=app, package_name=package_name, app_lines="\n ".join(all_apps), ), wrap_message=False, ) if not use_cache: # Let future _remove_all_expired_venvs know to remove this (venv_dir / VENV_EXPIRED_FILENAME).touch() venv.run_app(app, app_filename, app_args)