Beispiel #1
0
def install(
    venv_dir: Path,
    package: str,
    package_or_url: str,
    local_bin_dir: Path,
    python: str,
    pip_args: List[str],
    venv_args: List[str],
    verbose: bool,
    *,
    force: bool,
    include_dependencies: bool,
):
    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"{package!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_or_url, pip_args)

        if venv.get_venv_metadata_for_package(package).package_version is None:
            venv.remove_venv()
            raise PipxError(
                f"Could not find package {package}. Is the name correct?")

        _run_post_install_actions(venv,
                                  package,
                                  local_bin_dir,
                                  venv_dir,
                                  include_dependencies,
                                  force=force)
    except (Exception, KeyboardInterrupt):
        print("")
        venv.remove_venv()
        raise
Beispiel #2
0
def _run_post_install_actions(
    venv: Venv,
    package: str,
    local_bin_dir: Path,
    venv_dir: Path,
    include_dependencies: bool,
    *,
    force: bool,
):
    metadata = venv.get_venv_metadata_for_package(package)

    if not metadata.app_paths and not include_dependencies:
        # No apps associated with this package and we aren't including dependencies.
        # This package has nothing for pipx to use, so this is an error.
        for dep, dependent_apps in metadata.app_paths_of_dependencies.items():
            print(
                f"Note: Dependent package '{dep}' contains {len(dependent_apps)} apps"
            )
            for app in dependent_apps:
                print(f"  - {app.name}")

        if venv.safe_to_remove():
            venv.remove_venv()

        if len(metadata.app_paths_of_dependencies.keys()):
            raise PipxError(
                f"No apps associated with package {package}. "
                "Try again with '--include-deps' to include apps of dependent packages, "
                "which are listed above. "
                "If you are attempting to install a library, pipx should not be used. "
                "Consider using pip or a similar tool instead.")
        else:
            raise PipxError(
                f"No apps associated with package {package}."
                "If you are attempting to install a library, pipx should not be used. "
                "Consider using pip or a similar tool instead.")

    if metadata.apps:
        pass
    elif metadata.apps_of_dependencies and include_dependencies:
        pass
    else:
        # No apps associated with this package and we aren't including dependencies.
        # This package has nothing for pipx to use, so this is an error.
        if venv.safe_to_remove():
            venv.remove_venv()
        raise PipxError(
            f"No apps associated with package {package} or its dependencies."
            "If you are attempting to install a library, pipx should not be used. "
            "Consider using pip or a similar tool instead.")

    _expose_apps_globally(local_bin_dir,
                          metadata.app_paths,
                          package,
                          force=force)

    if include_dependencies:
        for _, app_paths in metadata.app_paths_of_dependencies.items():
            _expose_apps_globally(local_bin_dir,
                                  app_paths,
                                  package,
                                  force=force)

    print(_get_package_summary(venv_dir, package=package, new_install=True))
    _warn_if_not_on_path(local_bin_dir)
    print(f"done! {stars}", file=sys.stderr)