From 53100fa49ba3fe58e57aae12fc1b33605501fbd1 Mon Sep 17 00:00:00 2001 From: Niklas Zender Date: Tue, 4 Aug 2026 00:05:12 +0200 Subject: [PATCH] feat(dart): let a project choose its vodozemac release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The version was written into the bindings, so every project that adopts the standards is on the release we happened to pin. Nothing about the build needs that: what belongs here is the recipe — one crate compiled twice, the WebAssembly half through a nightly `std` rebuild with flags read off `flutter_rust_bridge` — not the choice of release. So `famedly.standards.dart.vodozemac` now carries the version and the two hashes, defaulting to what was hardcoded. A project that cannot follow a bump yet sets its own instead of dropping out of the standards, and the hook keeps comparing whatever it set against its `pubspec.yaml`, which is the drift that actually breaks an application. Signed-off-by: Niklas Zender Co-authored-by: Cursor --- nix/dart/vodozemac/default.nix | 65 +++++++++++++++++++++++++++++++--- nix/dart/vodozemac/native.nix | 5 +-- nix/dart/vodozemac/source.nix | 22 ++++++------ nix/dart/vodozemac/web.nix | 4 +-- 4 files changed, 74 insertions(+), 22 deletions(-) diff --git a/nix/dart/vodozemac/default.nix b/nix/dart/vodozemac/default.nix index e80a5254..2e4ba1fe 100644 --- a/nix/dart/vodozemac/default.nix +++ b/nix/dart/vodozemac/default.nix @@ -1,22 +1,73 @@ { lib, flake-parts-lib, ... }: importingFlake: { options.perSystem = flake-parts-lib.mkPerSystemOption ( - { pkgs, ... }: + { config, pkgs, ... }: let # The very package `packages.famedly-vodozemac` is built from, called # again rather than read off `self'`: reaching into the flake's own # packages from inside an option declaration would make the projects # depend on config that is derived from the projects. - vodozemac = pkgs.callPackage ./native.nix { }; + vodozemac = pkgs.callPackage ./native.nix { + source = pkgs.callPackage ./source.nix { + inherit (config.famedly.standards.dart.vodozemac) version hash cargoHash; + }; + }; in { + options.famedly.standards.dart.vodozemac = { + version = lib.mkOption { + description = '' + Which dart-vodozemac release to build the bindings from. + + Keep it equal to the `vodozemac` — or `flutter_vodozemac` — + constraint in the project's `pubspec.yaml`. The Dart package that + calls these bindings is generated from this very release, and a + project talking to bindings it was not generated against fails when + a call is made rather than when it is built, so a pre-commit hook + compares the two. + + The default is the release we would like everyone on. A project that + cannot follow yet sets its own, together with both hashes below, + which is why they are options at all: nothing forces two projects + onto one version of a dependency. + ''; + + type = lib.types.str; + default = "0.5.0"; + }; + + hash = lib.mkOption { + description = '' + Hash of the release's source tree, which changes with `version`. + Nix names the value it expected when this one disagrees. + ''; + + type = lib.types.str; + default = "sha256-H3g0is/+Cf3xBqqxw6qCjZSv5ZjftNSQP4hdwwEsOrs="; + }; + + cargoHash = lib.mkOption { + description = '' + Hash of the crate's vendored dependencies, which changes with the + release's `Cargo.lock`. One lockfile, so one vendor: which + dependencies a target links is decided when it is built, not when + they are resolved, and both targets share this. + ''; + + type = lib.types.str; + default = "sha256-eKKrcroV2yl/FV2WmgZWFPO5MPAGz0xCvpr0fgIuGZ4="; + }; + }; + options.famedly.standards.dart.projects = lib.mkOption { type = lib.types.attrsOf ( lib.types.submodule ( { config, ... }: { options.vodozemac.enable = lib.mkEnableOption '' - the vodozemac bindings for this project. + the vodozemac bindings for this project. Which release they are + built from is `famedly.standards.dart.vodozemac.version`, since + the bindings are built once for the repository. Points `flutter_rust_bridge`'s library lookup at the nix-built library, so `vod.init` finds it without the project having to @@ -54,11 +105,15 @@ importingFlake: { needed = lib.any (project: project.vodozemac.enable) ( lib.attrValues config.famedly.standards.dart.projects ); + + source = pkgs.callPackage ./source.nix { + inherit (config.famedly.standards.dart.vodozemac) version hash cargoHash; + }; in lib.mkMerge [ (lib.mkIf (config.famedly.standards.dart.projects != { }) { - packages.famedly-vodozemac = pkgs.callPackage ./native.nix { }; - packages.famedly-vodozemac-web = pkgs.callPackage ./web.nix { }; + packages.famedly-vodozemac = pkgs.callPackage ./native.nix { inherit source; }; + packages.famedly-vodozemac-web = pkgs.callPackage ./web.nix { inherit source; }; }) # The lookup itself goes through `runtime.env`; this only makes entering diff --git a/nix/dart/vodozemac/native.nix b/nix/dart/vodozemac/native.nix index 1140ce05..6a4da09b 100644 --- a/nix/dart/vodozemac/native.nix +++ b/nix/dart/vodozemac/native.nix @@ -1,14 +1,11 @@ { - callPackage, fixDarwinDylibNames, lib, rustPlatform, + source, stdenv, }: -let - source = callPackage ./source.nix { }; -in rustPlatform.buildRustPackage { pname = "famedly-vodozemac"; diff --git a/nix/dart/vodozemac/source.nix b/nix/dart/vodozemac/source.nix index 12751310..a0cb3234 100644 --- a/nix/dart/vodozemac/source.nix +++ b/nix/dart/vodozemac/source.nix @@ -2,29 +2,31 @@ # native library and the WebAssembly module are the same crate compiled twice, # and a version that drifted between them fails at the first call and not # before. -{ fetchFromGitHub }: +{ + fetchFromGitHub, + version, + hash, + cargoHash, +}: let - # Keep in sync with the `vodozemac` constraint in consumers' `pubspec.yaml`, - # which a pre-commit hook checks. The tags follow the Flutter plugin. - version = "0.5.0"; - src = fetchFromGitHub { owner = "famedly"; repo = "dart-vodozemac"; + + # The repository is a Flutter plugin; its tags follow that plugin's version, + # which for the releases we build is the Dart package's as well. tag = version; - hash = "sha256-H3g0is/+Cf3xBqqxw6qCjZSv5ZjftNSQP4hdwwEsOrs="; + + inherit hash; }; in { - inherit version src; + inherit version src cargoHash; # The repository is a Flutter plugin; only the crate is interesting to us. sourceRoot = "${src.name}/rust"; - # One lockfile, so one vendor for both targets. - cargoHash = "sha256-eKKrcroV2yl/FV2WmgZWFPO5MPAGz0xCvpr0fgIuGZ4="; - meta = { description = "Dart bindings for the vodozemac Matrix cryptography library"; homepage = "https://github.com/famedly/dart-vodozemac"; diff --git a/nix/dart/vodozemac/web.nix b/nix/dart/vodozemac/web.nix index 2fb80870..3387c6f3 100644 --- a/nix/dart/vodozemac/web.nix +++ b/nix/dart/vodozemac/web.nix @@ -7,12 +7,12 @@ { binaryen, buildPackages, - callPackage, cargo, lib, removeReferencesTo, rustPlatform, rustc, + source, stdenv, symlinkJoin, wasm-bindgen-cli_0_2_100, @@ -21,8 +21,6 @@ }: let - source = callPackage ./source.nix { }; - # The stem `wasm-bindgen` writes, and the name the Dart package looks up. crate = "vodozemac_bindings_dart";