From c7ee019d28f5295d1f854f14826437b805e8d313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Fri, 24 Oct 2025 10:23:14 +0200 Subject: [PATCH] try o fix ubuntu build --- npm_install.py | 82 ++++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 56 deletions(-) diff --git a/npm_install.py b/npm_install.py index 86530c2..c28da3d 100644 --- a/npm_install.py +++ b/npm_install.py @@ -582,6 +582,17 @@ def install_node_and_yarn(node_pkg: str): if not Path("/usr/bin/yarn").exists() and Path("/usr/bin/yarnpkg").exists(): os.symlink("/usr/bin/yarnpkg","/usr/bin/yarn") +def _is_ubuntu_wo_distutils() -> bool: + try: + dist = (OSREL.get("ID","") or "").lower() + ver = (OSREL.get("VERSION_ID","") or "").strip() + def _vers(t): + parts = (ver.split(".") + ["0","0"])[:2] + return (int(parts[0]), int(parts[1])) + return dist == "ubuntu" and _vers(ver) >= (24, 4) + except Exception: + return False + def _prepare_sass(frontend_dir: Path): pj = frontend_dir / "package.json" if not pj.exists(): @@ -597,9 +608,10 @@ def _prepare_sass(frontend_dir: Path): dev = data.get("devDependencies", {}) or {} has_node_sass = ("node-sass" in deps) or ("node-sass" in dev) if not has_node_sass: - return + return - use_dart = (os.environ.get("USE_DART_SASS","").strip() == "1") + env_flag = (os.environ.get("USE_DART_SASS","").strip()) + use_dart = (env_flag == "1") or (env_flag == "" and _is_ubuntu_wo_distutils()) data.setdefault("dependencies", {}) data.setdefault("devDependencies", {}) @@ -609,27 +621,32 @@ def _prepare_sass(frontend_dir: Path): data["devDependencies"].pop("node-sass", None) if "sass" not in data["dependencies"] and "sass" not in data["devDependencies"]: data["devDependencies"]["sass"] = "^1.77.0" + scripts = (data.get("scripts") or {}) - new_scripts = {} - for k, v in scripts.items(): - new_scripts[k] = re.sub(r"\bnode-sass\b", "sass", v or "") - data["scripts"] = new_scripts + data["scripts"] = {k: re.sub(r"\bnode-sass\b", "sass", v or "") for k, v in scripts.items()} + + if env_flag == "": + os.environ["USE_DART_SASS"] = "1" else: target = "^9.0.0" if "node-sass" in data["dependencies"]: data["dependencies"]["node-sass"] = target else: data["devDependencies"]["node-sass"] = target + res = (data.get("resolutions") or {}) - res["node-gyp"] = "^10.0.0" - res["node-sass"] = "^9.0.0" + res["node-gyp"] = "^10.0.0" + res["node-sass"] = "^9.0.0" data["resolutions"] = res + os.environ["npm_config_node_sass_binary_site"] = "https://github.com/sass/node-sass/releases/download" pj.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8") def _build_frontend(src_frontend: Path, dest_frontend: Path): + + def _semver(s: str) -> bool: return bool(re.match(r"^\d+(?:\.\d+){1,3}$", (s or "").strip())) @@ -662,17 +679,12 @@ def _build_frontend(src_frontend: Path, dest_frontend: Path): if not yarn_cmd: _ensure_yarn_installed() yarn_cmd = _pick_yarn_cmd() - if not yarn_cmd: - raise RuntimeError( - "Unable to detect or install a valid Yarn. " - "Try: apt-get install -y npm && npm i -g yarn." - ) + raise RuntimeError("Unable to detect or install a valid Yarn. Try: apt-get install -y npm && npm i -g yarn.") with step("Installing frontend dependencies (yarn)"): os.environ["NODE_ENV"] = "development" os.chdir(src_frontend) - _prepare_sass(src_frontend) cache_dir = (run_out(yarn_cmd + ["cache", "dir"], check=False) or "").strip() @@ -693,48 +705,6 @@ def _build_frontend(src_frontend: Path, dest_frontend: Path): shutil.copytree(src_frontend / "app-images", dest_frontend / "images", dirs_exist_ok=True) - def _ensure_yarn_installed(): - if not shutil.which("npm"): - try: - apt_try_install(["npm"]) - except Exception: - run(["apt-get", "update"], check=False) - run(["apt-get", "install", "-y", "npm"]) - run(["npm", "install", "-g", "yarn"], check=False) - - yarn_cmd = _pick_yarn_cmd() - if not yarn_cmd: - _ensure_yarn_installed() - yarn_cmd = _pick_yarn_cmd() - - if not yarn_cmd: - raise RuntimeError( - "Unable to detect or install a valid Yarn. " - "Try: apt-get install -y npm && npm i -g yarn." - ) - - with step("Installing frontend dependencies (yarn)"): - os.environ["NODE_ENV"] = "development" - os.chdir(src_frontend) - - cache_dir = (run_out(yarn_cmd + ["cache", "dir"], check=False) or "").strip() - if cache_dir and not Path(cache_dir).exists(): - Path(cache_dir).mkdir(parents=True, exist_ok=True) - - run(yarn_cmd + ["cache", "clean"], check=False) - run(yarn_cmd + ["install"]) - - with step("Building frontend (yarn build)"): - env = os.environ.copy() - env["NODE_OPTIONS"] = "--openssl-legacy-provider" - run(yarn_cmd + ["build"], env=env) - - with step("Copying frontend artifacts"): - shutil.copytree(src_frontend / "dist", dest_frontend, dirs_exist_ok=True) - if (src_frontend / "app-images").exists(): - shutil.copytree(src_frontend / "app-images", dest_frontend / "images", dirs_exist_ok=True) - - def patch_npm_backend_commands(): candidates = [ Path("/opt/npm/lib/utils.js"),