Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 58 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 49 additions & 35 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -1,51 +1,65 @@
{
description = "msgvault — offline Gmail archive with full-text search";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
gitignore.url = "github:hercules-ci/gitignore.nix";
gitignore.inputs.nixpkgs.follows = "nixpkgs";
};

outputs =
{ nixpkgs, ... }:
let
forAllSystems =
fn:
nixpkgs.lib.genAttrs [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" "x86_64-darwin" ] (
system: fn nixpkgs.legacyPackages.${system}
);

# Pin Go 1.26.3 until nixpkgs-unstable catches up from staging
goPinned = pkgs: pkgs.go_1_26.overrideAttrs (old: rec {
version = "1.26.3";
src = pkgs.fetchurl {
url = "https://go.dev/dl/go${version}.src.tar.gz";
hash = "sha256-HGRoddCqh5kTMYTtV895/yS97+jIggRwYCqdPW2Rkrg=";
};
});
in
{
packages = forAllSystems (pkgs: {
default = (pkgs.buildGoModule.override { go = goPinned pkgs; }) {
pname = "msgvault";
version = "0.14.1";
src = ./.;
vendorHash = "sha256-/C+svBQ4b9+l8nY8BZ5Lvd072XLKpRDIR2fvqVqLJUE=";
proxyVendor = true;
subPackages = [ "cmd/msgvault" ];
tags = [ "fts5" ];
ldflags = [
"-X github.com/wesm/msgvault/cmd/msgvault/cmd.Version=nix-dev"
];
nixpkgs,
flake-utils,
gitignore,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};

# Pin Go 1.26.3 until nixpkgs-unstable ships it (currently 1.26.2).
# Scoped to msgvault only — do NOT export via overlay, that would
# invalidate every Go derivation in the transitive closure.
goPinned = pkgs.go_1_26.overrideAttrs (_: rec {
version = "1.26.3";
src = pkgs.fetchurl {
url = "https://go.dev/dl/go${version}.src.tar.gz";
hash = "sha256-HGRoddCqh5kTMYTtV895/yS97+jIggRwYCqdPW2Rkrg=";
};
});

buildGoModule = pkgs.buildGoModule.override { go = goPinned; };

msgvault = pkgs.callPackage ./nix/package.nix {
inherit buildGoModule;
inherit (gitignore.lib) gitignoreSource;
};
in
{
packages = {
default = msgvault;
msgvault = msgvault;
};
});

devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
apps.default = flake-utils.lib.mkApp { drv = msgvault; };

devShells.default = pkgs.mkShell {
packages = [
(goPinned pkgs)
goPinned
pkgs.gopls
pkgs.gotools
pkgs.golangci-lint
pkgs.delve
pkgs.gcc
pkgs.prek
pkgs.sqlite-interactive
];
};
});
};

formatter = pkgs.nixfmt-rfc-style;
}
);
}
48 changes: 48 additions & 0 deletions nix/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
lib,
buildGoModule,
gitignoreSource,
sqlite,
}:
let
version = "0.14.1";
in
buildGoModule {
pname = "msgvault";
inherit version;

src = gitignoreSource ../.;

vendorHash = "sha256-/C+svBQ4b9+l8nY8BZ5Lvd072XLKpRDIR2fvqVqLJUE=";
proxyVendor = true;

subPackages = [ "cmd/msgvault" ];

# mattn/go-sqlite3, marcboeker/go-duckdb, and asg017/sqlite-vec-go-bindings
# all link C code. buildGoModule defaults CGO_ENABLED to 1, but be explicit.
env.CGO_ENABLED = 1;

# sqlite-vec-go-bindings does `#include "sqlite3.h"` but ships no sqlite
# source — provide the system header via buildInputs.
buildInputs = [ sqlite ];

tags = [
"fts5"
"sqlite_vec"
];

ldflags = [
"-s"
"-w"
"-X github.com/wesm/msgvault/cmd/msgvault/cmd.Version=${version}"
];

doCheck = false;

meta = {
description = "Offline Gmail archive with full-text search";
homepage = "https://github.com/wesm/msgvault";
license = lib.licenses.asl20;
mainProgram = "msgvault";
};
}
25 changes: 13 additions & 12 deletions scripts/update-nix-flake.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# update-nix-flake.sh — Update flake.nix vendorHash (and optionally version),
# update-nix-flake.sh — Update nix/package.nix vendorHash (and optionally version),
# then open a PR. Designed to be run after dependency changes or releases.
#
# Usage:
Expand All @@ -11,6 +11,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$REPO_ROOT"

PACKAGE_NIX="nix/package.nix"

VERSION_TAG="${1:-}"

# Require nix and gh
Expand All @@ -36,7 +38,7 @@ echo "==> Creating branch $BRANCH from origin/main..."
git fetch origin
git checkout -b "$BRANCH" origin/main

# Step 1: Update version in flake.nix if a version tag was provided
# Step 1: Update version in nix/package.nix if a version tag was provided
if [ -n "$VERSION_TAG" ]; then
# Strip leading 'v' if present
VERSION="${VERSION_TAG#v}"
Expand All @@ -46,17 +48,16 @@ if [ -n "$VERSION_TAG" ]; then
exit 1
fi
echo "==> Updating version to $VERSION..."
# Only replace the msgvault version (after pname), not the Go version
sed -i.bak -E '/pname = "msgvault"/,/version = "[^"]+"/ s/version = "[^"]+"/version = "'"$VERSION"'"/' flake.nix
rm -f flake.nix.bak
sed -i.bak -E 's/version = "[^"]+"/version = "'"$VERSION"'"/' "$PACKAGE_NIX"
rm -f "${PACKAGE_NIX}.bak"
fi

# Step 2: Compute the correct vendorHash
echo "==> Computing vendorHash (this runs nix build with a fake hash)..."

# Set a fake hash to force nix to report the correct one
sed -i.bak -E 's|vendorHash = "sha256-[^"]+"|vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="|' flake.nix
rm -f flake.nix.bak
sed -i.bak -E 's|vendorHash = "sha256-[^"]+"|vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="|' "$PACKAGE_NIX"
rm -f "${PACKAGE_NIX}.bak"

# Run nix build — it will fail and print the correct hash
CORRECT_HASH=""
Expand All @@ -67,29 +68,29 @@ CORRECT_HASH=$(echo "$BUILD_OUTPUT" | sed -n 's/.*got:[[:space:]]*\(sha256-[A-Za
if [ -z "$CORRECT_HASH" ] || ! echo "$CORRECT_HASH" | grep -qE '^sha256-[A-Za-z0-9+/]{43}=$'; then
echo "Error: Could not extract valid vendorHash from nix build output:" >&2
echo "$BUILD_OUTPUT" >&2
git checkout -- flake.nix
git checkout -- "$PACKAGE_NIX"
git checkout -
git branch -D "$BRANCH"
exit 1
fi

echo "==> Got vendorHash: $CORRECT_HASH"
sed -i.bak -E "s|vendorHash = \"sha256-[^\"]+\"|vendorHash = \"$CORRECT_HASH\"|" flake.nix
rm -f flake.nix.bak
sed -i.bak -E "s|vendorHash = \"sha256-[^\"]+\"|vendorHash = \"$CORRECT_HASH\"|" "$PACKAGE_NIX"
rm -f "${PACKAGE_NIX}.bak"

# Step 3: Verify it actually builds
echo "==> Verifying nix build succeeds..."
if ! nix build; then
echo "Error: nix build failed even with updated hash" >&2
git checkout -- flake.nix
git checkout -- "$PACKAGE_NIX"
git checkout -
git branch -D "$BRANCH"
exit 1
fi

# Step 4: Commit and open PR
echo "==> Committing and opening PR..."
git add flake.nix
git add "$PACKAGE_NIX"

COMMIT_MSG="Update nix flake vendorHash"
PR_TITLE="Update nix flake vendorHash"
Expand Down
Loading