refactor(#2280): packages.default = symlinkJoin — one rustc per bin, no double builds
Each binary now has its own derivation (daemonBins for hive-c0re/hive-ag3nt/MCP servers, hivectlPkg, hiveForgePkg), all sharing cargoArtifacts for a single rustc compilation. packages.default = pkgs.symlinkJoin assembles them without any additional compilation — no rustc is invoked more than once regardless of which packages the operator builds together. NixOS module consumers (pkgs.hyperhive = packages.default) are unaffected: symlinkJoin exposes all binaries at the same /bin/ paths.
This commit is contained in:
parent
c1ffa12a99
commit
4a9aff584e
1 changed files with 52 additions and 59 deletions
111
flake.nix
111
flake.nix
|
|
@ -171,66 +171,32 @@
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
inherit (nixpkgs.lib) nixosSystem;
|
inherit (nixpkgs.lib) nixosSystem;
|
||||||
};
|
};
|
||||||
in
|
# Daemon + harness + MCP server binaries. Excludes hivectl and
|
||||||
{
|
# hive-forge which are their own derivations below — so each bin
|
||||||
# Build the workspace binaries without running tests. Tests
|
# is compiled exactly once. `packages.default` joins all three
|
||||||
# are run as a separate check (`checks.cargo-test`) that
|
# via symlinkJoin; no binary is compiled more than once regardless
|
||||||
# carries the `hyperhive-assets` build input — `hive-ag3nt::
|
# of which packages the operator builds together.
|
||||||
# prompt::tests` reads the production prompt template at test
|
#
|
||||||
# runtime through `$HIVE_ASSETS_DIR`, so wiring the env var
|
# Tests are kept in the separate `checks.cargo-test` derivation
|
||||||
# into the build phase here would make the prompt's hash a
|
# (carries the hyperhive-assets build input for the prompt-template
|
||||||
# build input of `default` (defeats the asset-split cache goal: a
|
# assertions in hive-ag3nt::prompt::tests). Keeping them out of the
|
||||||
# prompt edit would still bust the binary derivation, even
|
# binary derivations means a prompt edit doesn't bust the cargo cache.
|
||||||
# though no .rs file changed). Keeping tests in a separate
|
daemonBins = craneLib.buildPackage {
|
||||||
# check derivation localises the asset-rebuild blast radius
|
|
||||||
# to that one check — `nix flake check` still exercises them.
|
|
||||||
default = craneLib.buildPackage {
|
|
||||||
src = cleanSrc;
|
src = cleanSrc;
|
||||||
inherit cargoArtifacts;
|
inherit cargoArtifacts;
|
||||||
# `installShellFiles` provides `installShellCompletion` and
|
cargoExtraArgs = "--bin hive-c0re --bin hive-agent --bin hive-agent-mcp --bin hive-agent-wake --bin hive-bash-daemon --bin hive-bash-mcp --bin hive-matrix-daemon --bin hive-matrix-mcp";
|
||||||
# `makeWrapper` provides `wrapProgram` for the postInstall below;
|
pname = "hyperhive-daemon";
|
||||||
# appended (not in the shared set) so they're build inputs only of
|
|
||||||
# this binary derivation.
|
|
||||||
nativeBuildInputs = nativeBuildInputs ++ [
|
|
||||||
pkgs.installShellFiles
|
|
||||||
pkgs.makeWrapper
|
|
||||||
];
|
|
||||||
pname = "hyperhive-workspace";
|
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
meta.description = "hyperhive workspace (hive-c0re, hive-ag3nt, hive-root)";
|
meta.description = "hyperhive daemon + agent harness + bash/matrix MCP servers";
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
# Ship hivectl shell completions in the package (the binary's own
|
|
||||||
# `completions <shell>` verb is the single source of truth, so they
|
|
||||||
# never drift from the actual verbs). Lands at
|
|
||||||
# `$out/share/{zsh/site-functions,bash-completion,fish}/…`; an
|
|
||||||
# operator gets working completion as soon as hivectl is in their
|
|
||||||
# system/user profile with the shell's completion enabled.
|
|
||||||
#
|
|
||||||
# Then wrap hivectl with `wireguard-tools` on PATH so its `wg`
|
|
||||||
# subcommands (`wg init`/`peer`/`status`) work even before the
|
|
||||||
# WireGuard mesh is configured — `wg init` is the *first* setup
|
|
||||||
# step, run before `swarm.wireguard.enable` (which would otherwise
|
|
||||||
# be what pulls wireguard-tools onto the system). Completion
|
|
||||||
# generation runs first since wrapProgram renames the real binary.
|
|
||||||
postInstall = ''
|
|
||||||
installShellCompletion --cmd hivectl \
|
|
||||||
--bash <("$out/bin/hivectl" completions bash) \
|
|
||||||
--zsh <("$out/bin/hivectl" completions zsh) \
|
|
||||||
--fish <("$out/bin/hivectl" completions fish)
|
|
||||||
wrapProgram "$out/bin/hivectl" \
|
|
||||||
--prefix PATH : ${pkgs.wireguard-tools}/bin
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
# Operator CLI only — ships `hivectl` (with shell completions
|
# Operator CLI — ships `hivectl` (with shell completions and the
|
||||||
# and the `wg` wrapper) without the daemon binaries. Suitable
|
# `wg` wrapper) without the daemon binaries. Suitable for
|
||||||
# for `nix profile install .#hivectl` / `environment.systemPackages
|
# `nix profile install .#hivectl` / `environment.systemPackages
|
||||||
# = [ inputs.hyperhive.packages.${system}.hivectl ]` when the
|
# = [ inputs.hyperhive.packages.${system}.hivectl ]` when the
|
||||||
# operator only wants the admin CLI on their workstation and
|
# operator only wants the admin CLI. Shares `cargoArtifacts` with
|
||||||
# does not want `hive-c0re` or `hive-ag3nt` in PATH.
|
# `daemonBins` so there is no double-rustc cost.
|
||||||
# Shares `cargoArtifacts` with `packages.default` so there is no
|
hivectlPkg = craneLib.buildPackage {
|
||||||
# double-compile cost when both are in the same `nix build`
|
|
||||||
# invocation.
|
|
||||||
hivectl = craneLib.buildPackage {
|
|
||||||
src = cleanSrc;
|
src = cleanSrc;
|
||||||
inherit cargoArtifacts;
|
inherit cargoArtifacts;
|
||||||
cargoExtraArgs = "--bin hivectl";
|
cargoExtraArgs = "--bin hivectl";
|
||||||
|
|
@ -238,10 +204,18 @@
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
meta.description = "hyperhive operator CLI";
|
meta.description = "hyperhive operator CLI";
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
# `installShellFiles` + `makeWrapper` scoped to this derivation
|
||||||
|
# only — daemon bins don't need them.
|
||||||
nativeBuildInputs = nativeBuildInputs ++ [
|
nativeBuildInputs = nativeBuildInputs ++ [
|
||||||
pkgs.installShellFiles
|
pkgs.installShellFiles
|
||||||
pkgs.makeWrapper
|
pkgs.makeWrapper
|
||||||
];
|
];
|
||||||
|
# Ship shell completions (the binary's own `completions <shell>`
|
||||||
|
# verb is the single source of truth, so they never drift from
|
||||||
|
# the actual verbs). Wrap with wireguard-tools so `hivectl wg`
|
||||||
|
# subcommands work before `swarm.wireguard.enable` is set (wg
|
||||||
|
# init is the very first setup step). Completion generation runs
|
||||||
|
# before wrapProgram since wrapProgram renames the real binary.
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
installShellCompletion --cmd hivectl \
|
installShellCompletion --cmd hivectl \
|
||||||
--bash <("$out/bin/hivectl" completions bash) \
|
--bash <("$out/bin/hivectl" completions bash) \
|
||||||
|
|
@ -251,11 +225,11 @@
|
||||||
--prefix PATH : ${pkgs.wireguard-tools}/bin
|
--prefix PATH : ${pkgs.wireguard-tools}/bin
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
# Forgejo CLI only — ships `hive-forge` without the rest of
|
# Forgejo CLI — ships `hive-forge` without the rest of the
|
||||||
# the workspace. Useful for operator workstations / CI
|
# workspace. Useful for operator workstations / CI environments
|
||||||
# environments that only need forge access. Shares
|
# that only need forge access. Shares `cargoArtifacts` with
|
||||||
# `cargoArtifacts` with `packages.default`.
|
# `daemonBins`.
|
||||||
hive-forge = craneLib.buildPackage {
|
hiveForgePkg = craneLib.buildPackage {
|
||||||
src = cleanSrc;
|
src = cleanSrc;
|
||||||
inherit cargoArtifacts;
|
inherit cargoArtifacts;
|
||||||
cargoExtraArgs = "--bin hive-forge";
|
cargoExtraArgs = "--bin hive-forge";
|
||||||
|
|
@ -264,6 +238,25 @@
|
||||||
meta.description = "hyperhive Forgejo CLI";
|
meta.description = "hyperhive Forgejo CLI";
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# All workspace binaries in one derivation via symlinkJoin.
|
||||||
|
# Each binary is compiled exactly once (one rustc per bin, all
|
||||||
|
# sharing `cargoArtifacts`); symlinkJoin assembles the outputs
|
||||||
|
# without any additional compilation. The NixOS module's
|
||||||
|
# `pkgs.hyperhive` (= this) and `nix build .#` both land here.
|
||||||
|
default = pkgs.symlinkJoin {
|
||||||
|
name = "hyperhive";
|
||||||
|
paths = [
|
||||||
|
daemonBins
|
||||||
|
hivectlPkg
|
||||||
|
hiveForgePkg
|
||||||
|
];
|
||||||
|
};
|
||||||
|
# Per-bin split packages — useful for operator workstations that
|
||||||
|
# only want the CLI(s) without the daemon binaries.
|
||||||
|
hivectl = hivectlPkg;
|
||||||
|
hive-forge = hiveForgePkg;
|
||||||
# Bundled browser assets — see ./nix/frontend.nix. Output is
|
# Bundled browser assets — see ./nix/frontend.nix. Output is
|
||||||
# $out/{dashboard,agent}/ which the Rust binaries serve via
|
# $out/{dashboard,agent}/ which the Rust binaries serve via
|
||||||
# tower_http::ServeDir.
|
# tower_http::ServeDir.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue