From b8ef21dadc16ce0c02a9aeb384387c0f60ac1b5c Mon Sep 17 00:00:00 2001 From: Sean Aye Date: Fri, 7 Aug 2026 12:36:34 -0400 Subject: [PATCH] chore(nix): consolidate development shells --- README.md | 4 + apps/web/README.md | 11 +- ...hql-cache-optimistic-enqueue-claim-plan.md | 4 +- crates/client/README.md | 4 +- nix/cloud-storage.nix | 5 + nix/js-app.nix | 173 ------------------ nix/tauri-dev-shells.nix | 117 ++++++++++++ 7 files changed, 140 insertions(+), 178 deletions(-) delete mode 100644 nix/js-app.nix create mode 100644 nix/tauri-dev-shells.nix diff --git a/README.md b/README.md index 04b95f9f90f..9d8aeff56da 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,10 @@ nix develop # Rust toolchain, Bun, sqlx, zig, cargo-zigbuild just run_local # local infra + backend services + proxy + frontend ``` +Tauri's large platform dependencies live in focused shells: use +`nix develop .#tauri-linux` for Linux desktop development or +`nix develop .#tauri-android` for Android development on x86_64 Linux. + `run_local` prints the frontend URL once the stack is up; `r` rebuilds changed Rust services, `q` tears it down. See [Running locally](docs/RUNNING_LOCALLY.md) for Doppler setup and named instances. ```bash diff --git a/apps/web/README.md b/apps/web/README.md index 745940dcfc9..5e39b75167f 100644 --- a/apps/web/README.md +++ b/apps/web/README.md @@ -48,8 +48,17 @@ You will need the following dependencies installed on your system to develop in 1. *For Android Development* The [Android Studio IDE](https://developer.android.com/studio) 1. *For iOS Development* [XCode](https://developer.apple.com/xcode/) for MacOS -If you do not want to manage these dependencies manually, it is recommended to use `nix develop` +The default shell contains the shared frontend and Tauri CLI tooling. Use the +focused shells when developing targets with large platform dependencies: +```bash +nix develop .#tauri-linux # GTK/WebKitGTK/GStreamer desktop stack +nix develop .#tauri-android # Android Studio, SDK/NDK, emulator, and Rust targets +``` + +`tauri-android` is available on x86_64 Linux. On macOS, use the default shell +with the platform IDE installed outside Nix (Xcode for iOS or Android Studio +for Android). ### Running Tauri diff --git a/apps/web/docs/graphql-cache-optimistic-enqueue-claim-plan.md b/apps/web/docs/graphql-cache-optimistic-enqueue-claim-plan.md index 2fc7082b586..32b85993185 100644 --- a/apps/web/docs/graphql-cache-optimistic-enqueue-claim-plan.md +++ b/apps/web/docs/graphql-cache-optimistic-enqueue-claim-plan.md @@ -393,10 +393,10 @@ Run the focused frontend tests for: - `tauri-host.test.ts` - grouped optimistic property tests -Then run the Tauri plugin tests using the established JS-app shell: +Then run the Tauri plugin tests using the Linux Tauri shell: ```bash -nix develop .#js-app --command cargo test \ +nix develop .#tauri-linux --command cargo test \ --manifest-path apps/web/tauri/graphql_cache_plugin/Cargo.toml ``` diff --git a/crates/client/README.md b/crates/client/README.md index 1ed08e67904..7d473c604bb 100644 --- a/crates/client/README.md +++ b/crates/client/README.md @@ -15,8 +15,8 @@ Normalized GraphQL cache with disk-backed persistence for urql. Design doc: The Tauri host lives in the tauri workspace (it needs the patched tauri fork pinned there): `apps/web/tauri/graphql_cache_plugin`, path-depending on `cache-core`/`cache-sqlite`. Test it from `apps/web/tauri` with -`cargo test -p graphql_cache_plugin` (on NixOS use the `js-app` dev shell — -tauri's Linux desktop stack needs its webkitgtk/dbus system libs). +`cargo test -p graphql_cache_plugin` (on NixOS use the `tauri-linux` dev shell — +Tauri's Linux desktop stack needs its WebKitGTK/DBus system libraries). ## Tests diff --git a/nix/cloud-storage.nix b/nix/cloud-storage.nix index 2181225aa9f..34cc488d4e9 100644 --- a/nix/cloud-storage.nix +++ b/nix/cloud-storage.nix @@ -666,12 +666,14 @@ parallel docker-compose curl + wget kcat xz unzip zip cargo-info cargo-udeps + cargo-tauri cargo-lambda cargo-zigbuild zig @@ -713,6 +715,9 @@ nodejs_24 pulumi pulumiPackages.pulumi-nodejs + pulumiPackages.pulumi-aws-native + playwright + playwright-mcp doppler biome jq diff --git a/nix/js-app.nix b/nix/js-app.nix deleted file mode 100644 index c517cb5f732..00000000000 --- a/nix/js-app.nix +++ /dev/null @@ -1,173 +0,0 @@ -{ inputs, ... }: -{ - perSystem = - { system, ... }: - let - inherit (inputs) - nixpkgs - fenix - ; - pkgs = import nixpkgs { - system = system; - }; - isDarwin = pkgs.stdenv.isDarwin; - isLinux = pkgs.stdenv.isLinux; - - # ── js-app (frontend Tauri app) ──────────────────────────────── - - # Need allowUnfree + android license for the Android SDK - jsPkgs = import nixpkgs { - inherit system; - config.allowUnfree = true; - config.android_sdk.accept_license = true; - }; - - android_sdk = pkgs.lib.optionalAttrs isLinux ( - (jsPkgs.androidenv.composeAndroidPackages { - platformVersions = [ - "34" - "36" - ]; - buildToolsVersions = [ - "35.0.0" - ]; - ndkVersions = [ "26.3.11579264" ]; - includeNDK = true; - useGoogleAPIs = false; - useGoogleTVAddOns = false; - includeEmulator = true; - includeSystemImages = true; - systemImageTypes = [ "google_apis_playstore" ]; - abiVersions = [ "x86_64" ]; - includeSources = false; - }).androidsdk - ); - - jsRustComponents = with fenix.packages.${system}; [ - complete.rustc - complete.rust-src - complete.cargo - complete.clippy - complete.rustfmt - complete.rust-analyzer - targets.wasm32-unknown-unknown.latest.rust-std - ]; - - jsRustToolchain = with fenix.packages.${system}; combine jsRustComponents; - jsAndroidRustToolchain = - with fenix.packages.${system}; - combine ( - jsRustComponents - ++ [ - targets.aarch64-linux-android.latest.rust-std - targets.armv7-linux-androideabi.latest.rust-std - targets.i686-linux-android.latest.rust-std - targets.x86_64-linux-android.latest.rust-std - ] - ); - - jsBasePackages = with jsPkgs; [ - curl - wget - pkg-config - just - bun - biome - nodejs_24 - typescript-language-server - cargo-tauri - cargo-info - cargo-udeps - wasm-pack - wasm-bindgen-cli - cmake - nasm - pulumi - pulumiPackages.pulumi-nodejs - pulumiPackages.pulumi-aws-native - playwright - playwright-mcp - ]; - - jsLinuxPackages = with jsPkgs; [ - gst_all_1.gstreamer - gst_all_1.gst-plugins-base - gst_all_1.gst-plugins-good - gst_all_1.gst-plugins-bad - xdg-utils - ]; - - jsPackages = jsBasePackages ++ [ jsRustToolchain ] ++ pkgs.lib.optionals isLinux jsLinuxPackages; - jsAndroidPackages = - jsBasePackages - ++ [ jsAndroidRustToolchain ] - ++ pkgs.lib.optionals isLinux ( - jsLinuxPackages - ++ [ - jsPkgs.jdk - android_sdk - ] - ); - - jsLinuxLibraries = with jsPkgs; [ - gtk3 - libsoup_3 - webkitgtk_4_1 - cairo - gdk-pixbuf - glib - dbus - openssl - librsvg - lsb-release - ]; - - jsDarwinLibraries = with jsPkgs; [ - openssl - libiconv - ]; - - jsLibraries = if isDarwin then jsDarwinLibraries else jsLinuxLibraries; - jsPkgConfigPath = pkgs.lib.makeSearchPath "lib/pkgconfig" [ - jsPkgs.openssl.dev - ]; - jsCmakeFixEnv = { - # Match the default dev shell's aws-lc-sys path. Its default cc builder - # can reject wrapped cross compilers; the CMake builder needs cmake+nasm. - AWS_LC_SYS_CMAKE_BUILDER = "1"; - }; - jsLinuxShellHook = '' - export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath jsLibraries}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" - export XDG_DATA_DIRS="${jsPkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${jsPkgs.gsettings-desktop-schemas.name}:${jsPkgs.gtk3}/share/gsettings-schemas/${jsPkgs.gtk3.name}''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}" - ''; - in - { - devShells = { - js-app = jsPkgs.mkShell ( - { - buildInputs = jsPackages ++ jsLibraries; - PKG_CONFIG_PATH = jsPkgConfigPath; - } - // jsCmakeFixEnv - // pkgs.lib.optionalAttrs isLinux { - shellHook = jsLinuxShellHook; - GIO_MODULE_DIR = "${jsPkgs.glib-networking}/lib/gio/modules/"; - } - ); - } - // pkgs.lib.optionalAttrs isLinux { - js-app-android = jsPkgs.mkShell ( - { - buildInputs = jsAndroidPackages ++ jsLibraries; - PKG_CONFIG_PATH = jsPkgConfigPath; - shellHook = jsLinuxShellHook; - ANDROID_HOME = "${android_sdk}/libexec/android-sdk"; - NDK_HOME = "${android_sdk}/libexec/android-sdk/ndk/26.3.11579264"; - GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${android_sdk}/libexec/android-sdk/build-tools/35.0.0/aapt2"; - GIO_MODULE_DIR = "${jsPkgs.glib-networking}/lib/gio/modules/"; - } - // jsCmakeFixEnv - ); - }; - }; -} diff --git a/nix/tauri-dev-shells.nix b/nix/tauri-dev-shells.nix new file mode 100644 index 00000000000..11b1421ad2d --- /dev/null +++ b/nix/tauri-dev-shells.nix @@ -0,0 +1,117 @@ +{ inputs, ... }: +{ + perSystem = + { config, system, ... }: + let + inherit (inputs) + nixpkgs + fenix + ; + pkgs = import nixpkgs { + inherit system; + }; + lib = pkgs.lib; + isLinux = pkgs.stdenv.isLinux; + isX86_64Linux = system == "x86_64-linux"; + + # Android Studio is unfree, and the composed SDK requires accepting the + # Android SDK license. Keep this package set isolated from the default + # shell so ordinary development does not pull in the mobile toolchain. + tauriPkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + config.android_sdk.accept_license = true; + }; + + androidSdk = + (tauriPkgs.androidenv.composeAndroidPackages { + platformVersions = [ + "34" + "36" + ]; + buildToolsVersions = [ "35.0.0" ]; + ndkVersions = [ "26.3.11579264" ]; + includeNDK = true; + useGoogleAPIs = false; + useGoogleTVAddOns = false; + includeEmulator = true; + includeSystemImages = true; + systemImageTypes = [ "google_apis_playstore" ]; + abiVersions = [ "x86_64" ]; + includeSources = false; + }).androidsdk; + + androidRustToolchain = + with fenix.packages.${system}; + combine [ + complete.rustc + complete.rust-src + complete.cargo + complete.clippy + complete.rustfmt + complete.rust-analyzer + targets.wasm32-unknown-unknown.latest.rust-std + targets.aarch64-linux-android.latest.rust-std + targets.armv7-linux-androideabi.latest.rust-std + targets.i686-linux-android.latest.rust-std + targets.x86_64-linux-android.latest.rust-std + ]; + + tauriLinuxPackages = with tauriPkgs; [ + gst_all_1.gstreamer + gst_all_1.gst-plugins-base + gst_all_1.gst-plugins-good + gst_all_1.gst-plugins-bad + xdg-utils + ]; + + tauriLinuxLibraries = with tauriPkgs; [ + gtk3 + libsoup_3 + webkitgtk_4_1 + cairo + gdk-pixbuf + glib + dbus + openssl + librsvg + lsb-release + ]; + + tauriLinuxShellHook = '' + export LD_LIBRARY_PATH="${lib.makeLibraryPath tauriLinuxLibraries}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + export XDG_DATA_DIRS="${tauriPkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${tauriPkgs.gsettings-desktop-schemas.name}:${tauriPkgs.gtk3}/share/gsettings-schemas/${tauriPkgs.gtk3.name}''${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}" + ''; + in + { + devShells = + lib.optionalAttrs isLinux { + tauri-linux = config.devShells.default.overrideAttrs (old: { + buildInputs = (old.buildInputs or [ ]) ++ tauriLinuxPackages ++ tauriLinuxLibraries; + shellHook = (old.shellHook or "") + tauriLinuxShellHook; + GIO_MODULE_DIR = "${tauriPkgs.glib-networking}/lib/gio/modules/"; + }); + } + // lib.optionalAttrs isX86_64Linux { + tauri-android = config.devShells.default.overrideAttrs (old: { + # Put the Android-capable toolchain before the default toolchain and + # explicitly prepend it to PATH below so rustc can find every + # Android target regardless of mkShell input ordering. + buildInputs = [ + androidRustToolchain + tauriPkgs.jdk + androidSdk + tauriPkgs.android-studio + ] + ++ (old.buildInputs or [ ]); + shellHook = (old.shellHook or "") + '' + export PATH="${androidRustToolchain}/bin:$PATH" + ''; + ANDROID_HOME = "${androidSdk}/libexec/android-sdk"; + ANDROID_SDK_ROOT = "${androidSdk}/libexec/android-sdk"; + NDK_HOME = "${androidSdk}/libexec/android-sdk/ndk/26.3.11579264"; + GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidSdk}/libexec/android-sdk/build-tools/35.0.0/aapt2"; + }); + }; + }; +}