Reinstate bun path (#1552)
This commit is contained in:
parent
2eefb5d26c
commit
ed4de0d7ba
@ -168,6 +168,9 @@ class Config(Base):
|
||||
# Additional frontend packages to install.
|
||||
frontend_packages: List[str] = []
|
||||
|
||||
# The bun path
|
||||
bun_path: str = constants.BUN_PATH
|
||||
|
||||
# The Admin Dash.
|
||||
admin_dash: Optional[AdminDash] = None
|
||||
|
||||
|
@ -65,10 +65,14 @@ JINJA_TEMPLATE_DIR = os.path.join(TEMPLATE_DIR, "jinja")
|
||||
# Bun config.
|
||||
# The Bun version.
|
||||
BUN_VERSION = "0.7.0"
|
||||
# Min Bun Version
|
||||
MIN_BUN_VERSION = "0.7.0"
|
||||
# The directory to store the bun.
|
||||
BUN_ROOT_PATH = os.path.join(REFLEX_DIR, ".bun")
|
||||
# Default bun path.
|
||||
DEFAULT_BUN_PATH = os.path.join(BUN_ROOT_PATH, "bin", "bun")
|
||||
# The bun path.
|
||||
BUN_PATH = os.path.join(BUN_ROOT_PATH, "bin", "bun")
|
||||
BUN_PATH = get_value("BUN_PATH", DEFAULT_BUN_PATH)
|
||||
# URL to bun install script.
|
||||
BUN_INSTALL_URL = "https://bun.sh/install"
|
||||
|
||||
|
@ -57,7 +57,7 @@ def get_bun_version() -> Optional[version.Version]:
|
||||
"""
|
||||
try:
|
||||
# Run the bun -v command and capture the output
|
||||
result = processes.new_process([constants.BUN_PATH, "-v"], run=True)
|
||||
result = processes.new_process([get_config().bun_path, "-v"], run=True)
|
||||
return version.parse(result.stdout) # type: ignore
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
@ -92,7 +92,7 @@ def get_install_package_manager() -> str:
|
||||
return get_windows_package_manager()
|
||||
|
||||
# On other platforms, we use bun.
|
||||
return constants.BUN_PATH
|
||||
return get_config().bun_path
|
||||
|
||||
|
||||
def get_package_manager() -> str:
|
||||
@ -245,36 +245,13 @@ def initialize_web_directory():
|
||||
json.dump(reflex_json, f, ensure_ascii=False)
|
||||
|
||||
|
||||
def initialize_bun():
|
||||
"""Check that bun requirements are met, and install if not."""
|
||||
if IS_WINDOWS:
|
||||
# Bun is not supported on Windows.
|
||||
console.debug("Skipping bun installation on Windows.")
|
||||
return
|
||||
|
||||
# Check the bun version.
|
||||
bun_version = get_bun_version()
|
||||
if bun_version != version.parse(constants.BUN_VERSION):
|
||||
console.debug(
|
||||
f"Current bun version ({bun_version}) does not match ({constants.BUN_VERSION})."
|
||||
)
|
||||
remove_existing_bun_installation()
|
||||
install_bun()
|
||||
|
||||
|
||||
def remove_existing_bun_installation():
|
||||
"""Remove existing bun installation."""
|
||||
console.debug("Removing existing bun installation.")
|
||||
if os.path.exists(constants.BUN_PATH):
|
||||
if os.path.exists(get_config().bun_path):
|
||||
path_ops.rm(constants.BUN_ROOT_PATH)
|
||||
|
||||
|
||||
def initialize_node():
|
||||
"""Validate nodejs have install or not."""
|
||||
if not check_node_version():
|
||||
install_node()
|
||||
|
||||
|
||||
def download_and_run(url: str, *args, show_status: bool = False, **env):
|
||||
"""Download and run a script.
|
||||
|
||||
@ -352,7 +329,7 @@ def install_bun():
|
||||
return
|
||||
|
||||
# Skip if bun is already installed.
|
||||
if os.path.exists(constants.BUN_PATH):
|
||||
if os.path.exists(get_config().bun_path):
|
||||
console.debug("Skipping bun installation as it is already installed.")
|
||||
return
|
||||
|
||||
@ -435,12 +412,46 @@ def is_latest_template() -> bool:
|
||||
return app_version == constants.VERSION
|
||||
|
||||
|
||||
def validate_bun():
|
||||
"""Validate bun if a custom bun path is specified to ensure the bun version meets requirements.
|
||||
|
||||
Raises:
|
||||
Exit: If custom specified bun does not exist or does not meet requirements.
|
||||
"""
|
||||
# if a custom bun path is provided, make sure its valid
|
||||
# This is specific to non-FHS OS
|
||||
bun_path = get_config().bun_path
|
||||
if bun_path != constants.DEFAULT_BUN_PATH:
|
||||
bun_version = get_bun_version()
|
||||
if not bun_version:
|
||||
console.error(
|
||||
"Failed to obtain bun version. Make sure the specified bun path in your config is correct."
|
||||
)
|
||||
raise typer.Exit(1)
|
||||
elif bun_version < version.parse(constants.MIN_BUN_VERSION):
|
||||
console.error(
|
||||
f"Reflex requires bun version {constants.BUN_VERSION} or higher to run, but the detected version is "
|
||||
f"{bun_version}. If you have specified a custom bun path in your config, make sure to provide one "
|
||||
f"that satisfies the minimum version requirement."
|
||||
)
|
||||
|
||||
raise typer.Exit(1)
|
||||
|
||||
|
||||
def validate_frontend_dependencies():
|
||||
"""Validate frontend dependencies to ensure they meet requirements."""
|
||||
if IS_WINDOWS:
|
||||
return
|
||||
return validate_bun()
|
||||
|
||||
|
||||
def initialize_frontend_dependencies():
|
||||
"""Initialize all the frontend dependencies."""
|
||||
# Create the reflex directory.
|
||||
if not IS_WINDOWS:
|
||||
path_ops.mkdir(constants.REFLEX_DIR)
|
||||
|
||||
# validate dependencies before install
|
||||
validate_frontend_dependencies()
|
||||
# Install the frontend dependencies.
|
||||
processes.run_concurrently(install_node, install_bun)
|
||||
|
||||
|
@ -255,36 +255,38 @@ def test_format_route(route: str, expected: bool):
|
||||
assert format.format_route(route) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"bun_version,is_valid, prompt_input",
|
||||
[
|
||||
(V055, False, "yes"),
|
||||
(V059, True, None),
|
||||
(VMAXPLUS1, False, "yes"),
|
||||
],
|
||||
)
|
||||
def test_initialize_bun(mocker, bun_version, is_valid, prompt_input):
|
||||
"""Test that the bun version on host system is validated properly. Also test that
|
||||
the required bun version is installed should the user opt for it.
|
||||
def test_validate_invalid_bun_path(mocker):
|
||||
"""Test that an error is thrown when a custom specified bun path is not valid
|
||||
or does not exist.
|
||||
|
||||
Args:
|
||||
mocker: Pytest mocker object.
|
||||
bun_version: The bun version.
|
||||
is_valid: Whether bun version is valid for running reflex.
|
||||
prompt_input: The input from user on whether to install bun.
|
||||
"""
|
||||
mocker.patch("reflex.utils.prerequisites.get_bun_version", return_value=bun_version)
|
||||
mocker.patch("reflex.utils.prerequisites.IS_WINDOWS", False)
|
||||
mock = mocker.Mock()
|
||||
mocker.patch.object(mock, "bun_path", return_value="/mock/path")
|
||||
mocker.patch("reflex.utils.prerequisites.get_config", mock)
|
||||
mocker.patch("reflex.utils.prerequisites.get_bun_version", return_value=None)
|
||||
|
||||
bun_install = mocker.patch("reflex.utils.prerequisites.install_bun")
|
||||
remove_existing_bun_installation = mocker.patch(
|
||||
"reflex.utils.prerequisites.remove_existing_bun_installation"
|
||||
with pytest.raises(typer.Exit):
|
||||
prerequisites.validate_bun()
|
||||
|
||||
|
||||
def test_validate_bun_path_incompatible_version(mocker):
|
||||
"""Test that an error is thrown when the bun version does not meet minimum requirements.
|
||||
|
||||
Args:
|
||||
mocker: Pytest mocker object.
|
||||
"""
|
||||
mock = mocker.Mock()
|
||||
mocker.patch.object(mock, "bun_path", return_value="/mock/path")
|
||||
mocker.patch("reflex.utils.prerequisites.get_config", mock)
|
||||
mocker.patch(
|
||||
"reflex.utils.prerequisites.get_bun_version",
|
||||
return_value=version.parse("0.6.5"),
|
||||
)
|
||||
|
||||
prerequisites.initialize_bun()
|
||||
if not is_valid:
|
||||
remove_existing_bun_installation.assert_called_once()
|
||||
bun_install.assert_called_once()
|
||||
with pytest.raises(typer.Exit):
|
||||
prerequisites.validate_bun()
|
||||
|
||||
|
||||
def test_remove_existing_bun_installation(mocker):
|
||||
@ -521,7 +523,7 @@ def test_node_install_windows(mocker):
|
||||
mocker.patch("reflex.utils.prerequisites.check_node_version", return_value=False)
|
||||
|
||||
with pytest.raises(typer.Exit):
|
||||
prerequisites.initialize_node()
|
||||
prerequisites.install_node()
|
||||
|
||||
|
||||
def test_node_install_unix(tmp_path, mocker):
|
||||
|
Loading…
Reference in New Issue
Block a user