nandi/gleanpublic Fork 0
d76710b
Commits
Clone
git clone https://git.rickub.com/nandi/glean.git
git clone ssh://git@rickub.com/nandi/glean.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Remove buck2 and make the flake the single build entry point

buck2 was a one-target wrapper: a genrule that shelled out to
scripts/build-image.sh, which in turn ran `nix build .#image`. The whole
prelude/toolchain/cell setup existed to describe a build that Nix already
described. Delete BUCK, .buckconfig, .buckroot and toolchains/, and let
the flake own it directly.

The flake now covers every system it can (x86_64/aarch64 linux, aarch64
darwin -- nixpkgs unstable has dropped x86_64-darwin), and gains a
devShell with the CGO include flags the Makefile computes, apps for
`nix run .#glean` / `nix run .#image`, checks that build the binary and
frontend and run the Go tests, and a committed flake.lock. The image
output stays Linux-only, since dockerTools is.

build-image.sh is no longer fed a buck2 symlink farm: it resolves the
repo from its own location, builds locally when `nix` is present, and
only falls back to the remote $GLEAN_NIX_VM builder otherwise. The
Makefile's docker-build/docker-push targets pointed at a Dockerfile that
no longer exists; image/image-load/image-push replace them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nandi committed 2026-09-05T10:10:13-07:00 Browse files
d76710b parent: e861f3e
deleted .buckconfig +0 -29
deleted file mode 100644
@@ -1,29 +0,0 @@
1-[cells]
2- root = .
3- prelude = prelude
4- toolchains = toolchains
5- none = none
6-
7-[cell_aliases]
8- config = prelude
9- ovr_config = prelude
10- fbcode = none
11- fbsource = none
12- fbcode_macros = none
13- buck = none
14-
15-# Uses a copy of the prelude bundled with the buck2 binary. You can alternatively delete this
16-# section and vendor a copy of the prelude to the `prelude` directory of your project.
17-[external_cells]
18- prelude = bundled
19-
20-[parser]
21- target_platform_detector_spec = target:root//...->prelude//platforms:default \
22- target:prelude//...->prelude//platforms:default \
23- target:toolchains//...->prelude//platforms:default
24-
25-[build]
26- execution_platforms = prelude//platforms:default
27-
28-[project]
29- ignore = .git, web/node_modules, web/.svelte-kit, web/build
deleted file mode 100644
@@ -1,29 +0,0 @@
1-[cells]
2- root = .
3- prelude = prelude
4- toolchains = toolchains
5- none = none
6-
7-[cell_aliases]
8- config = prelude
9- ovr_config = prelude
10- fbcode = none
11- fbsource = none
12- fbcode_macros = none
13- buck = none
14-
15-# Uses a copy of the prelude bundled with the buck2 binary. You can alternatively delete this
16-# section and vendor a copy of the prelude to the `prelude` directory of your project.
17-[external_cells]
18- prelude = bundled
19-
20-[parser]
21- target_platform_detector_spec = target:root//...->prelude//platforms:default \
22- target:prelude//...->prelude//platforms:default \
23- target:toolchains//...->prelude//platforms:default
24-
25-[build]
26- execution_platforms = prelude//platforms:default
27-
28-[project]
29- ignore = .git, web/node_modules, web/.svelte-kit, web/build
deleted .buckroot +0 -0
deleted file mode 100644
deleted file mode 100644
modified .gitignore +2 -2
@@ -31,8 +31,8 @@ web/node_modules/
3131 web/build/
3232 web/.svelte-kit/
3333
34-# buck2
35-/buck-out
34+# container image tarball
35+/glean-image.tar
3636
3737 # todo
3838 todo.md
@@ -31,8 +31,8 @@ web/node_modules/
31 web/build/31 web/build/
32 web/.svelte-kit/32 web/.svelte-kit/
33 33
34-# buck234+# container image tarball
35-/buck-out35+/glean-image.tar
36 36
37 # todo37 # todo
38 todo.md38 todo.md
modified .tangled/workflows/ci.yml +3 -0
@@ -11,6 +11,9 @@ clone:
1111 skip: false
1212 depth: 1
1313
14+# The repo is a nix flake (flake.nix): `nix build`/`nix develop` reproduce this
15+# environment exactly. The nixery engine has no `nix` of its own, so CI pulls
16+# the same toolchain the devShell declares and drives the Makefile directly.
1417 dependencies:
1518 nixpkgs:
1619 - go
@@ -11,6 +11,9 @@ clone:
11 skip: false11 skip: false
12 depth: 112 depth: 1
13 13
14+# The repo is a nix flake (flake.nix): `nix build`/`nix develop` reproduce this
15+# environment exactly. The nixery engine has no `nix` of its own, so CI pulls
16+# the same toolchain the devShell declares and drives the Makefile directly.
14 dependencies:17 dependencies:
15 nixpkgs:18 nixpkgs:
16 - go19 - go
deleted BUCK +0 -30
deleted file mode 100644
@@ -1,30 +0,0 @@
1-# A list of available rules and their signatures can be found here: https://buck2.build/docs/prelude/globals/
2-
3-export_file(
4- name = "build_image_sh",
5- src = "scripts/build-image.sh",
6-)
7-
8-# Builds the glean container image via Nix's dockerTools.streamLayeredImage
9-# (see flake.nix), executed on the remote `nix-vm` builder over SSH -- this
10-# machine has no `nix` installed. The genrule itself stays a thin, uninvolved
11-# wrapper; all the actual rsync/ssh side effects live in build-image.sh.
12-genrule(
13- name = "image",
14- out = "glean-image.tar",
15- # Populates $SRCDIR with a symlink farm mirroring the whole repo tree
16- # (minus buck-out/.git/node_modules) -- build-image.sh rsyncs it to the
17- # remote nix-vm builder, since it needs the full source, not just this
18- # target's declared deps.
19- srcs = glob(
20- ["**/*"],
21- exclude = [
22- "buck-out/**",
23- ".git/**",
24- "web/node_modules/**",
25- "web/.svelte-kit/**",
26- "web/build/**",
27- ],
28- ),
29- cmd = "chmod +x $(location :build_image_sh) && $(location :build_image_sh) $SRCDIR $OUT",
30-)
deleted file mode 100644
@@ -1,30 +0,0 @@
1-# A list of available rules and their signatures can be found here: https://buck2.build/docs/prelude/globals/
2-
3-export_file(
4- name = "build_image_sh",
5- src = "scripts/build-image.sh",
6-)
7-
8-# Builds the glean container image via Nix's dockerTools.streamLayeredImage
9-# (see flake.nix), executed on the remote `nix-vm` builder over SSH -- this
10-# machine has no `nix` installed. The genrule itself stays a thin, uninvolved
11-# wrapper; all the actual rsync/ssh side effects live in build-image.sh.
12-genrule(
13- name = "image",
14- out = "glean-image.tar",
15- # Populates $SRCDIR with a symlink farm mirroring the whole repo tree
16- # (minus buck-out/.git/node_modules) -- build-image.sh rsyncs it to the
17- # remote nix-vm builder, since it needs the full source, not just this
18- # target's declared deps.
19- srcs = glob(
20- ["**/*"],
21- exclude = [
22- "buck-out/**",
23- ".git/**",
24- "web/node_modules/**",
25- "web/.svelte-kit/**",
26- "web/build/**",
27- ],
28- ),
29- cmd = "chmod +x $(location :build_image_sh) && $(location :build_image_sh) $SRCDIR $OUT",
30-)
modified Makefile +18 -7
@@ -83,13 +83,24 @@ check:
8383
8484 .PHONY: clean
8585 clean:
86- rm -f glean glean.db
86+ rm -f glean glean.db $(IMAGE_TAR)
8787 rm -rf web/build web/.svelte-kit
8888
89-.PHONY: docker-build
90-docker-build:
91- docker build -t glean:latest -t atcr.io/julien.rbrt.fr/glean:latest .
89+# Container image: built by Nix (flake.nix `image` output, dockerTools
90+# streamLayeredImage). scripts/build-image.sh builds locally when `nix` is
91+# present and otherwise on the remote builder in $GLEAN_NIX_VM.
92+IMAGE ?= atcr.io/julien.rbrt.fr/glean:latest
93+IMAGE_TAR ?= glean-image.tar
9294
93-.PHONY: docker-push
94-docker-push:
95- docker push atcr.io/julien.rbrt.fr/glean:latest
95+.PHONY: image
96+image:
97+ scripts/build-image.sh $(IMAGE_TAR)
98+
99+.PHONY: image-load
100+image-load: image
101+ docker load < $(IMAGE_TAR)
102+ docker tag glean:latest $(IMAGE)
103+
104+.PHONY: image-push
105+image-push: image-load
106+ docker push $(IMAGE)
@@ -83,13 +83,24 @@ check:
83 83
84 .PHONY: clean84 .PHONY: clean
85 clean:85 clean:
86- rm -f glean glean.db86+ rm -f glean glean.db $(IMAGE_TAR)
87 rm -rf web/build web/.svelte-kit87 rm -rf web/build web/.svelte-kit
88 88
89-.PHONY: docker-build89+# Container image: built by Nix (flake.nix `image` output, dockerTools
90-docker-build:90+# streamLayeredImage). scripts/build-image.sh builds locally when `nix` is
91- docker build -t glean:latest -t atcr.io/julien.rbrt.fr/glean:latest .91+# present and otherwise on the remote builder in $GLEAN_NIX_VM.
92+IMAGE ?= atcr.io/julien.rbrt.fr/glean:latest
93+IMAGE_TAR ?= glean-image.tar
92 94
93-.PHONY: docker-push95+.PHONY: image
94-docker-push:96+image:
95- docker push atcr.io/julien.rbrt.fr/glean:latest97+ scripts/build-image.sh $(IMAGE_TAR)
98+
99+.PHONY: image-load
100+image-load: image
101+ docker load < $(IMAGE_TAR)
102+ docker tag glean:latest $(IMAGE)
103+
104+.PHONY: image-push
105+image-push: image-load
106+ docker push $(IMAGE)
added flake.lock +27 -0
new file mode 100644
@@ -0,0 +1,27 @@
1+{
2+ "nodes": {
3+ "nixpkgs": {
4+ "locked": {
5+ "lastModified": 1788531059,
6+ "narHash": "sha256-hLD4l3QOGBQhkVp3mQ2lJ/YbEi99qUgKapb40KovZ88=",
7+ "owner": "NixOS",
8+ "repo": "nixpkgs",
9+ "rev": "801bef6abd86b91e51083066b83fb354a11fc640",
10+ "type": "github"
11+ },
12+ "original": {
13+ "owner": "NixOS",
14+ "ref": "nixos-unstable",
15+ "repo": "nixpkgs",
16+ "type": "github"
17+ }
18+ },
19+ "root": {
20+ "inputs": {
21+ "nixpkgs": "nixpkgs"
22+ }
23+ }
24+ },
25+ "root": "root",
26+ "version": 7
27+}
new file mode 100644
@@ -0,0 +1,27 @@
1+{
2+ "nodes": {
3+ "nixpkgs": {
4+ "locked": {
5+ "lastModified": 1788531059,
6+ "narHash": "sha256-hLD4l3QOGBQhkVp3mQ2lJ/YbEi99qUgKapb40KovZ88=",
7+ "owner": "NixOS",
8+ "repo": "nixpkgs",
9+ "rev": "801bef6abd86b91e51083066b83fb354a11fc640",
10+ "type": "github"
11+ },
12+ "original": {
13+ "owner": "NixOS",
14+ "ref": "nixos-unstable",
15+ "repo": "nixpkgs",
16+ "type": "github"
17+ }
18+ },
19+ "root": {
20+ "inputs": {
21+ "nixpkgs": "nixpkgs"
22+ }
23+ }
24+ },
25+ "root": "root",
26+ "version": 7
27+}
modified flake.nix +93 -24
@@ -7,17 +7,17 @@
77
88 outputs = { self, nixpkgs }:
99 let
10- system = "x86_64-linux";
11- pkgs = import nixpkgs { inherit system; };
12- lib = pkgs.lib;
10+ systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
11+ forEachSystem = f: nixpkgs.lib.genAttrs systems (system:
12+ f (import nixpkgs { inherit system; }));
1313
1414 # --- Go API binary -----------------------------------------------------
15- # Mirrors the Dockerfile's CGO setup: mattn/go-sqlite3 vendors its own
16- # sqlite3 amalgamation, but sqlite-vec-go-bindings' cgo code expects a
17- # plain `sqlite3.h` on the include path. internal/db/include/sqlite3.h
18- # is that header; go-sqlite3's own module dir is added too so the
19- # u_intN_t compat defines line up with the same sqlite3 version.
20- glean = pkgs.buildGoModule {
15+ # Mirrors the historical Dockerfile's CGO setup: mattn/go-sqlite3 vendors
16+ # its own sqlite3 amalgamation, but sqlite-vec-go-bindings' cgo code
17+ # expects a plain `sqlite3.h` on the include path. internal/db/include/
18+ # sqlite3.h is that header; go-sqlite3's own module dir is added too so
19+ # the u_intN_t compat defines line up with the same sqlite3 version.
20+ mkGlean = pkgs: pkgs.buildGoModule {
2121 pname = "glean";
2222 version = "0.0.1";
2323 src = ./.;
@@ -42,7 +42,7 @@
4242 # normal derivation -- split into a fixed-output "fetch deps" step
4343 # (network allowed, output hash pinned) and a sandboxed "build" step
4444 # that only ever sees the already-fetched node_modules.
45- webDeps = pkgs.stdenvNoCC.mkDerivation {
45+ mkWebDeps = pkgs: pkgs.stdenvNoCC.mkDerivation {
4646 pname = "glean-web-deps";
4747 version = "0.0.1";
4848 src = ./web;
@@ -63,7 +63,7 @@
6363 outputHash = "sha256-q/VJbH1rWCsxf3A3RYb22t2RrtjUm4xCCrCZkLkAFFY=";
6464 };
6565
66- frontend = pkgs.stdenvNoCC.mkDerivation {
66+ mkFrontend = pkgs: webDeps: pkgs.stdenvNoCC.mkDerivation {
6767 pname = "glean-web";
6868 version = "0.0.1";
6969 src = ./web;
@@ -92,7 +92,7 @@
9292 # Runs both processes the same way the Dockerfile's CMD did: the Go API
9393 # in the background on loopback:8080, the SvelteKit Node server in front
9494 # on $PORT, proxying /api to it.
95- entrypoint = pkgs.writeShellScriptBin "glean-entrypoint" ''
95+ mkEntrypoint = pkgs: glean: frontend: pkgs.writeShellScriptBin "glean-entrypoint" ''
9696 set -euo pipefail
9797 export GLEAN_ADDR="127.0.0.1:8080"
9898 export GLEAN_API_URL="http://127.0.0.1:8080"
@@ -103,19 +103,88 @@
103103 '';
104104 in
105105 {
106- packages.${system} = {
107- inherit glean frontend webDeps;
108-
109- image = pkgs.dockerTools.streamLayeredImage {
110- name = "glean";
111- tag = "latest";
112- contents = [ pkgs.cacert pkgs.tzdata pkgs.dockerTools.fakeNss entrypoint ];
113- config = {
114- Cmd = [ "${entrypoint}/bin/glean-entrypoint" ];
115- Env = [ "PORT=3000" ];
116- ExposedPorts = { "3000/tcp" = { }; };
106+ packages = forEachSystem (pkgs:
107+ let
108+ glean = mkGlean pkgs;
109+ webDeps = mkWebDeps pkgs;
110+ frontend = mkFrontend pkgs webDeps;
111+ entrypoint = mkEntrypoint pkgs glean frontend;
112+ in
113+ {
114+ inherit glean frontend webDeps;
115+ default = glean;
116+ }
117+ # dockerTools images are Linux-only; on darwin the attribute is simply
118+ # absent rather than a derivation that fails at build time.
119+ // nixpkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
120+ image = pkgs.dockerTools.streamLayeredImage {
121+ name = "glean";
122+ tag = "latest";
123+ contents = [ pkgs.cacert pkgs.tzdata pkgs.dockerTools.fakeNss entrypoint ];
124+ config = {
125+ Cmd = [ "${entrypoint}/bin/glean-entrypoint" ];
126+ Env = [ "PORT=3000" ];
127+ ExposedPorts = { "3000/tcp" = { }; };
128+ };
117129 };
130+ });
131+
132+ # `nix run .#glean` runs the API; `nix run .#image > glean-image.tar`
133+ # streams the docker-archive tarball to stdout.
134+ apps = forEachSystem (pkgs:
135+ let
136+ system = pkgs.stdenv.hostPlatform.system;
137+ pkgsFor = self.packages.${system};
138+ in
139+ {
140+ default = { type = "app"; program = "${pkgsFor.glean}/bin/glean"; };
141+ glean = { type = "app"; program = "${pkgsFor.glean}/bin/glean"; };
142+ }
143+ // nixpkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
144+ # streamLayeredImage's output *is* the streaming script.
145+ image = { type = "app"; program = "${pkgsFor.image}"; };
146+ });
147+
148+ # Everything the Makefile targets need: Go with cgo, bun/node for the
149+ # frontend, and the image/lexicon tooling.
150+ devShells = forEachSystem (pkgs: {
151+ default = pkgs.mkShell {
152+ packages = with pkgs; [
153+ go
154+ gcc
155+ gnumake
156+ bun
157+ nodejs_22
158+ sqlite
159+ golangci-lint
160+ rsync
161+ openssh
162+ ];
163+
164+ # Same include flags the Makefile computes, so `go build -tags fts5`
165+ # works inside the shell without the module cache lookup.
166+ shellHook = ''
167+ export CGO_ENABLED=1
168+ export CGO_CFLAGS="-I$PWD/internal/db/include -I$(go env GOMODCACHE)/$(grep 'mattn/go-sqlite3' go.mod | awk '{print $1 "@" $2}')"
169+ '';
118170 };
119- };
171+ });
172+
173+ # `nix flake check` builds the binary and the frontend and runs the Go
174+ # tests.
175+ checks = forEachSystem (pkgs:
176+ let
177+ system = pkgs.stdenv.hostPlatform.system;
178+ in
179+ {
180+ glean = self.packages.${system}.glean;
181+ frontend = self.packages.${system}.frontend;
182+ tests = (mkGlean pkgs).overrideAttrs (_: {
183+ pname = "glean-tests";
184+ doCheck = true;
185+ });
186+ });
187+
188+ formatter = forEachSystem (pkgs: pkgs.nixpkgs-fmt);
120189 };
121190 }
@@ -7,17 +7,17 @@
7 7
8 outputs = { self, nixpkgs }:8 outputs = { self, nixpkgs }:
9 let9 let
10- system = "x86_64-linux";10+ systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
11- pkgs = import nixpkgs { inherit system; };11+ forEachSystem = f: nixpkgs.lib.genAttrs systems (system:
12- lib = pkgs.lib;12+ f (import nixpkgs { inherit system; }));
13 13
14 # --- Go API binary -----------------------------------------------------14 # --- Go API binary -----------------------------------------------------
15- # Mirrors the Dockerfile's CGO setup: mattn/go-sqlite3 vendors its own15+ # Mirrors the historical Dockerfile's CGO setup: mattn/go-sqlite3 vendors
16- # sqlite3 amalgamation, but sqlite-vec-go-bindings' cgo code expects a16+ # its own sqlite3 amalgamation, but sqlite-vec-go-bindings' cgo code
17- # plain `sqlite3.h` on the include path. internal/db/include/sqlite3.h17+ # expects a plain `sqlite3.h` on the include path. internal/db/include/
18- # is that header; go-sqlite3's own module dir is added too so the18+ # sqlite3.h is that header; go-sqlite3's own module dir is added too so
19- # u_intN_t compat defines line up with the same sqlite3 version.19+ # the u_intN_t compat defines line up with the same sqlite3 version.
20- glean = pkgs.buildGoModule {20+ mkGlean = pkgs: pkgs.buildGoModule {
21 pname = "glean";21 pname = "glean";
22 version = "0.0.1";22 version = "0.0.1";
23 src = ./.;23 src = ./.;
@@ -42,7 +42,7 @@
42 # normal derivation -- split into a fixed-output "fetch deps" step42 # normal derivation -- split into a fixed-output "fetch deps" step
43 # (network allowed, output hash pinned) and a sandboxed "build" step43 # (network allowed, output hash pinned) and a sandboxed "build" step
44 # that only ever sees the already-fetched node_modules.44 # that only ever sees the already-fetched node_modules.
45- webDeps = pkgs.stdenvNoCC.mkDerivation {45+ mkWebDeps = pkgs: pkgs.stdenvNoCC.mkDerivation {
46 pname = "glean-web-deps";46 pname = "glean-web-deps";
47 version = "0.0.1";47 version = "0.0.1";
48 src = ./web;48 src = ./web;
@@ -63,7 +63,7 @@
63 outputHash = "sha256-q/VJbH1rWCsxf3A3RYb22t2RrtjUm4xCCrCZkLkAFFY=";63 outputHash = "sha256-q/VJbH1rWCsxf3A3RYb22t2RrtjUm4xCCrCZkLkAFFY=";
64 };64 };
65 65
66- frontend = pkgs.stdenvNoCC.mkDerivation {66+ mkFrontend = pkgs: webDeps: pkgs.stdenvNoCC.mkDerivation {
67 pname = "glean-web";67 pname = "glean-web";
68 version = "0.0.1";68 version = "0.0.1";
69 src = ./web;69 src = ./web;
@@ -92,7 +92,7 @@
92 # Runs both processes the same way the Dockerfile's CMD did: the Go API92 # Runs both processes the same way the Dockerfile's CMD did: the Go API
93 # in the background on loopback:8080, the SvelteKit Node server in front93 # in the background on loopback:8080, the SvelteKit Node server in front
94 # on $PORT, proxying /api to it.94 # on $PORT, proxying /api to it.
95- entrypoint = pkgs.writeShellScriptBin "glean-entrypoint" ''95+ mkEntrypoint = pkgs: glean: frontend: pkgs.writeShellScriptBin "glean-entrypoint" ''
96 set -euo pipefail96 set -euo pipefail
97 export GLEAN_ADDR="127.0.0.1:8080"97 export GLEAN_ADDR="127.0.0.1:8080"
98 export GLEAN_API_URL="http://127.0.0.1:8080"98 export GLEAN_API_URL="http://127.0.0.1:8080"
@@ -103,19 +103,88 @@
103 '';103 '';
104 in104 in
105 {105 {
106- packages.${system} = {106+ packages = forEachSystem (pkgs:
107- inherit glean frontend webDeps;107+ let
108-108+ glean = mkGlean pkgs;
109- image = pkgs.dockerTools.streamLayeredImage {109+ webDeps = mkWebDeps pkgs;
110- name = "glean";110+ frontend = mkFrontend pkgs webDeps;
111- tag = "latest";111+ entrypoint = mkEntrypoint pkgs glean frontend;
112- contents = [ pkgs.cacert pkgs.tzdata pkgs.dockerTools.fakeNss entrypoint ];112+ in
113- config = {113+ {
114- Cmd = [ "${entrypoint}/bin/glean-entrypoint" ];114+ inherit glean frontend webDeps;
115- Env = [ "PORT=3000" ];115+ default = glean;
116- ExposedPorts = { "3000/tcp" = { }; };116+ }
117+ # dockerTools images are Linux-only; on darwin the attribute is simply
118+ # absent rather than a derivation that fails at build time.
119+ // nixpkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
120+ image = pkgs.dockerTools.streamLayeredImage {
121+ name = "glean";
122+ tag = "latest";
123+ contents = [ pkgs.cacert pkgs.tzdata pkgs.dockerTools.fakeNss entrypoint ];
124+ config = {
125+ Cmd = [ "${entrypoint}/bin/glean-entrypoint" ];
126+ Env = [ "PORT=3000" ];
127+ ExposedPorts = { "3000/tcp" = { }; };
128+ };
117 };129 };
130+ });
131+
132+ # `nix run .#glean` runs the API; `nix run .#image > glean-image.tar`
133+ # streams the docker-archive tarball to stdout.
134+ apps = forEachSystem (pkgs:
135+ let
136+ system = pkgs.stdenv.hostPlatform.system;
137+ pkgsFor = self.packages.${system};
138+ in
139+ {
140+ default = { type = "app"; program = "${pkgsFor.glean}/bin/glean"; };
141+ glean = { type = "app"; program = "${pkgsFor.glean}/bin/glean"; };
142+ }
143+ // nixpkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
144+ # streamLayeredImage's output *is* the streaming script.
145+ image = { type = "app"; program = "${pkgsFor.image}"; };
146+ });
147+
148+ # Everything the Makefile targets need: Go with cgo, bun/node for the
149+ # frontend, and the image/lexicon tooling.
150+ devShells = forEachSystem (pkgs: {
151+ default = pkgs.mkShell {
152+ packages = with pkgs; [
153+ go
154+ gcc
155+ gnumake
156+ bun
157+ nodejs_22
158+ sqlite
159+ golangci-lint
160+ rsync
161+ openssh
162+ ];
163+
164+ # Same include flags the Makefile computes, so `go build -tags fts5`
165+ # works inside the shell without the module cache lookup.
166+ shellHook = ''
167+ export CGO_ENABLED=1
168+ export CGO_CFLAGS="-I$PWD/internal/db/include -I$(go env GOMODCACHE)/$(grep 'mattn/go-sqlite3' go.mod | awk '{print $1 "@" $2}')"
169+ '';
118 };170 };
119- };171+ });
172+
173+ # `nix flake check` builds the binary and the frontend and runs the Go
174+ # tests.
175+ checks = forEachSystem (pkgs:
176+ let
177+ system = pkgs.stdenv.hostPlatform.system;
178+ in
179+ {
180+ glean = self.packages.${system}.glean;
181+ frontend = self.packages.${system}.frontend;
182+ tests = (mkGlean pkgs).overrideAttrs (_: {
183+ pname = "glean-tests";
184+ doCheck = true;
185+ });
186+ });
187+
188+ formatter = forEachSystem (pkgs: pkgs.nixpkgs-fmt);
120 };189 };
121 }190 }
modified readme.md +20 -0
@@ -39,12 +39,32 @@ The system improves over time: as you subscribe to feeds and like articles, Glea
3939 docker run -p 3000:3000 -e GLEAN_SESSION_KEY=changeme -v glean-data:/data atcr.io/julien.rbrt.fr/glean:latest
4040 ```
4141
42+The published image is built from this repo's flake — `nix build .#image`
43+produces a script that streams a docker-archive tarball:
44+
45+```bash
46+nix run .#image > glean-image.tar && docker load < glean-image.tar
47+```
48+
49+`make image` wraps that, and falls back to building on a remote nix builder
50+(`$GLEAN_NIX_VM`, default `nix-vm`) when the local machine has no `nix`.
51+
4252 ### From source
4353
4454 The frontend is a SvelteKit app in `web/`; the Go binary serves a JSON API.
4555 SvelteKit runs the SSR server (port 3000) and proxies `/api` to the Go API
4656 (port 8080).
4757
58+Everything is packaged as a nix flake, so with nix installed:
59+
60+```bash
61+nix build .#glean # the Go binary
62+nix build .#frontend # the built SvelteKit app
63+nix develop # a shell with go, gcc, bun, node and the CGO flags set
64+```
65+
66+Without nix, the Makefile does the same thing against your own toolchain:
67+
4868 ```bash
4969 git clone https://github.com/anomalyco/glean.git
5070 cd glean
@@ -39,12 +39,32 @@ The system improves over time: as you subscribe to feeds and like articles, Glea
39 docker run -p 3000:3000 -e GLEAN_SESSION_KEY=changeme -v glean-data:/data atcr.io/julien.rbrt.fr/glean:latest39 docker run -p 3000:3000 -e GLEAN_SESSION_KEY=changeme -v glean-data:/data atcr.io/julien.rbrt.fr/glean:latest
40 ```40 ```
41 41
42+The published image is built from this repo's flake — `nix build .#image`
43+produces a script that streams a docker-archive tarball:
44+
45+```bash
46+nix run .#image > glean-image.tar && docker load < glean-image.tar
47+```
48+
49+`make image` wraps that, and falls back to building on a remote nix builder
50+(`$GLEAN_NIX_VM`, default `nix-vm`) when the local machine has no `nix`.
51+
42 ### From source52 ### From source
43 53
44 The frontend is a SvelteKit app in `web/`; the Go binary serves a JSON API.54 The frontend is a SvelteKit app in `web/`; the Go binary serves a JSON API.
45 SvelteKit runs the SSR server (port 3000) and proxies `/api` to the Go API55 SvelteKit runs the SSR server (port 3000) and proxies `/api` to the Go API
46 (port 8080).56 (port 8080).
47 57
58+Everything is packaged as a nix flake, so with nix installed:
59+
60+```bash
61+nix build .#glean # the Go binary
62+nix build .#frontend # the built SvelteKit app
63+nix develop # a shell with go, gcc, bun, node and the CGO flags set
64+```
65+
66+Without nix, the Makefile does the same thing against your own toolchain:
67+
48 ```bash68 ```bash
49 git clone https://github.com/anomalyco/glean.git69 git clone https://github.com/anomalyco/glean.git
50 cd glean70 cd glean
modified scripts/build-image.sh +20 -16
@@ -1,29 +1,33 @@
11 #!/bin/bash
22 # Builds the glean container image with Nix (pkgs.dockerTools.streamLayeredImage,
3-# defined in flake.nix) on a remote builder over SSH -- this dev machine has no
4-# `nix` installed, so the actual build can't happen locally. Side-effecting (rsync
5-# + ssh) on purpose: buck2's genrule for :image just calls this script and stays
6-# pure/uninvolved in how the remote build actually happens.
3+# defined in flake.nix). If `nix` is available locally the build happens here;
4+# otherwise the repo is rsync'd to a remote builder over SSH and built there,
5+# with the resulting docker-archive tarball streamed back.
76 #
8-# Usage: scripts/build-image.sh <srcdir> <output-tar-path>
7+# Usage: scripts/build-image.sh [output-tar-path] (default: glean-image.tar)
98 set -euo pipefail
10-# $SRCDIR is populated by the genrule's `srcs = glob(...)` as a symlink farm
11-# mirroring the repo tree -- NOT this script's own location (which, after
12-# export_file, is a buck-out copy) and NOT $PWD (buck2 runs genrule cmds with
13-# cwd at a srcs scratch dir, not the project root).
14-DIR="$1"
15-OUT="$2"
9+
10+OUT="${1:-glean-image.tar}"
11+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
12+
13+if command -v nix >/dev/null 2>&1; then
14+ echo "==> building .#image locally" >&2
15+ nix build "$DIR#image" --print-out-paths --no-link -L | {
16+ read -r store_path
17+ echo "==> streaming image (docker-archive tar) to $OUT" >&2
18+ "$store_path" > "$OUT"
19+ }
20+ echo "==> wrote $OUT" >&2
21+ exit 0
22+fi
1623
1724 NIX_VM="${GLEAN_NIX_VM:-nix-vm}"
1825 REMOTE_DIR="${GLEAN_NIX_VM_DIR:-~/builds/glean}"
1926
20-echo "==> syncing source to $NIX_VM:$REMOTE_DIR" >&2
27+echo "==> no local nix; syncing source to $NIX_VM:$REMOTE_DIR" >&2
2128 ssh "$NIX_VM" "mkdir -p $REMOTE_DIR"
22-# -L dereferences $SRCDIR's symlinks (they point back at buck2's srcs farm,
23-# which doesn't exist on the remote host) so real file content gets copied.
24-rsync -aL --delete \
29+rsync -a --delete \
2530 --exclude .git \
26- --exclude buck-out \
2731 --exclude web/node_modules \
2832 --exclude web/.svelte-kit \
2933 --exclude web/build \
@@ -1,29 +1,33 @@
1 #!/bin/bash1 #!/bin/bash
2 # Builds the glean container image with Nix (pkgs.dockerTools.streamLayeredImage,2 # Builds the glean container image with Nix (pkgs.dockerTools.streamLayeredImage,
3-# defined in flake.nix) on a remote builder over SSH -- this dev machine has no3+# defined in flake.nix). If `nix` is available locally the build happens here;
4-# `nix` installed, so the actual build can't happen locally. Side-effecting (rsync4+# otherwise the repo is rsync'd to a remote builder over SSH and built there,
5-# + ssh) on purpose: buck2's genrule for :image just calls this script and stays5+# with the resulting docker-archive tarball streamed back.
6-# pure/uninvolved in how the remote build actually happens.
7 #6 #
8-# Usage: scripts/build-image.sh <srcdir> <output-tar-path>7+# Usage: scripts/build-image.sh [output-tar-path] (default: glean-image.tar)
9 set -euo pipefail8 set -euo pipefail
10-# $SRCDIR is populated by the genrule's `srcs = glob(...)` as a symlink farm9+
11-# mirroring the repo tree -- NOT this script's own location (which, after10+OUT="${1:-glean-image.tar}"
12-# export_file, is a buck-out copy) and NOT $PWD (buck2 runs genrule cmds with11+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
13-# cwd at a srcs scratch dir, not the project root).12+
14-DIR="$1"13+if command -v nix >/dev/null 2>&1; then
15-OUT="$2"14+ echo "==> building .#image locally" >&2
15+ nix build "$DIR#image" --print-out-paths --no-link -L | {
16+ read -r store_path
17+ echo "==> streaming image (docker-archive tar) to $OUT" >&2
18+ "$store_path" > "$OUT"
19+ }
20+ echo "==> wrote $OUT" >&2
21+ exit 0
22+fi
16 23
17 NIX_VM="${GLEAN_NIX_VM:-nix-vm}"24 NIX_VM="${GLEAN_NIX_VM:-nix-vm}"
18 REMOTE_DIR="${GLEAN_NIX_VM_DIR:-~/builds/glean}"25 REMOTE_DIR="${GLEAN_NIX_VM_DIR:-~/builds/glean}"
19 26
20-echo "==> syncing source to $NIX_VM:$REMOTE_DIR" >&227+echo "==> no local nix; syncing source to $NIX_VM:$REMOTE_DIR" >&2
21 ssh "$NIX_VM" "mkdir -p $REMOTE_DIR"28 ssh "$NIX_VM" "mkdir -p $REMOTE_DIR"
22-# -L dereferences $SRCDIR's symlinks (they point back at buck2's srcs farm,29+rsync -a --delete \
23-# which doesn't exist on the remote host) so real file content gets copied.
24-rsync -aL --delete \
25 --exclude .git \30 --exclude .git \
26- --exclude buck-out \
27 --exclude web/node_modules \31 --exclude web/node_modules \
28 --exclude web/.svelte-kit \32 --exclude web/.svelte-kit \
29 --exclude web/build \33 --exclude web/build \
deleted toolchains/BUCK +0 -5
deleted file mode 100644
@@ -1,5 +0,0 @@
1-load("@prelude//toolchains:demo.bzl", "system_demo_toolchains")
2-
3-# All the default toolchains, suitable for a quick demo or early prototyping.
4-# Most real projects should copy/paste the implementation to configure them.
5-system_demo_toolchains()
deleted file mode 100644
@@ -1,5 +0,0 @@
1-load("@prelude//toolchains:demo.bzl", "system_demo_toolchains")
2-
3-# All the default toolchains, suitable for a quick demo or early prototyping.
4-# Most real projects should copy/paste the implementation to configure them.
5-system_demo_toolchains()