def _symlink_package_apps(local_bin_dir: Path, app_paths: List[Path], package: str, *, force: bool): for app_path in app_paths: app_name = app_path.name symlink_path = Path(local_bin_dir / app_name) if not symlink_path.parent.is_dir(): mkdir(symlink_path.parent) if force: logging.info(f"Force is true. Removing {str(symlink_path)}.") try: symlink_path.unlink() except FileNotFoundError: pass except IsADirectoryError: rmdir(symlink_path) if symlink_path.exists(): if symlink_path.samefile(app_path): logging.info( f"Same path {str(symlink_path)} and {str(app_path)}") else: logging.warning( f"{hazard} File exists at {str(symlink_path)} and points " f"to {symlink_path.resolve()}, not {str(app_path)}. Not modifying." ) continue existing_executable_on_path = which(app_name) symlink_path.symlink_to(app_path) if existing_executable_on_path: logging.warning( f"{hazard} Note: {app_name} was already on your PATH at " f"{existing_executable_on_path}")
def _symlink_package_apps( local_bin_dir: Path, app_paths: List[Path], *, force: bool, suffix: str = "" ) -> None: for app_path in app_paths: app_name = app_path.name app_name_suffixed = add_suffix(app_name, suffix) symlink_path = Path(local_bin_dir / app_name_suffixed) if not symlink_path.parent.is_dir(): mkdir(symlink_path.parent) if force: logger.info(f"Force is true. Removing {str(symlink_path)}.") try: symlink_path.unlink() except FileNotFoundError: pass except IsADirectoryError: rmdir(symlink_path) exists = symlink_path.exists() is_symlink = symlink_path.is_symlink() if exists: if symlink_path.samefile(app_path): logger.info(f"Same path {str(symlink_path)} and {str(app_path)}") else: logger.warning( pipx_wrap( f""" {hazard} File exists at {str(symlink_path)} and points to {symlink_path.resolve()}, not {str(app_path)}. Not modifying. """, subsequent_indent=" " * 4, ) ) continue if is_symlink and not exists: logger.info( f"Removing existing symlink {str(symlink_path)} since it " "pointed non-existent location" ) symlink_path.unlink() existing_executable_on_path = which(app_name_suffixed) symlink_path.symlink_to(app_path) if existing_executable_on_path: logger.warning( pipx_wrap( f""" {hazard} Note: {app_name_suffixed} was already on your PATH at {existing_executable_on_path} """, subsequent_indent=" " * 4, ) )
def _copy_package_apps(local_bin_dir: Path, app_paths: List[Path], package: str): for src_unresolved in app_paths: src = src_unresolved.resolve() app = src.name dest = Path(local_bin_dir / app) if not dest.parent.is_dir(): mkdir(dest.parent) if dest.exists(): logging.warning(f"{hazard} Overwriting file {str(dest)} with {str(src)}") dest.unlink() if src.exists(): shutil.copy(src, dest)
def _copy_package_apps( local_bin_dir: Path, app_paths: List[Path], suffix: str = "" ) -> None: for src_unresolved in app_paths: src = src_unresolved.resolve() app = src.name dest = Path(local_bin_dir / add_suffix(app, suffix)) if not dest.parent.is_dir(): mkdir(dest.parent) if dest.exists(): logger.warning(f"{hazard} Overwriting file {str(dest)} with {str(src)}") safe_unlink(dest) if src.exists(): shutil.copy(src, dest)
def setup(args: argparse.Namespace) -> None: if "version" in args and args.version: print_version() sys.exit(0) setup_logging("verbose" in args and args.verbose) logger.debug(f"{time.strftime('%Y-%m-%d %H:%M:%S')}") logger.debug(f"{' '.join(sys.argv)}") logger.info(f"pipx version is {__version__}") logger.info(f"Default python interpreter is {repr(DEFAULT_PYTHON)}") mkdir(constants.PIPX_LOCAL_VENVS) mkdir(constants.LOCAL_BIN_DIR) mkdir(constants.PIPX_VENV_CACHEDIR) old_pipx_venv_location = constants.PIPX_LOCAL_VENVS / "pipx-app" if old_pipx_venv_location.exists(): logger.warning( pipx_wrap( f""" {hazard} A virtual environment for pipx was detected at {str(old_pipx_venv_location)}. The 'pipx-app' package has been renamed back to 'pipx' (https://github.com/pipxproject/pipx/issues/82). """, subsequent_indent=" " * 4, ))
def setup(args: argparse.Namespace) -> None: if "version" in args and args.version: print_version() sys.exit(0) # Setup logging so debug and above go to log file, # info (verbose) or warning (non-verbose) and above go to console root_logger = logging.getLogger() root_logger.setLevel(logging.DEBUG) file_handler = setup_file_handler() stream_handler = setup_stream_handler("verbose" in args and args.verbose) root_logger.addHandler(file_handler) root_logger.addHandler(stream_handler) logging.debug(f"{time.strftime('%Y-%m-%d %H:%M:%S')}") logging.debug(f"{' '.join(sys.argv)}") logging.info(f"pipx version is {__version__}") logging.info(f"Default python interpreter is {repr(DEFAULT_PYTHON)}") mkdir(constants.PIPX_LOCAL_VENVS) mkdir(constants.LOCAL_BIN_DIR) mkdir(constants.PIPX_VENV_CACHEDIR) old_pipx_venv_location = constants.PIPX_LOCAL_VENVS / "pipx-app" if old_pipx_venv_location.exists(): logging.warning( "A virtual environment for pipx was detected at " f"{str(old_pipx_venv_location)}. The 'pipx-app' package has been renamed " "back to 'pipx' (https://github.com/pipxproject/pipx/issues/82).")