mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
4d7f8c944e
Three follow-ups from #3768, plus a bug the verification turned up. **The flake stops declaring outputs for `x86_64-darwin`.** nixpkgs drops Intel macOS in 26.11: evaluating anything for that system against `nixos-unstable` (`26.11pre-git`) throws. The rev `flake.lock` pins is 26.05-era, so it still evaluates today, carrying nixpkgs' own warning that "26.05 will be the last release to support x86_64-darwin". Naming three systems rather than `eachDefaultSystem` drops Nix support for Intel Macs now, ahead of that bump. Release binaries are untouched: `dist-workspace.toml` still ships `x86_64-apple-darwin` and nightly still tests it on `macos-15-intel`. **`git` leaves the devShell's `packages`.** It arrives with the `checks`, which crane folds in via `inputsFrom`, the same mechanism that already supplied `python3`, `procps` and `lsof`. **`task setup-web` installs `pwsh` and `jq`.** Without them Claude Code web can't run `--features shell-integration-tests`, which is what the pre-merge gate runs. PowerShell comes from the release `.deb` rather than the tarball, because pwsh aborts at startup without libicu and only the `.deb` declares that dependency for apt to resolve. The verification loop runs each tool instead of looking for it on PATH, since the tarball install left a `pwsh` that was on PATH and still aborted. **A `set -e` abort found while testing that.** The `sources.list.d` cleanup was an `&&` chain, and under `set -e` a chain ending false takes the whole task down. This one ends false on an unmatched glob and on a `.list` file with no `[` line, so setup was dying before it installed anything on a stock Debian box as well as an empty one. It's an `if` now. ## Verification No `nix` on the machine this was written on, so the flake was checked in a `nixos/nix` container and the Taskfile block in an amd64 Debian one. <details> <summary>flake: three systems evaluate, x86_64-darwin is gone, git survives its deletion</summary> ``` == devShell evaluates per system == x86_64-linux OK g172vwl0g339zsxx9l6mz5pca6w9jbcx-nix-shell.drv aarch64-linux OK pgvq71zs48bx3naddncms954jyqpl0bl-nix-shell.drv aarch64-darwin OK d17q1772si0x0hj1lgpnin8wiq4zlpr2-nix-shell.drv x86_64-darwin FAIL: flake does not provide attribute 'devShells.x86_64-darwin.default' == systems the flake declares == ["aarch64-darwin","aarch64-linux","x86_64-linux"] == tools in the x86_64-linux devShell == git: present jq: present nushell: present powershell: present python3: present procps: present lsof: present fish: present zsh: present bash: present gh: present pre-commit: present == nixfmt --check flake.nix == clean (exit 0) ``` The x86_64-darwin claim, checked against nixpkgs directly rather than inferred: ``` == nixos-unstable lib.version == "26.11pre-git" == x86_64-darwin eval on nixos-unstable == error, pointing at release-notes#x86_64-darwin-26.11 == x86_64-darwin eval on the pinned rev (flake.lock) == evaluation warning: Nixpkgs 26.05 will be the last release to support x86_64-darwin "hello-2.12.3" ``` Not verified: nothing was built, only evaluated. The nightly `nix-flake` job runs `nix flake check` on PRs touching `flake.nix`, which covers that on x86_64-linux. </details> <details> <summary>setup-web: the block run under Task's own interpreter, in an amd64 Debian container</summary> The edited block was extracted into a minimal Taskfile and run by `task` itself, so mvdan/sh parses it rather than bash. `curl` and nushell are container prereqs, not part of what's under test. ``` === running the extracted block under Task === Installing shell-integration test dependencies... pwsh installed bash available zsh available fish available nu available pwsh available jq available task exit: 0 === does the installed pwsh actually run? === 7.6.4 jq-1.6 /usr/bin/pwsh === rerun is idempotent === Installing shell-integration test dependencies... bash available zsh available fish available nu available pwsh available jq available ``` Two earlier runs are why the shape changed. The first died at the `sources.list.d` glob. The second installed PowerShell from the release tarball: every tool reported "available" and `pwsh` then aborted with `Couldn't find a valid ICU package installed on the system`, which is what moved the install to the `.deb` and the check from `command -v` to `--version`. </details> `cargo run -- hook pre-merge --yes` passes: 4574 tests, 1 skipped. ## Notes `task setup-web` still requires nushell to be present rather than installing it, unchanged here. > _This was written by Claude Code on behalf of max-sixty_ --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
250 lines
8.0 KiB
Nix
250 lines
8.0 KiB
Nix
{
|
|
description = "Worktrunk - A CLI for Git worktree management";
|
|
|
|
inputs = {
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
flake-utils.url = "github:numtide/flake-utils";
|
|
rust-overlay = {
|
|
url = "github:oxalica/rust-overlay";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
crane.url = "github:ipetkov/crane";
|
|
};
|
|
|
|
outputs =
|
|
{
|
|
self,
|
|
nixpkgs,
|
|
flake-utils,
|
|
rust-overlay,
|
|
crane,
|
|
}:
|
|
# `eachDefaultSystem` minus x86_64-darwin: nixpkgs drops Intel macOS in
|
|
# 26.11, so that system stops evaluating once flake.lock advances past
|
|
# it. Release binaries still ship for Intel macOS (dist-workspace.toml);
|
|
# this is the Nix surface only.
|
|
flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ] (
|
|
system:
|
|
let
|
|
overlays = [ (import rust-overlay) ];
|
|
pkgs = import nixpkgs {
|
|
inherit system overlays;
|
|
};
|
|
|
|
# Pin to the channel declared in rust-toolchain.toml so rustup and Nix
|
|
# stay on the same version. Extensions are dev-shell-only, so we keep
|
|
# them here rather than in rust-toolchain.toml (which CI also reads).
|
|
toolchainChannel = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml)).toolchain.channel;
|
|
rustToolchain = pkgs.rust-bin.stable.${toolchainChannel}.default.override {
|
|
extensions = [
|
|
"rust-src"
|
|
"rust-analyzer"
|
|
];
|
|
};
|
|
|
|
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;
|
|
|
|
# Filter source to include Cargo files, askama templates, and compile-time data.
|
|
# Gemini's loader requires its manifest at the repo root (see #2807).
|
|
# The benchmark fixture definition stays extensionless so Cargo does not
|
|
# auto-discover it as a bench target.
|
|
src = pkgs.lib.cleanSourceWith {
|
|
src = ./.;
|
|
filter =
|
|
p: type:
|
|
(craneLib.filterCargoSources p type)
|
|
|| (pkgs.lib.hasInfix "/templates/" p)
|
|
|| (baseNameOf (dirOf p) == "templates")
|
|
|| (pkgs.lib.hasInfix "/dev/" p)
|
|
|| (baseNameOf (dirOf p) == "dev")
|
|
|| (baseNameOf p == "gemini-extension.json")
|
|
|| (baseNameOf p == "imported-fixture");
|
|
};
|
|
|
|
# Common arguments for crane builds
|
|
commonArgs = {
|
|
inherit src;
|
|
strictDeps = true;
|
|
|
|
nativeBuildInputs = with pkgs; [
|
|
pkg-config
|
|
];
|
|
|
|
buildInputs =
|
|
with pkgs;
|
|
[
|
|
# Required for tree-sitter (syntax-highlighting feature, enabled by default)
|
|
tree-sitter
|
|
]
|
|
++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
|
|
libiconv
|
|
];
|
|
|
|
# vergen-gitcl needs git info; VERGEN_IDEMPOTENT makes it emit
|
|
# placeholder values when .git isn't available (which is the case
|
|
# in Nix builds since the store doesn't include .git)
|
|
VERGEN_IDEMPOTENT = "1";
|
|
|
|
# Optionally provide git describe via environment if flake has rev
|
|
VERGEN_GIT_DESCRIBE =
|
|
self.shortRev or self.dirtyShortRev or "nix-${self.lastModifiedDate or "unknown"}";
|
|
};
|
|
|
|
# Build just the cargo dependencies for caching.
|
|
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
|
|
|
|
# Build the actual package
|
|
worktrunk = craneLib.buildPackage (
|
|
commonArgs
|
|
// {
|
|
inherit cargoArtifacts;
|
|
|
|
# Skip tests during package build - they require snapshot files (insta)
|
|
# which bloat the source. Tests should run in CI instead.
|
|
doCheck = false;
|
|
|
|
meta = with pkgs.lib; {
|
|
description = "A CLI for Git worktree management, designed for parallel AI agent workflows";
|
|
homepage = "https://github.com/max-sixty/worktrunk";
|
|
license = with licenses; [
|
|
mit
|
|
asl20
|
|
];
|
|
maintainers = [ ];
|
|
mainProgram = "wt";
|
|
};
|
|
}
|
|
);
|
|
|
|
# Build with git-wt feature for Windows compatibility
|
|
worktrunk-with-git-wt = craneLib.buildPackage (
|
|
commonArgs
|
|
// {
|
|
inherit cargoArtifacts;
|
|
cargoExtraArgs = "--features git-wt";
|
|
doCheck = false;
|
|
|
|
meta = worktrunk.meta // {
|
|
description = "Worktrunk with git-wt binary (for 'git wt' subcommand)";
|
|
};
|
|
}
|
|
);
|
|
|
|
in
|
|
{
|
|
checks = {
|
|
inherit worktrunk;
|
|
|
|
# Run clippy
|
|
worktrunk-clippy = craneLib.cargoClippy (
|
|
commonArgs
|
|
// {
|
|
inherit cargoArtifacts;
|
|
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
|
|
}
|
|
);
|
|
|
|
# Check formatting
|
|
worktrunk-fmt = craneLib.cargoFmt { inherit src; };
|
|
|
|
# Run tests inside the nix sandbox. Catches packaging-environment
|
|
# bugs (#2624 is the canonical example) before nixpkgs maintainers
|
|
# do — see .github/workflows/nightly.yaml.
|
|
#
|
|
# Wider src than the package build: tests need .snap files and
|
|
# tests/ fixtures (prebuilt _git/ trees, .sh scripts, no-extension
|
|
# git database files). Default features only — shell-integration-
|
|
# tests wants a PTY and more shells than this derivation carries;
|
|
# the devShell below is where that set lives (see tests/CLAUDE.md →
|
|
# "Feature Flags, Not Runtime Skipping").
|
|
worktrunk-tests = craneLib.cargoTest (
|
|
commonArgs
|
|
// {
|
|
inherit cargoArtifacts;
|
|
src = pkgs.lib.cleanSource ./.;
|
|
# Tests shell out to a few host tools — `git` for the harness,
|
|
# `python3` for argv-quoting and post-start fixtures, `ps`
|
|
# (procps) for the pgid invariant test, `lsof` for the
|
|
# `--reap` process-discovery test. Without these on PATH
|
|
# the sandbox surfaces them as `No such file or directory`.
|
|
nativeBuildInputs = commonArgs.nativeBuildInputs ++ [
|
|
pkgs.git
|
|
pkgs.python3
|
|
pkgs.procps
|
|
pkgs.lsof
|
|
];
|
|
}
|
|
);
|
|
};
|
|
|
|
packages = {
|
|
default = worktrunk;
|
|
inherit worktrunk;
|
|
inherit worktrunk-with-git-wt;
|
|
};
|
|
|
|
apps = {
|
|
default = flake-utils.lib.mkApp {
|
|
drv = worktrunk;
|
|
name = "wt";
|
|
};
|
|
wt = flake-utils.lib.mkApp {
|
|
drv = worktrunk;
|
|
name = "wt";
|
|
};
|
|
};
|
|
|
|
devShells.default = craneLib.devShell {
|
|
checks = self.checks.${system};
|
|
|
|
packages = with pkgs; [
|
|
# Rust tooling
|
|
cargo-watch
|
|
cargo-edit
|
|
cargo-outdated
|
|
cargo-release
|
|
cargo-llvm-cov
|
|
|
|
# Shells the `shell-integration-tests` feature drives, plus the
|
|
# `jq` its Claude-hook tests pipe the hook payload through. The
|
|
# pre-merge gate runs `--all-features`, so a run here exercises
|
|
# every one.
|
|
bash
|
|
zsh
|
|
fish
|
|
nushell
|
|
powershell
|
|
jq
|
|
|
|
# Development tools. `git` comes from the `checks` above: crane
|
|
# folds each check's `nativeBuildInputs` in via `inputsFrom`.
|
|
gh
|
|
pre-commit
|
|
];
|
|
|
|
shellHook = ''
|
|
echo "Worktrunk development shell"
|
|
echo " Build: cargo build"
|
|
echo " Test: cargo test"
|
|
echo " Lint: cargo clippy"
|
|
'';
|
|
};
|
|
}
|
|
)
|
|
// {
|
|
homeModules = {
|
|
default =
|
|
{
|
|
lib,
|
|
config,
|
|
pkgs,
|
|
...
|
|
}:
|
|
(import ./nix/home-manager-module.nix) {
|
|
inherit lib config pkgs;
|
|
worktrunk-pkgs = self.packages.${pkgs.stdenv.hostPlatform.system};
|
|
};
|
|
};
|
|
};
|
|
}
|