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.
|
# Additional frontend packages to install.
|
||||||
frontend_packages: List[str] = []
|
frontend_packages: List[str] = []
|
||||||
|
|
||||||
|
# The bun path
|
||||||
|
bun_path: str = constants.BUN_PATH
|
||||||
|
|
||||||
# The Admin Dash.
|
# The Admin Dash.
|
||||||
admin_dash: Optional[AdminDash] = None
|
admin_dash: Optional[AdminDash] = None
|
||||||
|
|
||||||
|
@ -65,10 +65,14 @@ JINJA_TEMPLATE_DIR = os.path.join(TEMPLATE_DIR, "jinja")
|
|||||||
# Bun config.
|
# Bun config.
|
||||||
# The Bun version.
|
# The Bun version.
|
||||||
BUN_VERSION = "0.7.0"
|
BUN_VERSION = "0.7.0"
|
||||||
|
# Min Bun Version
|
||||||
|
MIN_BUN_VERSION = "0.7.0"
|
||||||
# The directory to store the bun.
|
# The directory to store the bun.
|
||||||
BUN_ROOT_PATH = os.path.join(REFLEX_DIR, ".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.
|
# 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.
|
# URL to bun install script.
|
||||||
BUN_INSTALL_URL = "https://bun.sh/install"
|
BUN_INSTALL_URL = "https://bun.sh/install"
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ def get_bun_version() -> Optional[version.Version]:
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Run the bun -v command and capture the output
|
# 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
|
return version.parse(result.stdout) # type: ignore
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return None
|
return None
|
||||||
@ -92,7 +92,7 @@ def get_install_package_manager() -> str:
|
|||||||
return get_windows_package_manager()
|
return get_windows_package_manager()
|
||||||
|
|
||||||
# On other platforms, we use bun.
|
# On other platforms, we use bun.
|
||||||
return constants.BUN_PATH
|
return get_config().bun_path
|
||||||
|
|
||||||
|
|
||||||
def get_package_manager() -> str:
|
def get_package_manager() -> str:
|
||||||
@ -245,36 +245,13 @@ def initialize_web_directory():
|
|||||||
json.dump(reflex_json, f, ensure_ascii=False)
|
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():
|
def remove_existing_bun_installation():
|
||||||
"""Remove existing bun installation."""
|
"""Remove existing bun installation."""
|
||||||
console.debug("Removing 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)
|
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):
|
def download_and_run(url: str, *args, show_status: bool = False, **env):
|
||||||
"""Download and run a script.
|
"""Download and run a script.
|
||||||
|
|
||||||
@ -352,7 +329,7 @@ def install_bun():
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Skip if bun is already installed.
|
# 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.")
|
console.debug("Skipping bun installation as it is already installed.")
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -435,12 +412,46 @@ def is_latest_template() -> bool:
|
|||||||
return app_version == constants.VERSION
|
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():
|
def initialize_frontend_dependencies():
|
||||||
"""Initialize all the frontend dependencies."""
|
"""Initialize all the frontend dependencies."""
|
||||||
# Create the reflex directory.
|
# Create the reflex directory.
|
||||||
if not IS_WINDOWS:
|
if not IS_WINDOWS:
|
||||||
path_ops.mkdir(constants.REFLEX_DIR)
|
path_ops.mkdir(constants.REFLEX_DIR)
|
||||||
|
# validate dependencies before install
|
||||||
|
validate_frontend_dependencies()
|
||||||
# Install the frontend dependencies.
|
# Install the frontend dependencies.
|
||||||
processes.run_concurrently(install_node, install_bun)
|
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
|
assert format.format_route(route) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
def test_validate_invalid_bun_path(mocker):
|
||||||
"bun_version,is_valid, prompt_input",
|
"""Test that an error is thrown when a custom specified bun path is not valid
|
||||||
[
|
or does not exist.
|
||||||
(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.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
mocker: Pytest mocker object.
|
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)
|
mock = mocker.Mock()
|
||||||
mocker.patch("reflex.utils.prerequisites.IS_WINDOWS", False)
|
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")
|
with pytest.raises(typer.Exit):
|
||||||
remove_existing_bun_installation = mocker.patch(
|
prerequisites.validate_bun()
|
||||||
"reflex.utils.prerequisites.remove_existing_bun_installation"
|
|
||||||
|
|
||||||
|
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()
|
with pytest.raises(typer.Exit):
|
||||||
if not is_valid:
|
prerequisites.validate_bun()
|
||||||
remove_existing_bun_installation.assert_called_once()
|
|
||||||
bun_install.assert_called_once()
|
|
||||||
|
|
||||||
|
|
||||||
def test_remove_existing_bun_installation(mocker):
|
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)
|
mocker.patch("reflex.utils.prerequisites.check_node_version", return_value=False)
|
||||||
|
|
||||||
with pytest.raises(typer.Exit):
|
with pytest.raises(typer.Exit):
|
||||||
prerequisites.initialize_node()
|
prerequisites.install_node()
|
||||||
|
|
||||||
|
|
||||||
def test_node_install_unix(tmp_path, mocker):
|
def test_node_install_unix(tmp_path, mocker):
|
||||||
|
Loading…
Reference in New Issue
Block a user