diff --git a/pkgs/by-name/cl/clash-rs/package.nix b/pkgs/by-name/cl/clash-rs/package.nix index de5edae3fcab..ce601655695b 100644 --- a/pkgs/by-name/cl/clash-rs/package.nix +++ b/pkgs/by-name/cl/clash-rs/package.nix @@ -6,25 +6,44 @@ versionCheckHook, cmake, pkg-config, + nodejs, + fetchNpmDeps, + npmHooks, nix-update-script, }: rustPlatform.buildRustPackage (finalAttrs: { pname = "clash-rs"; - version = "0.10.0"; + version = "0.10.6"; src = fetchFromGitHub { owner = "Watfaq"; repo = "clash-rs"; tag = "v${finalAttrs.version}"; - hash = "sha256-r+9tFw4B/7g/4EEYnX0Zcv4jPeGbcVgdtpAcSyk/cxA="; + hash = "sha256-ncMJxVNHAgeXWhqZgWt3nth4BXqrrBaAEWmOVF/KsPg="; }; - cargoHash = "sha256-D/TalJ0fBD4ZoHwU6uj5P0O6xFwinL9hE91bQhxC7s8="; + patches = [ + # Remove the `npm ci` call in build.rs as it fails. + ./skip-npm-ci.patch + ]; + + cargoHash = "sha256-WI+wg6cu0cBFrZYyN3GXlfHOmo/cVo2uMLn1D5YTOCQ="; + + npmDeps = fetchNpmDeps { + name = "${finalAttrs.pname}-${finalAttrs.version}-npm-deps"; + inherit (finalAttrs) src; + sourceRoot = "${finalAttrs.src.name}/clash-dashboard"; + hash = "sha256-8fDeO7Yx+m2s0mzTO7MkQOQ0UYs8B2vFnNevHHZFghc="; + }; + + npmRoot = "clash-dashboard"; nativeBuildInputs = [ cmake pkg-config rustPlatform.bindgenHook + nodejs + npmHooks.npmConfigHook ]; nativeInstallCheckInputs = [ @@ -33,8 +52,9 @@ rustPlatform.buildRustPackage (finalAttrs: { ]; env = { - # requires features: sync_unsafe_cell, unbounded_shifts, let_chains, ip + # requires features: sync_unsafe_cell, unbounded_shifts, let_chains, ip, if_let_guard RUSTC_BOOTSTRAP = 1; + RUSTFLAGS = "-Zcrate-attr=feature(if_let_guard)"; }; buildFeatures = [ "plus" ]; diff --git a/pkgs/by-name/cl/clash-rs/skip-npm-ci.patch b/pkgs/by-name/cl/clash-rs/skip-npm-ci.patch new file mode 100644 index 000000000000..cb148e9bb9df --- /dev/null +++ b/pkgs/by-name/cl/clash-rs/skip-npm-ci.patch @@ -0,0 +1,35 @@ +diff --git a/clash-lib/build.rs b/clash-lib/build.rs +index e8c8d44..adf9a74 100644 +--- a/clash-lib/build.rs ++++ b/clash-lib/build.rs +@@ -81,25 +81,11 @@ fn build_dashboard() -> anyhow::Result<()> { + // On Windows npm is a .cmd script, not a binary. + let npm = if cfg!(windows) { "npm.cmd" } else { "npm" }; + +- // Use /tmp for the npm cache so that non-root users inside cross containers +- // (which run as UID 1001) are not blocked by a root-owned /.npm directory +- // that the nodesource pre-build step may have created. +- let npm_cache = std::env::temp_dir().join("npm-cache"); +- +- // Run `npm ci` to install dependencies (no-op if already up to date). +- let status = match std::process::Command::new(npm) +- .args(["ci", "--prefer-offline", "--cache"]) +- .arg(&npm_cache) +- .current_dir(&dashboard_dir) +- .status() +- { +- Ok(s) => s, +- Err(e) => { +- anyhow::bail!("npm not found; is Node.js installed? ({e})"); +- } +- }; +- +- anyhow::ensure!(status.success(), "`npm ci` failed with status {status}"); ++ // Use npm_config_cache from the environment if available (Nix), ++ // otherwise fall back to /tmp for the npm cache. ++ let npm_cache = std::env::var_os("npm_config_cache") ++ .map(std::path::PathBuf::from) ++ .unwrap_or_else(|| std::env::temp_dir().join("npm-cache")); + + // Run `npm run build`. + let status = std::process::Command::new(npm)