def _download_and_run( venv_dir: Path, package: str, app: str, binary_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) venv.install_package(package, pip_args) if not (venv.bin_path / app).exists(): apps = venv.get_venv_metadata_for_package(package).apps raise PipxError( f"'{app}' executable script not found in package '{package}'. " "Available executable scripts: " f"{', '.join(b for b in apps)}") return venv.run_app(app, binary_args)
def run( app: str, package_or_url: str, binary_args: List[str], python: str, pip_args: List[str], venv_args: List[str], pypackages: bool, verbose: bool, use_cache: bool, ): """Installs venv to temporary dir (or reuses cache), then runs app from package """ if urllib.parse.urlparse(app).scheme: if not app.endswith(".py"): exit( "pipx will only execute apps from the internet directly if " "they end with '.py'. To run from an SVN, try pipx --spec URL BINARY" ) logging.info( "Detected url. Downloading and executing as a Python file.") content = _http_get_request(app) try: exit(subprocess.run([str(python), "-c", content]).returncode) except KeyboardInterrupt: pass exit(0) elif which(app): logging.warning( f"{hazard} {app} is already on your PATH and installed at " f"{which(app)}. Downloading and " "running anyway.") if WINDOWS and not app.endswith(".exe"): app = f"{app}.exe" logging.warning(f"Assuming app is {app!r} (Windows only)") pypackage_bin_path = get_pypackage_bin_path(app) if pypackage_bin_path.exists(): logging.info( f"Using app in local __pypackages__ directory at {str(pypackage_bin_path)}" ) return run_pypackage_bin(pypackage_bin_path, binary_args) if pypackages: raise PipxError( f"'--pypackages' flag was passed, but {str(pypackage_bin_path)!r} was " "not found. See https://github.com/cs01/pythonloc to learn how to " "install here, or omit the flag.") venv_dir = _get_temporary_venv_path(package_or_url, python, pip_args, venv_args) venv = Venv(venv_dir) bin_path = venv.bin_path / app _prepare_venv_cache(venv, bin_path, use_cache) if bin_path.exists(): logging.info(f"Reusing cached venv {venv_dir}") retval = venv.run_app(app, binary_args) else: logging.info(f"venv location is {venv_dir}") retval = _download_and_run( Path(venv_dir), package_or_url, app, binary_args, python, pip_args, venv_args, verbose, ) if not use_cache: rmdir(venv_dir) return retval