コード例 #1
0
ファイル: common.py プロジェクト: abn/pipx
def package_name_from_spec(package_spec: str, python: str, *,
                           pip_args: List[str], verbose: bool) -> str:
    start_time = time.time()

    # shortcut if valid PyPI name
    pypi_name = valid_pypi_name(package_spec)
    if pypi_name is not None:
        # NOTE: if pypi name and installed package name differ, this means pipx
        #       will use the pypi name
        package_name = pypi_name
        logging.info(f"Determined package name: {package_name}")
        logging.info(
            f"Package name determined in {time.time()-start_time:.1f}s")
        return package_name

    # check syntax and clean up spec and pip_args
    (package_spec,
     pip_args) = parse_specifier_for_install(package_spec, pip_args)

    with tempfile.TemporaryDirectory() as temp_venv_dir:
        venv = Venv(Path(temp_venv_dir), python=python, verbose=verbose)
        venv.create_venv(venv_args=[], pip_args=[])
        package_name = venv.install_package_no_deps(
            package_or_url=package_spec, pip_args=pip_args)

    logging.info(f"Package name determined in {time.time()-start_time:.1f}s")
    return package_name
コード例 #2
0
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)

    # venv.pipx_metadata.main_package.package contains package name if it is
    #   pre-existing, otherwise is None to instruct venv.install_package to
    #   determine package name.

    venv.install_package(
        package=venv.pipx_metadata.main_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)
コード例 #3
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)
        try:
            venv.install_package(
                package=package,
                package_or_url=package_or_url,
                pip_args=pip_args,
                include_dependencies=include_dependencies,
                include_apps=True,
                is_main_package=True,
            )
        except PackageInstallFailureError:
            venv.remove_venv()
            raise PipxError(
                f"Could not install package {package}. Is the name or spec correct?"
            )

        _run_post_install_actions(venv,
                                  package,
                                  local_bin_dir,
                                  venv_dir,
                                  include_dependencies,
                                  force=force)
    except (Exception, KeyboardInterrupt):
        print("")
        venv.remove_venv()
        raise
コード例 #4
0
ファイル: run.py プロジェクト: stjordanis/pipx
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)
コード例 #5
0
ファイル: common.py プロジェクト: chaitanyakrishna/pipx
def package_name_from_spec(package_spec: str, python: str, *,
                           pip_args: List[str], verbose: bool) -> str:
    start_time = time.time()

    # shortcut if valid PyPI name and not a local path
    if valid_pypi_name(package_spec) and not Path(package_spec).exists():
        package_name = package_spec
        logging.info(f"Determined package name: {package_name}")
        logging.info(
            f"Package name determined in {time.time()-start_time:.1f}s")
        return package_name

    with tempfile.TemporaryDirectory() as temp_venv_dir:
        venv = Venv(Path(temp_venv_dir), python=python, verbose=verbose)
        venv.create_venv(venv_args=[], pip_args=[])
        package_name = venv.install_package_no_deps(
            package_or_url=package_spec, pip_args=pip_args)

    logging.info(f"Package name determined in {time.time()-start_time:.1f}s")
    return package_name
コード例 #6
0
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)
コード例 #7
0
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)
コード例 #8
0
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
コード例 #9
0
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
コード例 #10
0
ファイル: run.py プロジェクト: pypa/pipx
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)