Reinstate bun path (#1552)

This commit is contained in:
Elijah Ahianyo 2023-08-16 00:39:43 +00:00 committed by GitHub
parent 2eefb5d26c
commit ed4de0d7ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 53 deletions

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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):