diff --git a/.github/workflows/check_node_latest.yml b/.github/workflows/check_node_latest.yml index 945786c05..749b94efa 100644 --- a/.github/workflows/check_node_latest.yml +++ b/.github/workflows/check_node_latest.yml @@ -10,6 +10,7 @@ on: env: TELEMETRY_ENABLED: false + REFLEX_USE_SYSTEM_NODE: true jobs: check_latest_node: @@ -32,7 +33,7 @@ jobs: poetry run uv pip install pyvirtualdisplay pillow poetry run playwright install --with-deps - run: | - # poetry run pytest tests/test_node_version.py + poetry run pytest tests/test_node_version.py poetry run pytest tests/integration diff --git a/reflex/constants/installer.py b/reflex/constants/installer.py index e01e5ae69..01a11a37e 100644 --- a/reflex/constants/installer.py +++ b/reflex/constants/installer.py @@ -54,6 +54,9 @@ class Bun(SimpleNamespace): # Path of the bunfig file CONFIG_PATH = "bunfig.toml" + # The environment variable to use the system installed bun. + USE_SYSTEM_VAR = "REFLEX_USE_SYSTEM_BUN" + # FNM config. class Fnm(SimpleNamespace): @@ -96,6 +99,9 @@ class Node(SimpleNamespace): # The default path where npm is installed. NPM_PATH = os.path.join(BIN_PATH, "npm") + # The environment variable to use the system installed node. + USE_SYSTEM_VAR = "REFLEX_USE_SYSTEM_NODE" + class PackageJson(SimpleNamespace): """Constants used to build the package.json file.""" diff --git a/reflex/utils/path_ops.py b/reflex/utils/path_ops.py index 21065db99..00affd820 100644 --- a/reflex/utils/path_ops.py +++ b/reflex/utils/path_ops.py @@ -129,6 +129,41 @@ def which(program: str | Path) -> str | Path | None: return shutil.which(str(program)) +def use_system_install(var_name: str) -> bool: + """Check if the system install should be used. + + Args: + var_name: The name of the environment variable. + + Raises: + ValueError: If the variable name is invalid. + + Returns: + Whether the associated env var should use the system install. + """ + if not var_name.startswith("REFLEX_USE_SYSTEM_"): + raise ValueError("Invalid system install variable name.") + return os.getenv(var_name, "").lower() in ["true", "1", "yes"] + + +def use_system_node() -> bool: + """Check if the system node should be used. + + Returns: + Whether the system node should be used. + """ + return use_system_install(constants.Node.USE_SYSTEM_VAR) + + +def use_system_bun() -> bool: + """Check if the system bun should be used. + + Returns: + Whether the system bun should be used. + """ + return use_system_install(constants.Bun.USE_SYSTEM_VAR) + + def get_node_bin_path() -> str | None: """Get the node binary dir path. @@ -149,7 +184,7 @@ def get_node_path() -> str | None: The path to the node binary file. """ node_path = Path(constants.Node.PATH) - if not node_path.exists(): + if use_system_node() or not node_path.exists(): return str(which("node")) return str(node_path) diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index f86da0c53..f9eb9a790 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -143,7 +143,7 @@ def check_node_version() -> bool: # Compare the version numbers return ( current_version >= version.parse(constants.Node.MIN_VERSION) - if constants.IS_WINDOWS + if constants.IS_WINDOWS or path_ops.use_system_node() else current_version == version.parse(constants.Node.VERSION) ) return False @@ -1034,6 +1034,8 @@ def validate_bun(): # 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 path_ops.use_system_bun(): + bun_path = path_ops.which("bun") if bun_path != constants.Bun.DEFAULT_PATH: console.info(f"Using custom Bun path: {bun_path}") bun_version = get_bun_version()