diff --git a/default.nix b/default.nix index d638815..82f28fd 100644 --- a/default.nix +++ b/default.nix @@ -21,10 +21,13 @@ pango, webkitgtk_4_1, zlib, + # `desktop` and `web` are mutually exclusive cargo features (see + # diffcore-tauri/src/lib.rs), so diffcore-web needs its own derivation. + webMode ? false, }: rustPlatform.buildRustPackage { - pname = "diff-core"; + pname = if webMode then "diffcore-web" else "diff-core"; version = (lib.importTOML ./Cargo.toml).workspace.package.version; __structuredAttrs = true; @@ -40,25 +43,31 @@ rustPlatform.buildRustPackage { nativeBuildInputs = [ pkg-config - wrapGAppsHook3 nodejs npmHooks.npmConfigHook + ] + ++ lib.optionals (!webMode) [ + wrapGAppsHook3 copyDesktopItems ]; + # The web server is a plain axum binary; only the desktop app needs the + # gtk/webkit stack. buildInputs = [ + libgit2 + oniguruma + openssl + zlib + ] + ++ lib.optionals (!webMode) [ atk cairo gdk-pixbuf glib gtk3 - libgit2 libsoup_3 - oniguruma - openssl pango webkitgtk_4_1 - zlib ]; env = { @@ -70,15 +79,35 @@ rustPlatform.buildRustPackage { npm --prefix crates/diffcore-tauri/ui run build ''; - # Desktop app + CLI (production webview assets). The `web` feature is - # mutually exclusive with `desktop` upstream, so diffcore-web needs its - # own derivation. - cargoBuildFlags = [ + # Desktop app + CLI (production webview assets), or the standalone web + # server. `--no-default-features` is scoped to diffcore-tauri via `-p` so it + # does not strip defaults from the rest of the workspace. + cargoBuildFlags = + if webMode then + [ + "-p" + "diffcore-tauri" + "--no-default-features" + "--features" + "web" + ] + else + [ + "--features" + "diffcore-tauri/custom-protocol" + ]; + + # Default cargoTestFlags would test the whole workspace with default + # features, pulling `desktop` back in without gtk/webkit present. + cargoTestFlags = lib.optionals webMode [ + "-p" + "diffcore-tauri" + "--no-default-features" "--features" - "diffcore-tauri/custom-protocol" + "web" ]; - desktopItems = [ + desktopItems = lib.optionals (!webMode) [ (makeDesktopItem { name = "diffcore-tauri"; exec = "diffcore-tauri"; @@ -94,9 +123,12 @@ rustPlatform.buildRustPackage { }) ]; + # Both binaries resolve the UI from ../share/diffcore/ui relative to $out/bin. postInstall = '' mkdir -p $out/share/diffcore cp -r crates/diffcore-tauri/ui/dist $out/share/diffcore/ui + '' + + lib.optionalString (!webMode) '' for size in 32 64 128; do install -Dm444 crates/diffcore-tauri/icons/''${size}x''${size}.png \ $out/share/icons/hicolor/''${size}x''${size}/apps/diffcore-tauri.png @@ -118,9 +150,13 @@ rustPlatform.buildRustPackage { ''; meta = { - description = "Semantic diff layer for code review"; + description = + if webMode then + "Semantic diff layer for code review (web server)" + else + "Semantic diff layer for code review"; homepage = "https://github.com/jamesaphoenix/diff-core"; license = lib.licenses.mit; - mainProgram = "diffcore"; + mainProgram = if webMode then "diffcore-web" else "diffcore"; }; } diff --git a/flake.nix b/flake.nix index 2eaf1b6..fa0a67a 100644 --- a/flake.nix +++ b/flake.nix @@ -13,14 +13,16 @@ ]; forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); diffCoreFor = pkgs: pkgs.callPackage ./default.nix { }; + diffCoreWebFor = pkgs: pkgs.callPackage ./default.nix { webMode = true; }; in { packages = forAllSystems (pkgs: rec { diff-core = diffCoreFor pkgs; + diffcore-web = diffCoreWebFor pkgs; default = diff-core; }); - # The two modes: `nix run .#cli|desktop` + # The three modes: `nix run .#cli|desktop|web` apps = forAllSystems ( pkgs: let @@ -33,6 +35,10 @@ rec { cli = app "diffcore"; desktop = app "diffcore-tauri"; + web = { + type = "app"; + program = "${diffCoreWebFor pkgs}/bin/diffcore-web"; + }; default = desktop; } );