raise error when get package manager is not found (#4289)

* raise error when get package manager is not found

* add escape hatch

* handle installing frontend packages more gracefully

* fix no return

* dang it darglint
This commit is contained in:
Khaleel Al-Adhami 2024-11-04 10:31:24 -08:00 committed by GitHub
parent 163acf70a2
commit 6394a6dfc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 15 deletions

View File

@ -467,9 +467,11 @@ def output_system_info():
console.debug(f"{dep}") console.debug(f"{dep}")
console.debug( console.debug(
f"Using package installer at: {prerequisites.get_install_package_manager()}" # type: ignore f"Using package installer at: {prerequisites.get_install_package_manager(on_failure_return_none=True)}" # type: ignore
) )
console.debug(f"Using package executer at: {prerequisites.get_package_manager()}") # type: ignore console.debug(
f"Using package executer at: {prerequisites.get_package_manager(on_failure_return_none=True)}"
) # type: ignore
if system != "Windows": if system != "Windows":
console.debug(f"Unzip path: {path_ops.which('unzip')}") console.debug(f"Unzip path: {path_ops.which('unzip')}")

View File

@ -204,10 +204,13 @@ def get_bun_version() -> version.Version | None:
return None return None
def get_install_package_manager() -> str | None: def get_install_package_manager(on_failure_return_none: bool = False) -> str | None:
"""Get the package manager executable for installation. """Get the package manager executable for installation.
Currently, bun is used for installation only. Currently, bun is used for installation only.
Args:
on_failure_return_none: Whether to return None on failure.
Returns: Returns:
The path to the package manager. The path to the package manager.
""" """
@ -217,21 +220,29 @@ def get_install_package_manager() -> str | None:
or windows_check_onedrive_in_path() or windows_check_onedrive_in_path()
or windows_npm_escape_hatch() or windows_npm_escape_hatch()
): ):
return get_package_manager() return get_package_manager(on_failure_return_none)
return str(get_config().bun_path) return str(get_config().bun_path)
def get_package_manager() -> str | None: def get_package_manager(on_failure_return_none: bool = False) -> str | None:
"""Get the package manager executable for running app. """Get the package manager executable for running app.
Currently on unix systems, npm is used for running the app only. Currently on unix systems, npm is used for running the app only.
Args:
on_failure_return_none: Whether to return None on failure.
Returns: Returns:
The path to the package manager. The path to the package manager.
Raises:
FileNotFoundError: If the package manager is not found.
""" """
npm_path = path_ops.get_npm_path() npm_path = path_ops.get_npm_path()
if npm_path is not None: if npm_path is not None:
npm_path = str(Path(npm_path).resolve()) return str(Path(npm_path).resolve())
return npm_path if on_failure_return_none:
return None
raise FileNotFoundError("NPM not found. You may need to run `reflex init`.")
def windows_check_onedrive_in_path() -> bool: def windows_check_onedrive_in_path() -> bool:
@ -920,20 +931,39 @@ def install_frontend_packages(packages: set[str], config: Config):
packages: A list of package names to be installed. packages: A list of package names to be installed.
config: The config object. config: The config object.
Raises:
FileNotFoundError: If the package manager is not found.
Example: Example:
>>> install_frontend_packages(["react", "react-dom"], get_config()) >>> install_frontend_packages(["react", "react-dom"], get_config())
""" """
# unsupported archs(arm and 32bit machines) will use npm anyway. so we dont have to run npm twice # unsupported archs(arm and 32bit machines) will use npm anyway. so we dont have to run npm twice
fallback_command = ( fallback_command = (
get_package_manager() get_package_manager(on_failure_return_none=True)
if not constants.IS_WINDOWS if (
or constants.IS_WINDOWS not constants.IS_WINDOWS
and is_windows_bun_supported() or constants.IS_WINDOWS
and not windows_check_onedrive_in_path() and is_windows_bun_supported()
and not windows_check_onedrive_in_path()
)
else None else None
) )
install_package_manager = (
get_install_package_manager(on_failure_return_none=True) or fallback_command
)
if install_package_manager is None:
raise FileNotFoundError(
"Could not find a package manager to install frontend packages. You may need to run `reflex init`."
)
fallback_command = (
fallback_command if fallback_command is not install_package_manager else None
)
processes.run_process_with_fallback( processes.run_process_with_fallback(
[get_install_package_manager(), "install"], # type: ignore [install_package_manager, "install"], # type: ignore
fallback=fallback_command, fallback=fallback_command,
analytics_enabled=True, analytics_enabled=True,
show_status_message="Installing base frontend packages", show_status_message="Installing base frontend packages",
@ -944,7 +974,7 @@ def install_frontend_packages(packages: set[str], config: Config):
if config.tailwind is not None: if config.tailwind is not None:
processes.run_process_with_fallback( processes.run_process_with_fallback(
[ [
get_install_package_manager(), install_package_manager,
"add", "add",
"-d", "-d",
constants.Tailwind.VERSION, constants.Tailwind.VERSION,
@ -960,7 +990,7 @@ def install_frontend_packages(packages: set[str], config: Config):
# Install custom packages defined in frontend_packages # Install custom packages defined in frontend_packages
if len(packages) > 0: if len(packages) > 0:
processes.run_process_with_fallback( processes.run_process_with_fallback(
[get_install_package_manager(), "add", *packages], [install_package_manager, "add", *packages],
fallback=fallback_command, fallback=fallback_command,
analytics_enabled=True, analytics_enabled=True,
show_status_message="Installing frontend packages from config and components", show_status_message="Installing frontend packages from config and components",