openlogi 0.6.13

OpenLogi command-line interface — a local-first companion for Logitech HID++ peripherals.
# Nix package for OpenLogi (the GUI .app), modeled on nixpkgs' zed-editor.
#
# Build via the flake (`nix build .#openlogi`) or standalone:
#   nix-build -E 'with import <nixpkgs> {}; callPackage ./nix/package.nix {}'
#
# For a nixpkgs submission, swap the local `src` for the fetchFromGitHub block
# below, pointed at a release tag that ships crates/openlogi-gui/icon/AppIcon.icns.
{
  lib,
  rustPlatform,
  fetchFromGitHub,
  stdenv,
  cargo-bundle,
  nix-update-script,
}:

rustPlatform.buildRustPackage (finalAttrs: {
  pname = "openlogi";
  version = "0.4.0";

  # Build from the working tree (target/.git/etc. filtered out). cargo-bundle
  # uses the committed crates/openlogi-gui/icon/AppIcon.icns.
  src = lib.cleanSourceWith {
    src = ../.;
    filter =
      path: _type:
      !(builtins.elem (baseNameOf path) [
        "target"
        ".git"
        ".devenv"
        ".direnv"
        "result"
      ]);
  };
  # For nixpkgs, replace the local `src` above with a tagged tarball:
  #   src = fetchFromGitHub {
  #     owner = "AprilNEA";
  #     repo = "OpenLogi";
  #     tag = "v${finalAttrs.version}"; # a release that ships the committed .icns
  #     hash = lib.fakeHash;            # TODO
  #   };

  # One FOD vendors every dependency, including the zed / wgpu / font-kit git
  # forks gpui pulls in. Same approach as nixpkgs' zed-editor.
  cargoHash = "sha256-bY/yKDjdjFAF7A6Q8Yc/r5H0K0ATbP9Jq9zAN72CYi4=";

  postPatch = ''
    # .cargo/config.toml forces `linker = /usr/bin/cc` + a /Applications/Xcode
    # DEVELOPER_DIR for local macOS dev — neither exists in the Nix sandbox, so
    # linking would fail. Drop it; Nix's cc wrapper + runtime_shaders (below)
    # are what we want. (nixpkgs' zed-editor drops its config for the same reason.)
    rm -f .cargo/config.toml

    # gpui-component's IconName proc-macro reads `../assets/assets/icons`
    # relative to its own crate, assuming the upstream repo's workspace layout.
    # Cargo vendors each git crate separately, so that sibling dir is gone —
    # recreate it by linking the gpui-component-assets crate (the lucide SVGs).
    ( cd "$cargoDepsCopy/source-git-1" && ln -sfn gpui-component-assets-* assets )
  '';

  nativeBuildInputs = [
    cargo-bundle # assembles OpenLogi.app from [package.metadata.bundle]
  ];

  # The GUI plus the headless agent (embedded below as a login-item helper). The
  # CLI (`openlogi`) doesn't depend on gpui_platform, so it can't share the
  # `buildFeatures` below — package it separately if wanted. The agent pulls no
  # new vendored deps (tarpc/objc2 already arrive via the GUI), so `cargoHash`
  # above is unchanged by adding it.
  cargoBuildFlags = [ "--package=openlogi-gui" "--package=openlogi-agent" ];

  # Required on darwin: compile Metal shaders at runtime instead of invoking the
  # proprietary `metal` compiler at build time (it isn't in the Nix sandbox).
  # Same trick nixpkgs' zed-editor uses to ship gpui on macOS.
  buildFeatures = lib.optionals stdenv.hostPlatform.isDarwin [ "gpui_platform/runtime_shaders" ];

  # gpui tests would hit the same Metal path; nothing here is worth running.
  doCheck = false;

  # The in-app updater reads `option_env!("OPENLOGI_UPDATE_MANIFEST_URL")`;
  # leaving it unset disables self-updates — correct for a Nix-managed install.

  installPhase = lib.optionalString stdenv.hostPlatform.isDarwin ''
    runHook preInstall

    release_target="target/${stdenv.hostPlatform.rust.cargoShortTarget}/release"
    # cargo-bundle (with SKIP_BUILD) expects the binary at target/release.
    mv "$release_target/openlogi-gui" target/release/openlogi-gui

    pushd crates/openlogi-gui
    export CARGO_BUNDLE_SKIP_BUILD=true
    app_path=$(cargo bundle --release | xargs)
    popd

    # Embed the headless agent as a nested login-item helper. Mirrors xtask's
    # embed_agent_helper, since this install path runs `cargo bundle` directly
    # rather than `xtask bundle-macos`.
    helper="$app_path/Contents/Library/LoginItems/OpenLogiAgent.app"
    mkdir -p "$helper/Contents/MacOS"
    cp "$release_target/openlogi-agent" "$helper/Contents/MacOS/openlogi-agent"
    cp crates/openlogi-agent/macos/Info.plist "$helper/Contents/Info.plist"

    mkdir -p "$out/Applications"
    mv "$app_path" "$out/Applications/"

    runHook postInstall
  '';

  # `nix-update openlogi` (and nixpkgs' autobump) bump the version and refetch
  # src.hash + cargoHash automatically — effective once `src` is the
  # fetchFromGitHub form above (a local `src` has no remote version to track).
  passthru.updateScript = nix-update-script { };

  meta = {
    description = "Local-first alternative to Logitech Options+ for HID++ devices";
    homepage = "https://openlogi.org/";
    license = with lib.licenses; [
      mit
      asl20
    ];
    maintainers = [ ]; # TODO: add yourself
    platforms = lib.platforms.darwin; # Linux once the port lands (+ x11/wayland/vulkan inputs)
  };
})