about summary refs log tree commit diff
path: root/third_party
diff options
context:
space:
mode:
Diffstat (limited to 'third_party')
-rw-r--r--third_party/cgit/default.nix25
-rw-r--r--third_party/chicago95/default.nix47
-rw-r--r--third_party/exwm/exwm-core.el70
-rw-r--r--third_party/exwm/exwm-floating.el10
-rw-r--r--third_party/exwm/exwm-input.el2
-rw-r--r--third_party/exwm/exwm-layout.el7
-rw-r--r--third_party/exwm/exwm-systemtray.el11
-rw-r--r--third_party/exwm/exwm-workspace.el10
-rw-r--r--third_party/exwm/exwm-xsettings.el2
-rw-r--r--third_party/exwm/exwm.el19
-rw-r--r--third_party/geesefs/default.nix25
-rw-r--r--third_party/gerrit/0001-Syntax-highlight-nix.patch16
-rw-r--r--third_party/gerrit/0002-Syntax-highlight-rules.pl.patch12
-rw-r--r--third_party/gerrit/0003-Add-titles-to-CLs-over-HTTP.patch35
-rw-r--r--third_party/gerrit/bazelrc11
-rw-r--r--third_party/gerrit/default.nix175
-rw-r--r--third_party/gerrit/detzip.go97
-rw-r--r--third_party/gerrit/workspace_overrides.bzl5
-rw-r--r--third_party/gerrit_plugins/builder.nix25
-rw-r--r--third_party/gerrit_plugins/code-owners/default.nix6
-rw-r--r--third_party/gerrit_plugins/oauth/default.nix11
-rw-r--r--third_party/git/default.nix2
-rw-r--r--third_party/gitignoreSource/default.nix12
-rw-r--r--third_party/nixpkgs/default.nix11
-rw-r--r--third_party/overlays/patches/cbtemulator-uds.patch140
-rw-r--r--third_party/overlays/patches/crate2nix-0001-Fix-Use-mkDerivation-with-src-instead-of-runCommand.patch109
-rw-r--r--third_party/overlays/patches/crate2nix-run-tests-in-build-source.patch69
-rw-r--r--third_party/overlays/patches/treefmt-fix-no-cache.patch43
-rw-r--r--third_party/overlays/tvl.nix106
-rw-r--r--third_party/radicle-explorer/0001-remove-dependency-on-plausible.patch78
-rw-r--r--third_party/radicle-explorer/default.nix66
-rw-r--r--third_party/rust-crates/default.nix126
-rw-r--r--third_party/sources/sources.json66
-rw-r--r--third_party/teleirc/default.nix23
34 files changed, 679 insertions, 793 deletions
diff --git a/third_party/cgit/default.nix b/third_party/cgit/default.nix
index c783bda16ed2..bac6a3264e6e 100644
--- a/third_party/cgit/default.nix
+++ b/third_party/cgit/default.nix
@@ -27,12 +27,25 @@ stdenv.mkDerivation rec {
   #
   # TODO(tazjin): Add an assert for this somewhere so we notice it on
   # channel bumps.
-  preBuild = ''
-    rm -rf git # remove submodule dir ...
-    cp -r --no-preserve=ownership,mode ${pkgs.srcOnly depot.third_party.git} git
-    makeFlagsArray+=(prefix="$out" CGIT_SCRIPT_PATH="$out/cgit/")
-    cat tvl-extra.css >> cgit.css
-  '';
+  preBuild =
+    let
+      # we have to give cgit a git with dottime support to build
+      git' = pkgs.git.overrideAttrs (old: {
+        src = pkgs.fetchurl {
+          url = "https://github.com/git/git/archive/refs/tags/v2.44.2.tar.gz";
+          hash = "sha256-3h0LBfAD4MXfZc0tjWQDO81UdbRo3w5C0W7j7rr9m9I=";
+        };
+        patches = (old.patches or [ ]) ++ [
+          ../git/0001-feat-third_party-git-date-add-dottime-format.patch
+        ];
+      });
+    in
+    ''
+      rm -rf git # remove submodule dir ...
+      cp -r --no-preserve=ownership,mode ${pkgs.srcOnly git'} git
+      makeFlagsArray+=(prefix="$out" CGIT_SCRIPT_PATH="$out/cgit/")
+      cat tvl-extra.css >> cgit.css
+    '';
 
   stripDebugList = [ "cgit" ];
 
diff --git a/third_party/chicago95/default.nix b/third_party/chicago95/default.nix
new file mode 100644
index 000000000000..8703ec3548ad
--- /dev/null
+++ b/third_party/chicago95/default.nix
@@ -0,0 +1,47 @@
+# A rendition of everyone's favourite computer theme.
+{ pkgs, ... }:
+
+let
+  # Chicago95 has no GTK-4 theme (because GTK-4 removed important features that
+  # it needs), but there is a project with an approximation.
+  #
+  # This is a bit of a hack, but I inject that project's GTK-4 theme as if it
+  # was a part of Chicago95.
+  #
+  # This other project is GPL-3.0, under which Chicago95 is also distributed.
+  gtk4ProjectSrc = pkgs.fetchFromGitHub {
+    owner = "B00merang-Project";
+    repo = "Windows-95";
+    rev = "055abd7a3608afdcb2ef021732e07020f2b416b2";
+    hash = "sha256:1li6wzyn3y09d188xki1h96pmn4xcx2lklfc4rkiq2y2r22wx7kz";
+  };
+in
+pkgs.stdenvNoCC.mkDerivation {
+  pname = "Chicago95";
+  version = "master";
+
+  src = pkgs.fetchFromGitHub {
+    owner = "grassmunk";
+    repo = "Chicago95";
+    rev = "bdf5cf36a16102aaac297f3de887c601c2b1146f";
+    hash = "sha256:11fsy3bam1rhp1292zflvzmf1432z1p0ncwy3601wl2f8rnvfdfm";
+  };
+
+  # The project has a Makefile, but it's broken in all sorts of ways, so we just
+  # copy the important stuff manually.
+  dontBuild = true;
+  installPhase = ''
+    mkdir -p $out/share/{icons,fonts,themes,sounds,qt5ct/colors}
+
+    cp -r Theme/Chicago95 $out/share/themes
+    cp -r Icons/* $out/share/icons
+    cp -r Cursors/* $out/share/icons
+    cp -r Fonts/* $out/share/fonts
+    cp Extras/Chicago95_qt.conf $out/share/qt5ct/colors
+
+    cp -r ${gtk4ProjectSrc}/gtk-4.0 $out/share/themes/Chicago95
+  '';
+
+  meta.license = pkgs.lib.licenses.gpl3;
+}
+
diff --git a/third_party/exwm/exwm-core.el b/third_party/exwm/exwm-core.el
index e0d644d941ed..a7fdfce71097 100644
--- a/third_party/exwm/exwm-core.el
+++ b/third_party/exwm/exwm-core.el
@@ -82,6 +82,7 @@ Here are some predefined candidates:
 (defvar exwm-input--simulation-keys)
 (defvar exwm-input-line-mode-passthrough)
 (defvar exwm-input-prefix-keys)
+(defvar exwm-workspace--list)
 (declare-function exwm-input--fake-key "exwm-input.el" (event))
 (declare-function exwm-input--on-KeyPress-line-mode "exwm-input.el"
                   (key-press raw-data))
@@ -94,6 +95,8 @@ Here are some predefined candidates:
 (declare-function exwm-manage--kill-buffer-query-function "exwm-manage.el")
 (declare-function exwm-workspace-move-window "exwm-workspace.el"
                   (frame-or-index &optional id))
+(declare-function exwm-workspace-switch "exwm-workspace.el"
+                  (frame-or-index &optional force))
 
 (define-minor-mode exwm-debug
   "Debug-logging enabled if non-nil."
@@ -229,6 +232,14 @@ If CONN is non-nil, use it instead of the value of the variable
       (setq ret-depth depth))
     (list ret-visual ret-depth ret-colormap)))
 
+(defun exwm--mode-name ()
+  "Mode name string used in `exwm-mode' buffers."
+  (let ((name "EXWM"))
+    (if (cl-some (lambda (i) (frame-parameter i 'exwm-urgency))
+                 exwm-workspace--list)
+        (propertize name 'face 'font-lock-warning-face)
+      name)))
+
 ;; Internal variables
 (defvar-local exwm--id nil)               ;window ID
 (defvar-local exwm--configurations nil)   ;initial configurations.
@@ -311,7 +322,7 @@ One of `line-mode' or `char-mode'.")
 ;; Also, inactive entries should be disabled rather than hidden.
 (easy-menu-define exwm-mode-menu exwm-mode-map
   "Menu for `exwm-mode'."
-  '("EXWM"
+  `("EXWM"
     "---"
     "*General*"
     "---"
@@ -336,22 +347,20 @@ One of `line-mode' or `char-mode'.")
     ["Send key" exwm-input-send-next-key (eq exwm--input-mode 'line-mode)]
     ;; This is merely a reference.
     ("Send simulation key" :filter
-     (lambda (&rest _args)
-       (let (result)
-         (maphash
-          (lambda (key value)
-            (when (sequencep key)
-              (setq result (append result
-                                   `([
-                                      ,(format "Send '%s'"
-                                               (key-description value))
-                                      (lambda ()
-                                        (interactive)
-                                        (dolist (i ',value)
-                                          (exwm-input--fake-key i)))
-                                      :keys ,(key-description key)])))))
-          exwm-input--simulation-keys)
-         result)))
+     ,(lambda (&rest _args)
+        (let (result)
+          (maphash
+           (lambda (key value)
+             (when (sequencep key)
+               (setq result (append result
+                                    `([,(format "Send '%s'"
+                                                (key-description value))
+                                       ,(lambda ()
+                                          (interactive)
+                                          (mapc #'exwm-input--fake-key value))
+                                       :keys ,(key-description key)])))))
+           exwm-input--simulation-keys)
+          result)))
 
     ["Define global binding" exwm-input-set-key]
 
@@ -368,26 +377,20 @@ One of `line-mode' or `char-mode'.")
     ["Switch workspace" exwm-workspace-switch]
     ;; Place this entry at bottom to avoid selecting others by accident.
     ("Switch to" :filter
-     (lambda (&rest _args)
-       (mapcar (lambda (i)
-                 `[,(format "Workspace %d" i)
-                   (lambda ()
-                     (interactive)
-                     (exwm-workspace-switch ,i))
-                   (/= ,i exwm-workspace-current-index)])
-               (number-sequence 0 (1- (exwm-workspace--count))))))))
+     ,(lambda (&rest _args)
+        (mapcar (lambda (i)
+                  `[,(format "Workspace %d" i)
+                    ,(lambda ()
+                       (interactive)
+                       (exwm-workspace-switch i))
+                    (/= ,i exwm-workspace-current-index)])
+                (number-sequence 0 (1- (length exwm-workspace--list))))))))
 
 (define-derived-mode exwm-mode nil "EXWM"
   "Major mode for managing X windows.
 
 \\{exwm-mode-map}"
-  ;;
-  (setq mode-name
-        '(:eval (propertize "EXWM" 'face
-                            (when (cl-some (lambda (i)
-                                             (frame-parameter i 'exwm-urgency))
-                                           exwm-workspace--list)
-                              'font-lock-warning-face))))
+  :interactive nil :abbrev-table nil :syntax-table nil
   ;; Change major-mode is not allowed
   (add-hook 'change-major-mode-hook #'kill-buffer nil t)
   ;; Kill buffer -> close window
@@ -396,7 +399,8 @@ One of `line-mode' or `char-mode'.")
   ;; Redirect events when executing keyboard macros.
   (push `(executing-kbd-macro . ,exwm--kmacro-map)
         minor-mode-overriding-map-alist)
-  (setq buffer-read-only t
+  (setq mode-name '(:eval (exwm--mode-name))
+        buffer-read-only t
         cursor-type nil
         left-margin-width nil
         right-margin-width nil
diff --git a/third_party/exwm/exwm-floating.el b/third_party/exwm/exwm-floating.el
index 34d06a30db09..574a78f01562 100644
--- a/third_party/exwm/exwm-floating.el
+++ b/third_party/exwm/exwm-floating.el
@@ -67,11 +67,11 @@ This hook runs in the context of the corresponding buffer."
 
 (defcustom exwm-floating-border-width 1
   "Border width of floating windows."
-  :type '(integer
-          :validate (lambda (widget)
-                      (when (< (widget-value widget) 0)
-                        (widget-put widget :error "Border width is at least 0")
-                        widget)))
+  :type `(integer
+          :validate ,(lambda (widget)
+                       (when (< (widget-value widget) 0)
+                         (widget-put widget :error "Border width is at least 0")
+                         widget)))
   :initialize #'custom-initialize-default
   :set (lambda (symbol value)
          (let ((delta (- value exwm-floating-border-width))
diff --git a/third_party/exwm/exwm-input.el b/third_party/exwm/exwm-input.el
index f1f035c91ad9..eac0ef6a374e 100644
--- a/third_party/exwm/exwm-input.el
+++ b/third_party/exwm/exwm-input.el
@@ -46,7 +46,7 @@
   '(?\C-x ?\C-u ?\C-h ?\M-x ?\M-` ?\M-& ?\M-:)
   "List of prefix keys EXWM should forward to Emacs when in `line-mode'.
 
-The point is to make keys like 'C-x C-f' forwarded to Emacs in `line-mode'.
+The point is to make keys like `C-x C-f' forwarded to Emacs in `line-mode'.
 There is no need to add prefix keys for global/simulation keys or those
 defined in `exwm-mode-map' here."
   :type '(repeat key-sequence)
diff --git a/third_party/exwm/exwm-layout.el b/third_party/exwm/exwm-layout.el
index 8649c11ffd42..83421b2e9975 100644
--- a/third_party/exwm/exwm-layout.el
+++ b/third_party/exwm/exwm-layout.el
@@ -602,9 +602,7 @@ See also `exwm-layout-enlarge-window'."
   ;; Auto refresh layout
   (exwm--log)
   (add-hook 'window-configuration-change-hook #'exwm-layout--refresh)
-  ;; The behavior of `window-configuration-change-hook' will be changed.
-  (when (fboundp 'window-pixel-width-before-size-change)
-    (add-hook 'window-size-change-functions #'exwm-layout--refresh))
+  (add-hook 'window-size-change-functions #'exwm-layout--refresh)
   (unless (exwm-workspace--minibuffer-own-frame-p)
     ;; Refresh when minibuffer grows
     (add-hook 'minibuffer-setup-hook #'exwm-layout--on-minibuffer-setup t)
@@ -616,8 +614,7 @@ See also `exwm-layout-enlarge-window'."
   "Exit the layout module."
   (exwm--log)
   (remove-hook 'window-configuration-change-hook #'exwm-layout--refresh)
-  (when (fboundp 'window-pixel-width-before-size-change)
-    (remove-hook 'window-size-change-functions #'exwm-layout--refresh))
+  (remove-hook 'window-size-change-functions #'exwm-layout--refresh)
   (remove-hook 'minibuffer-setup-hook #'exwm-layout--on-minibuffer-setup)
   (when exwm-layout--timer
     (cancel-timer exwm-layout--timer)
diff --git a/third_party/exwm/exwm-systemtray.el b/third_party/exwm/exwm-systemtray.el
index 9e57dae4ebb8..2b46568152b4 100644
--- a/third_party/exwm/exwm-systemtray.el
+++ b/third_party/exwm/exwm-systemtray.el
@@ -46,15 +46,6 @@
    (visible :initarg :visible))
   :documentation "Attributes of a system tray icon.")
 
-(defclass xcb:systemtray:-ClientMessage
-  (xcb:icccm:--ClientMessage xcb:ClientMessage)
-  ((format :initform 32)
-   (type :initform 'xcb:Atom:MANAGER)
-   (time :initarg :time :type xcb:TIMESTAMP)      ;new slot
-   (selection :initarg :selection :type xcb:ATOM) ;new slot
-   (owner :initarg :owner :type xcb:WINDOW))      ;new slot
-  :documentation "A systemtray client message.")
-
 (defgroup exwm-systemtray nil
   "System tray."
   :group 'exwm)
@@ -542,7 +533,7 @@ Argument DATA contains the raw event data."
                        :destination exwm--root
                        :event-mask xcb:EventMask:StructureNotify
                        :event (xcb:marshal
-                               (make-instance 'xcb:systemtray:-ClientMessage
+                               (make-instance 'xcb:icccm:-ManagerSelection
                                               :window exwm--root
                                               :time xcb:Time:CurrentTime
                                               :selection
diff --git a/third_party/exwm/exwm-workspace.el b/third_party/exwm/exwm-workspace.el
index 89be6971598c..9337dc08ab8e 100644
--- a/third_party/exwm/exwm-workspace.el
+++ b/third_party/exwm/exwm-workspace.el
@@ -1257,12 +1257,10 @@ ALIST is an action alist, as accepted by function `display-buffer'."
   ;;        fail to retrieve the correct window.  It's likely there are
   ;;        other related issues.
   ;; This is not required by Emacs 24.
-  (when (fboundp 'window-preserve-size)
-    (let ((window (get-buffer-window "*Completions*"
-                                     exwm-workspace--current)))
-      (when window
-        (fit-window-to-buffer window)
-        (window-preserve-size window)))))
+  (let ((window (get-buffer-window "*Completions*" exwm-workspace--current)))
+    (when window
+      (fit-window-to-buffer window)
+      (window-preserve-size window))))
 
 (defun exwm-workspace--on-minibuffer-exit ()
   "Run in `minibuffer-exit-hook' to hide the minibuffer container."
diff --git a/third_party/exwm/exwm-xsettings.el b/third_party/exwm/exwm-xsettings.el
index 99d6b9c4ac87..596588b8237c 100644
--- a/third_party/exwm/exwm-xsettings.el
+++ b/third_party/exwm/exwm-xsettings.el
@@ -293,7 +293,7 @@ SERIAL is a sequence number."
                        :destination exwm--root
                        :event-mask xcb:EventMask:StructureNotify
                        :event (xcb:marshal
-                               (make-instance 'xcb:xsettings:-ClientMessage
+                               (make-instance 'xcb:icccm:-ManagerSelection
                                               :window exwm--root
                                               :time xcb:Time:CurrentTime
                                               :selection exwm-xsettings--XSETTINGS_S0-atom
diff --git a/third_party/exwm/exwm.el b/third_party/exwm/exwm.el
index c4900eab48ca..1186a40f441d 100644
--- a/third_party/exwm/exwm.el
+++ b/third_party/exwm/exwm.el
@@ -4,8 +4,8 @@
 
 ;; Author: Chris Feng <chris.w.feng@gmail.com>
 ;; Maintainer: Adrián Medraño Calvo <adrian@medranocalvo.com>, Steven Allen <steven@stebalien.com>, Daniel Mendler <mail@daniel-mendler.de>
-;; Version: 0.28
-;; Package-Requires: ((emacs "27.1") (xelb "0.18"))
+;; Version: 0.30
+;; Package-Requires: ((emacs "27.1") (xelb "0.19"))
 ;; Keywords: unix
 ;; URL: https://github.com/emacs-exwm/exwm
 
@@ -493,23 +493,20 @@ RAW-DATA contains unmarshalled ClientMessage event data."
      ;; _NET_ACTIVE_WINDOW.
      ((= type xcb:Atom:_NET_ACTIVE_WINDOW)
       (let ((buffer (exwm--id->buffer id))
-            iconic window)
+            window)
         (if (buffer-live-p buffer)
           ;; Either an `exwm-mode' buffer (an X window) or a floating frame.
           (with-current-buffer buffer
             (when (eq exwm--frame exwm-workspace--current)
               (if exwm--floating-frame
                   (select-frame exwm--floating-frame)
-                (setq iconic (exwm-layout--iconic-state-p))
-                (when iconic
+                (setq window (get-buffer-window nil t))
+                (unless window
                   ;; State change: iconic => normal.
-                  (set-window-buffer (frame-selected-window exwm--frame)
-                                     (current-buffer)))
+                  (setq window (frame-selected-window exwm--frame))
+                  (set-window-buffer window (current-buffer)))
                 ;; Focus transfer.
-                (setq window (get-buffer-window nil t))
-                (when (or iconic
-                          (not (eq window (selected-window))))
-                  (select-window window)))))
+                (select-window window))))
           ;; A workspace.
           (dolist (f exwm-workspace--list)
             (when (eq id (frame-parameter f 'exwm-outer-id))
diff --git a/third_party/geesefs/default.nix b/third_party/geesefs/default.nix
deleted file mode 100644
index 98448bb737c6..000000000000
--- a/third_party/geesefs/default.nix
+++ /dev/null
@@ -1,25 +0,0 @@
-# Finally, a good FUSE FS implementation over S3.
-# https://github.com/yandex-cloud/geesefs
-
-{ pkgs, ... }:
-
-pkgs.buildGoModule rec {
-  pname = "geesefs";
-  version = "0.40.1";
-
-  src = pkgs.fetchFromGitHub {
-    owner = "yandex-cloud";
-    repo = "geesefs";
-    rev = "v${version}";
-    hash = "sha256:0ig8h17z8n5j8qb7k2jyh40vv77zazhnz8bxdam9xihxksj8mizp";
-  };
-
-  subPackages = [ "." ];
-  buildInputs = [ pkgs.fuse ];
-  vendorHash = "sha256:11i7cmnlxi00d0csgpv8drfcw0aqshwc4hfs0jw7zwafdhnlyy0j";
-
-  meta = with pkgs.lib; {
-    license = licenses.asl20;
-    maintainers = [ maintainers.tazjin ];
-  };
-}
diff --git a/third_party/gerrit/0001-Syntax-highlight-nix.patch b/third_party/gerrit/0001-Syntax-highlight-nix.patch
index bdc3fd3b5510..d17dc27db094 100644
--- a/third_party/gerrit/0001-Syntax-highlight-nix.patch
+++ b/third_party/gerrit/0001-Syntax-highlight-nix.patch
@@ -1,4 +1,4 @@
-From 084e4f92fb58f7cd85303ba602fb3c40133c8fcc Mon Sep 17 00:00:00 2001
+From 216843cff4a8e41ad9887118751a412c1a22ce72 Mon Sep 17 00:00:00 2001
 From: Luke Granger-Brown <git@lukegb.com>
 Date: Thu, 2 Jul 2020 23:02:32 +0100
 Subject: [PATCH 1/3] Syntax highlight nix
@@ -9,23 +9,23 @@ Subject: [PATCH 1/3] Syntax highlight nix
  2 files changed, 2 insertions(+)
 
 diff --git a/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts b/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts
-index a9f88bdd81..385249f280 100644
+index 50742903de..d1e89920cc 100644
 --- a/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts
 +++ b/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts
-@@ -93,6 +93,7 @@ const LANGUAGE_MAP = new Map<string, string>([
+@@ -98,6 +98,7 @@ const LANGUAGE_MAP = new Map<string, string>([
    ['text/x-vhdl', 'vhdl'],
    ['text/x-yaml', 'yaml'],
    ['text/vbscript', 'vbscript'],
 +  ['text/x-nix', 'nix'],
  ]);
  
- const CLASS_PREFIX = 'gr-diff gr-syntax gr-syntax-';
+ const CLASS_PREFIX = 'gr-syntax gr-syntax-';
 diff --git a/resources/com/google/gerrit/server/mime/mime-types.properties b/resources/com/google/gerrit/server/mime/mime-types.properties
-index 2f9561ba2e..739818ec05 100644
+index 642ef474a5..97f1ff835b 100644
 --- a/resources/com/google/gerrit/server/mime/mime-types.properties
 +++ b/resources/com/google/gerrit/server/mime/mime-types.properties
-@@ -149,6 +149,7 @@ mscin = text/x-mscgen
- msgenny = text/x-msgenny
+@@ -154,6 +154,7 @@ msgenny = text/x-msgenny
+ mts = application/typescript
  nb = text/x-mathematica
  nginx.conf = text/x-nginx-conf
 +nix = text/x-nix
@@ -33,5 +33,5 @@ index 2f9561ba2e..739818ec05 100644
  nsi = text/x-nsis
  nt = text/n-triples
 -- 
-2.37.3
+2.45.1
 
diff --git a/third_party/gerrit/0002-Syntax-highlight-rules.pl.patch b/third_party/gerrit/0002-Syntax-highlight-rules.pl.patch
index 4b91e2c3541f..d0da61dd0f21 100644
--- a/third_party/gerrit/0002-Syntax-highlight-rules.pl.patch
+++ b/third_party/gerrit/0002-Syntax-highlight-rules.pl.patch
@@ -1,4 +1,4 @@
-From aedf8ac8fa5113843bcd83ff85e2d9f3bffdb16c Mon Sep 17 00:00:00 2001
+From 63f1ff6ea749ae2af29a53463bca81bc3f4bf25b Mon Sep 17 00:00:00 2001
 From: Luke Granger-Brown <git@lukegb.com>
 Date: Thu, 2 Jul 2020 23:02:43 +0100
 Subject: [PATCH 2/3] Syntax highlight rules.pl
@@ -9,10 +9,10 @@ Subject: [PATCH 2/3] Syntax highlight rules.pl
  2 files changed, 2 insertions(+)
 
 diff --git a/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts b/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts
-index 385249f280..7cb3068494 100644
+index d1e89920cc..5d62af1c64 100644
 --- a/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts
 +++ b/polygerrit-ui/app/embed/diff/gr-syntax-layer/gr-syntax-layer-worker.ts
-@@ -68,6 +68,7 @@ const LANGUAGE_MAP = new Map<string, string>([
+@@ -72,6 +72,7 @@ const LANGUAGE_MAP = new Map<string, string>([
    ['text/x-perl', 'perl'],
    ['text/x-pgsql', 'pgsql'], // postgresql
    ['text/x-php', 'php'],
@@ -21,10 +21,10 @@ index 385249f280..7cb3068494 100644
    ['text/x-protobuf', 'protobuf'],
    ['text/x-puppet', 'puppet'],
 diff --git a/resources/com/google/gerrit/server/mime/mime-types.properties b/resources/com/google/gerrit/server/mime/mime-types.properties
-index 739818ec05..58eb727bf9 100644
+index 97f1ff835b..85d630340f 100644
 --- a/resources/com/google/gerrit/server/mime/mime-types.properties
 +++ b/resources/com/google/gerrit/server/mime/mime-types.properties
-@@ -200,6 +200,7 @@ rq = application/sparql-query
+@@ -208,6 +208,7 @@ rq = application/sparql-query
  rs = text/x-rustsrc
  rss = application/xml
  rst = text/x-rst
@@ -33,5 +33,5 @@ index 739818ec05..58eb727bf9 100644
  s = text/x-gas
  sas = text/x-sas
 -- 
-2.37.3
+2.45.1
 
diff --git a/third_party/gerrit/0003-Add-titles-to-CLs-over-HTTP.patch b/third_party/gerrit/0003-Add-titles-to-CLs-over-HTTP.patch
index c4edee3a40c3..a5881e5a6c27 100644
--- a/third_party/gerrit/0003-Add-titles-to-CLs-over-HTTP.patch
+++ b/third_party/gerrit/0003-Add-titles-to-CLs-over-HTTP.patch
@@ -1,19 +1,19 @@
-From f49c50ca9a84ca374b7bd91c171bbea0457f2c7a Mon Sep 17 00:00:00 2001
+From ca2df6d7f53441d443d42908e30bf60fbfc15392 Mon Sep 17 00:00:00 2001
 From: Luke Granger-Brown <git@lukegb.com>
 Date: Thu, 2 Jul 2020 23:03:02 +0100
 Subject: [PATCH 3/3] Add titles to CLs over HTTP
 
 ---
- .../gerrit/httpd/raw/IndexHtmlUtil.java       | 13 +++-
+ .../gerrit/httpd/raw/IndexHtmlUtil.java       | 12 +++-
  .../google/gerrit/httpd/raw/IndexServlet.java |  8 ++-
  .../google/gerrit/httpd/raw/StaticModule.java |  5 +-
  .../gerrit/httpd/raw/TitleComputer.java       | 67 +++++++++++++++++++
  .../gerrit/httpd/raw/PolyGerritIndexHtml.soy  |  4 +-
- 5 files changed, 89 insertions(+), 8 deletions(-)
+ 5 files changed, 88 insertions(+), 8 deletions(-)
  create mode 100644 java/com/google/gerrit/httpd/raw/TitleComputer.java
 
 diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
-index 72bfe40c3b..439bd73b44 100644
+index a92dd18f04..f87c46d321 100644
 --- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 +++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 @@ -41,6 +41,7 @@ import java.util.Collections;
@@ -24,7 +24,7 @@ index 72bfe40c3b..439bd73b44 100644
  import java.util.Set;
  import java.util.function.Function;
  
-@@ -62,13 +63,14 @@ public class IndexHtmlUtil {
+@@ -63,13 +64,14 @@ public class IndexHtmlUtil {
        String faviconPath,
        Map<String, String[]> urlParameterMap,
        Function<String, SanitizedContent> urlInScriptTagOrdainer,
@@ -36,22 +36,21 @@ index 72bfe40c3b..439bd73b44 100644
      data.putAll(
              staticTemplateData(
                  canonicalURL, cdnPath, faviconPath, urlParameterMap, urlInScriptTagOrdainer))
--        .putAll(dynamicTemplateData(gerritApi, requestedURL));
-+        .putAll(dynamicTemplateData(gerritApi, requestedURL, titleComputer));
+-        .putAll(dynamicTemplateData(gerritApi, requestedURL, canonicalURL));
++        .putAll(dynamicTemplateData(gerritApi, requestedURL, canonicalURL, titleComputer));
      Set<String> enabledExperiments = new HashSet<>();
      enabledExperiments.addAll(experimentFeatures.getEnabledExperimentFeatures());
      // Add all experiments enabled through url
-@@ -81,7 +83,8 @@ public class IndexHtmlUtil {
+@@ -82,7 +84,7 @@ public class IndexHtmlUtil {
  
    /** Returns dynamic parameters of {@code index.html}. */
    public static ImmutableMap<String, Object> dynamicTemplateData(
--      GerritApi gerritApi, String requestedURL) throws RestApiException, URISyntaxException {
-+      GerritApi gerritApi, String requestedURL, TitleComputer titleComputer)
-+                throws RestApiException, URISyntaxException {
+-      GerritApi gerritApi, String requestedURL, String canonicalURL)
++      GerritApi gerritApi, String requestedURL, String canonicalURL, TitleComputer titleComputer)
+       throws RestApiException, URISyntaxException {
      ImmutableMap.Builder<String, Object> data = ImmutableMap.builder();
      Map<String, SanitizedContent> initialData = new HashMap<>();
-     Server serverApi = gerritApi.config().server();
-@@ -129,6 +132,10 @@ public class IndexHtmlUtil {
+@@ -141,6 +143,10 @@ public class IndexHtmlUtil {
      }
  
      data.put("gerritInitialData", initialData);
@@ -102,17 +101,17 @@ index fcb821e5ae..e1464b992b 100644
      } catch (URISyntaxException | RestApiException e) {
        throw new IOException(e);
 diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java
-index 15dcf42e0e..9f56bf33ce 100644
+index b00294f73e..f1c1aae12c 100644
 --- a/java/com/google/gerrit/httpd/raw/StaticModule.java
 +++ b/java/com/google/gerrit/httpd/raw/StaticModule.java
-@@ -241,10 +241,11 @@ public class StaticModule extends ServletModule {
+@@ -224,10 +224,11 @@ public class StaticModule extends ServletModule {
          @CanonicalWebUrl @Nullable String canonicalUrl,
          @GerritServerConfig Config cfg,
          GerritApi gerritApi,
 -        ExperimentFeatures experimentFeatures) {
 +        ExperimentFeatures experimentFeatures,
 +        TitleComputer titleComputer) {
-       String cdnPath = options.devCdn().orElse(cfg.getString("gerrit", null, "cdnPath"));
+       String cdnPath = options.devCdn().orElseGet(() -> cfg.getString("gerrit", null, "cdnPath"));
        String faviconPath = cfg.getString("gerrit", null, "faviconPath");
 -      return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi, experimentFeatures);
 +      return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi, experimentFeatures, titleComputer);
@@ -193,7 +192,7 @@ index 0000000000..8fd2053ad0
 +  }
 +}
 diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
-index dbfef44dfe..347ee75aab 100644
+index 5ff1822cd9..81c3cdf0e1 100644
 --- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 +++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 @@ -33,10 +33,12 @@
@@ -211,5 +210,5 @@ index dbfef44dfe..347ee75aab 100644
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">{\n}
  
 -- 
-2.37.3
+2.45.1
 
diff --git a/third_party/gerrit/bazelrc b/third_party/gerrit/bazelrc
new file mode 100644
index 000000000000..f77da77b46ee
--- /dev/null
+++ b/third_party/gerrit/bazelrc
@@ -0,0 +1,11 @@
+# Not using common --repository_cache because Gerrit's bazelrc overrides this...
+build --repository_cache=repository-cache
+build --action_env=SSL_CERT_FILE
+build --action_env=GERRIT_CACHE_HOME
+build --tool_java_runtime_version=local_jdk --java_runtime_version=local_jdk
+build --workspace_status_command="cat .version"
+
+# Disable errorprone
+build --javacopt="-XepDisableAllChecks"
+
+sync --repository_cache=repository-cache
diff --git a/third_party/gerrit/default.nix b/third_party/gerrit/default.nix
index a137946264ed..fdf4a8d9d460 100644
--- a/third_party/gerrit/default.nix
+++ b/third_party/gerrit/default.nix
@@ -1,41 +1,33 @@
 { depot, pkgs, ... }:
 
 let
-  bazelRunScript = pkgs.writeShellScriptBin "bazel-run" ''
-    yarn config set cache-folder "$bazelOut/external/yarn_cache"
-    export HOME="$bazelOut/external/home"
-    mkdir -p "$bazelOut/external/home"
-    exec /bin/bazel "$@"
-  '';
-  bazelTop = pkgs.buildFHSUserEnv {
-    name = "bazel";
-    targetPkgs = pkgs: [
-      (pkgs.bazel_5.override { enableNixHacks = true; })
-      pkgs.jdk17_headless
-      pkgs.zlib
-      pkgs.python3
-      pkgs.curl
-      pkgs.nodejs
-      pkgs.yarn
-      pkgs.git
-      bazelRunScript
-    ];
-    runScript = "/bin/bazel-run";
-  };
-  bazel = bazelTop // { override = x: bazelTop; };
-  version = "3.9.1";
+  inherit (depot.nix) buildBazelPackageNG;
+  inherit (buildBazelPackageNG) bazelRulesJavaHook bazelRulesNodeJS5Hook;
 in
-pkgs.lib.makeOverridable pkgs.buildBazelPackage {
+pkgs.lib.makeOverridable depot.nix.buildBazelPackageNG rec {
   pname = "gerrit";
-  inherit version;
+  version = "3.10.0";
 
-  src = pkgs.fetchgit {
+  bazel = pkgs.bazel_7;
+
+  src = (pkgs.fetchgit {
     url = "https://gerrit.googlesource.com/gerrit";
-    rev = "620a819cbf3c64fff7a66798822775ad42c91d8e";
-    branchName = "v${version}";
-    sha256 = "sha256:1mdxbgnx3mpxand4wq96ic38bb4yh45q271h40jrk7dk23sgmz02";
+    rev = "v${version}";
     fetchSubmodules = true;
-  };
+    deepClone = true;
+    hash = "sha256-FpKuzityHuHNYBIOL8YUjCLlkuVBfxjvHECb26NsZNE=";
+  }).overrideAttrs (_: {
+    env.NIX_PREFETCH_GIT_CHECKOUT_HOOK = ''
+      pushd "$dir" >/dev/null
+      ${pkgs.python3}/bin/python tools/workspace_status_release.py | sort > .version
+      popd >/dev/null
+
+      # delete all the .git; we can't do this using fetchgit if deepClone is on,
+      # but our mischief has already been achieved by the python command above :)
+      find "$dir" -name .git -print0 | xargs -0 rm -rf
+    '';
+  });
+  depsHash = "sha256-OS2kLXjtuWf+XRyQO2qGvEaAOvxqu20+gXR+fsCvpMc=";
 
   patches = [
     ./0001-Syntax-highlight-nix.patch
@@ -43,97 +35,52 @@ pkgs.lib.makeOverridable pkgs.buildBazelPackage {
     ./0003-Add-titles-to-CLs-over-HTTP.patch
   ];
 
-  bazelTargets = [ "release" "api-skip-javadoc" ];
-  inherit bazel;
+  nativeBuildInputs = with pkgs; [
+    bazelRulesJavaHook
+    bazelRulesNodeJS5Hook
 
-  bazelFlags = [
-    "--repository_cache="
-    "--disk_cache="
+    curl
+    jdk
+    python3
+    unzip
   ];
 
-  removeRulesCC = false;
-  fetchConfigured = true;
+  prePatch = ''
+    rm .bazelversion
 
-  fetchAttrs = {
-    sha256 = "sha256:119mqli75c9fy05ddrlh2brjxb354yvv1ijjkk1y1yqcaqppwwb8";
-    preBuild = ''
-      rm .bazelversion
-    '';
+    ln -sf ${./bazelrc} user.bazelrc
 
-    installPhase = ''
-      runHook preInstall
-
-      # Remove all built in external workspaces, Bazel will recreate them when building
-      rm -rf $bazelOut/external/{bazel_tools,\@bazel_tools.marker}
-      rm -rf $bazelOut/external/{embedded_jdk,\@embedded_jdk.marker}
-      rm -rf $bazelOut/external/{local_config_cc,\@local_config_cc.marker}
-      rm -rf $bazelOut/external/{local_*,\@local_*.marker}
-
-      # Clear markers
-      find $bazelOut/external -name '@*\.marker' -exec sh -c 'echo > {}' \;
-
-      # Remove all vcs files
-      rm -rf $(find $bazelOut/external -type d -name .git)
-      rm -rf $(find $bazelOut/external -type d -name .svn)
-      rm -rf $(find $bazelOut/external -type d -name .hg)
-
-      # Removing top-level symlinks along with their markers.
-      # This is needed because they sometimes point to temporary paths (?).
-      # For example, in Tensorflow-gpu build:
-      #sha256:06bmzbcb9717s4b016kcbn8nr9pgaz04i8bnzg7ybkbdwpl8vxvv"; platforms -> NIX_BUILD_TOP/tmp/install/35282f5123611afa742331368e9ae529/_embedded_binaries/platforms
-      find $bazelOut/external -maxdepth 1 -type l | while read symlink; do
-        name="$(basename "$symlink")"
-        rm -rf "$symlink" "$bazelOut/external/@$name.marker"
-      done
-
-      # Patching symlinks to remove build directory reference
-      find $bazelOut/external -type l | while read symlink; do
-        new_target="$(readlink "$symlink" | sed "s,$NIX_BUILD_TOP,NIX_BUILD_TOP,")"
-        rm "$symlink"
-        ln -sf "$new_target" "$symlink"
-      done
-
-      echo '${bazel.name}' > $bazelOut/external/.nix-bazel-version
-
-      # Gerrit fixups:
-      # Normalize permissions on .yarn-{tarball,metadata} files
-      test -d $bazelOut/external/yarn_cache && find $bazelOut/external/yarn_cache \( -name .yarn-tarball.tgz -or -name .yarn-metadata.json \) -exec chmod 644 {} +
-
-      mkdir $bazelOut/_bits/
-      find . -name node_modules -prune -print | while read d; do
-        echo "$d" "$(dirname $d)"
-        mkdir -p $bazelOut/_bits/$(dirname $d)
-        cp -R "$d" "$bazelOut/_bits/$(dirname $d)/node_modules"
-      done
-
-      (cd $bazelOut/ && tar czf $out --sort=name --mtime='@1' --owner=0 --group=0 --numeric-owner external/ _bits/)
-
-      runHook postInstall
-    '';
-  };
+    ln -sf ${./workspace_overrides.bzl} workspace_overrides.bzl
+    substituteInPlace WORKSPACE \
+      --replace-fail 'load("@io_bazel_rules_webtesting//web:repositories.bzl"' 'load("//:workspace_overrides.bzl"' \
+      --replace-fail 'load("@io_bazel_rules_webtesting//web/versioned:browsers-0.3.3.bzl"' 'load("//:workspace_overrides.bzl"'
 
-  buildAttrs = {
-    preConfigure = ''
-      rm .bazelversion
+    patchShebangs Documentation/replace_macros.py
+  '';
 
-      [ "$(ls -A $bazelOut/_bits)" ] && cp -R $bazelOut/_bits/* ./ || true
-    '';
-    postPatch = ''
-      # Disable all errorprone checks, since we might be using a different version.
-      sed -i \
-        -e '/-Xep:/d' \
-        -e '/-XepExcludedPaths:/a "-XepDisableAllChecks",' \
-        tools/BUILD
-    '';
-    installPhase = ''
-      mkdir -p "$out"/webapps/ "$out"/share/api/
-      cp bazel-bin/release.war "$out"/webapps/gerrit-${version}.war
-      unzip bazel-bin/api-skip-javadoc.zip -d "$out"/share/api
-    '';
+  postPatch = ''
+    sed -Ei 's,^(STABLE_BUILD_GERRIT_LABEL.*)$,\1-dirty-nix,' .version
+  '';
 
-    nativeBuildInputs = with pkgs; [
-      unzip
-    ];
+  preBuild = ''
+    export GERRIT_CACHE_HOME=$HOME/gerrit-cache
+  '';
+
+  extraCacheInstall = ''
+    cp -R $GERRIT_CACHE_HOME $out/gerrit-cache
+  '';
+
+  extraBuildSetup = ''
+    ln -sf $cache/gerrit-cache $GERRIT_CACHE_HOME
+  '';
+  extraBuildInstall = ''
+    mkdir -p "$out"/share/api/
+    unzip bazel-bin/api-skip-javadoc.zip -d "$out"/share/api
+  '';
+
+  bazelTargets = {
+    "//:release" = "$out/webapps/gerrit-${version}.war";
+    "//:api-skip-javadoc" = null;
   };
 
   passthru = {
@@ -154,5 +101,5 @@ pkgs.lib.makeOverridable pkgs.buildBazelPackage {
     ];
   };
 
-  meta.ci.targets = [ "deps" ];
+  meta.ci.targets = [ "cache" ];
 }
diff --git a/third_party/gerrit/detzip.go b/third_party/gerrit/detzip.go
deleted file mode 100644
index 511c18ecfe17..000000000000
--- a/third_party/gerrit/detzip.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package main
-
-import (
-	"archive/zip"
-	"flag"
-	"fmt"
-	"io"
-	"log"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-)
-
-var (
-	exclude = flag.String("exclude", "", "comma-separated list of filenames to exclude (in any directory)")
-)
-
-func init() {
-	flag.Usage = func() {
-		fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s [zip file] [directory]:\n", os.Args[0])
-		flag.PrintDefaults()
-	}
-}
-
-func listToMap(ss []string) map[string]bool {
-	m := make(map[string]bool)
-	for _, s := range ss {
-		m[s] = true
-	}
-	return m
-}
-
-func main() {
-	flag.Parse()
-	if flag.NArg() != 2 {
-		flag.Usage()
-		os.Exit(1)
-	}
-
-	outPath := flag.Arg(0)
-	dirPath := flag.Arg(1)
-
-	excludeFiles := listToMap(strings.Split(*exclude, ","))
-
-	// Aggregate all files first.
-	var files []string
-	filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
-		if err != nil {
-			return err
-		}
-		if info.IsDir() {
-			return nil
-		}
-		if excludeFiles[info.Name()] {
-			return nil
-		}
-		files = append(files, path)
-		return nil
-	})
-
-	// Create zip
-	outW, err := os.Create(outPath)
-	if err != nil {
-		log.Fatalf("Create(%q): %v", outPath, err)
-	}
-
-	zipW := zip.NewWriter(outW)
-
-	// Output files in alphabetical order
-	sort.Strings(files)
-	for _, f := range files {
-		fw, err := zipW.CreateHeader(&zip.FileHeader{
-			Name:   f,
-			Method: zip.Store,
-		})
-		if err != nil {
-			log.Fatalf("creating %q in zip: %v", f, err)
-		}
-
-		ff, err := os.Open(f)
-		if err != nil {
-			log.Fatalf("opening %q: %v", f, err)
-		}
-		if _, err := io.Copy(fw, ff); err != nil {
-			log.Fatalf("copying %q to zip: %v", f, err)
-		}
-		ff.Close()
-	}
-
-	if err := zipW.Close(); err != nil {
-		log.Fatalf("writing ZIP central directory: %v", err)
-	}
-	if err := outW.Close(); err != nil {
-		log.Fatalf("closing ZIP file: %v", err)
-	}
-}
diff --git a/third_party/gerrit/workspace_overrides.bzl b/third_party/gerrit/workspace_overrides.bzl
new file mode 100644
index 000000000000..839368606557
--- /dev/null
+++ b/third_party/gerrit/workspace_overrides.bzl
@@ -0,0 +1,5 @@
+def web_test_repositories():
+    pass
+
+def browser_repositories(*args, **kwargs):
+    pass
diff --git a/third_party/gerrit_plugins/builder.nix b/third_party/gerrit_plugins/builder.nix
index 50a4e78ae7cf..a478dfe5d71d 100644
--- a/third_party/gerrit_plugins/builder.nix
+++ b/third_party/gerrit_plugins/builder.nix
@@ -2,30 +2,33 @@
 {
   buildGerritBazelPlugin =
     { name
+    , version
     , src
-    , depsOutputHash
+    , depsHash ? null
     , overlayPluginCmd ? ''
         cp -R "${src}" "$out/plugins/${name}"
+        echo "STABLE_BUILD_${lib.toUpper name}_LABEL v${version}-nix${if patches != [] then "-dirty" else ""}" >> $out/.version
       ''
+    , postOverlayPlugin ? ""
     , postPatch ? ""
     , patches ? [ ]
-    }: ((depot.third_party.gerrit.override {
+    }: ((depot.third_party.gerrit.override (old: {
       name = "${name}.jar";
 
       src = pkgs.runCommandLocal "${name}-src" { } ''
         cp -R "${depot.third_party.gerrit.src}" "$out"
-        chmod +w "$out/plugins"
+        chmod -R +w "$out"
         ${overlayPluginCmd}
+        ${postOverlayPlugin}
       '';
+      depsHash = (if depsHash != null then depsHash else old.depsHash);
 
-      bazelTargets = [ "//plugins/${name}" ];
-    }).overrideAttrs (super: {
-      deps = super.deps.overrideAttrs (superDeps: {
-        outputHash = depsOutputHash;
-      });
-      installPhase = ''
-        cp "bazel-bin/plugins/${name}/${name}.jar" "$out"
-      '';
+      bazelTargets = {
+        "//plugins/${name}" = "$out";
+      };
+
+      extraBuildInstall = "";
+    })).overrideAttrs (super: {
       postPatch = ''
         ${super.postPatch or ""}
         pushd "plugins/${name}"
diff --git a/third_party/gerrit_plugins/code-owners/default.nix b/third_party/gerrit_plugins/code-owners/default.nix
index 0dc3ef83ae7f..c849bfb52d41 100644
--- a/third_party/gerrit_plugins/code-owners/default.nix
+++ b/third_party/gerrit_plugins/code-owners/default.nix
@@ -5,11 +5,11 @@ let
 in
 buildGerritBazelPlugin rec {
   name = "code-owners";
-  depsOutputHash = "sha256:0jv62cc1kpgsmwk119i9njmqn6w6k8frlbgcw87y8nfbpprmcf01";
+  version = "7de40d8";
   src = pkgs.fetchgit {
     url = "https://gerrit.googlesource.com/plugins/code-owners";
-    rev = "e654ae5bda2085bce9a99942bec440e004a114f3";
-    sha256 = "sha256:14d3x3iqskgw16pvyaa0swh252agj84p9pzlf24l8lgx9d7y4biz";
+    rev = "7de40d8b30e55eb64316b6fc3d0d00da9caddade";
+    hash = "sha256-0sLwUcG9RN1o9vZGW8ErwL7UgJapgYoo8XMGsWLO25Q=";
   };
   patches = [
     ./using-usernames.patch
diff --git a/third_party/gerrit_plugins/oauth/default.nix b/third_party/gerrit_plugins/oauth/default.nix
index e7626fa88c38..811614d66a18 100644
--- a/third_party/gerrit_plugins/oauth/default.nix
+++ b/third_party/gerrit_plugins/oauth/default.nix
@@ -5,15 +5,14 @@ let
 in
 buildGerritBazelPlugin rec {
   name = "oauth";
-  depsOutputHash = "sha256:01z7rn8hnms3cp7mq27yk063lpy4pmqwpfrcc3cfl0r43k889zz3";
+  version = "982316";
   src = pkgs.fetchgit {
     url = "https://gerrit.googlesource.com/plugins/oauth";
-    rev = "b27cf3ea820eec2ddd22d217fc839261692ccdb0";
-    sha256 = "1m654ibgzprrhcl0wpzqrmq8drpgx6rzlw0ha16l1fi2zv5idkk2";
+    rev = "98231604d60788bb43490f1a301d792817ac8008";
+    hash = "sha256-AuVO1Yys8BYqGHZI/adszCUg0JM2v4Td4fe26LdOPLM=";
   };
-  overlayPluginCmd = ''
-    chmod +w "$out" "$out/plugins/external_plugin_deps.bzl"
-    cp -R "${src}" "$out/plugins/${name}"
+  depsHash = "sha256-7SC4NXm4zGeJrYBqtEvcrLmsZmXEX8P21J0kwHBDBZ4=";
+  postOverlayPlugin = ''
     cp "${src}/external_plugin_deps.bzl" "$out/plugins/external_plugin_deps.bzl"
   '';
 }
diff --git a/third_party/git/default.nix b/third_party/git/default.nix
index eed07b5616c6..19613fd69555 100644
--- a/third_party/git/default.nix
+++ b/third_party/git/default.nix
@@ -4,6 +4,6 @@
 
 pkgs.git.overrideAttrs (old: {
   patches = (old.patches or [ ]) ++ [
-    ./0001-feat-third_party-git-date-add-dottime-format.patch
+    # ./0001-feat-third_party-git-date-add-dottime-format.patch
   ];
 })
diff --git a/third_party/gitignoreSource/default.nix b/third_party/gitignoreSource/default.nix
index 150de7c990e4..78a7414ed3ad 100644
--- a/third_party/gitignoreSource/default.nix
+++ b/third_party/gitignoreSource/default.nix
@@ -1,15 +1,7 @@
-{ pkgs, ... }:
+{ depot, lib, ... }:
 
 let
-  gitignoreNix = import
-    (pkgs.fetchFromGitHub {
-      owner = "hercules-ci";
-      repo = "gitignore";
-      rev = "f9e996052b5af4032fe6150bba4a6fe4f7b9d698";
-      sha256 = "0jrh5ghisaqdd0vldbywags20m2cxpkbbk5jjjmwaw0gr8nhsafv";
-    })
-    { inherit (pkgs) lib; };
-
+  gitignoreNix = import depot.third_party.sources."gitignore.nix" { inherit lib; };
 in
 {
   __functor = _: gitignoreNix.gitignoreSource;
diff --git a/third_party/nixpkgs/default.nix b/third_party/nixpkgs/default.nix
index b79a963e5c9f..3ec49ea084d8 100644
--- a/third_party/nixpkgs/default.nix
+++ b/third_party/nixpkgs/default.nix
@@ -52,7 +52,16 @@ let
   # Overlay for packages that should come from the stable channel
   # instead (e.g. because something is broken in unstable).
   # Use `stableNixpkgs` from above.
-  stableOverlay = _unstableSelf: unstableSuper: { };
+  stableOverlay = _unstableSelf: unstableSuper: {
+    # newer trunk fails somewhere within reqwest, trying to read a mystery file
+    trunk = stableNixpkgs.trunk;
+
+    # the big lis package change breaks everything in //3p/lisp, undo it for now.
+    lispPackages = stableNixpkgs.lispPackages;
+
+    # mypaint is broken on stable (2024-09-05)
+    mypaint = stableNixpkgs.mypaint;
+  };
 
   # Overlay to expose the nixpkgs commits we are using to other Nix code.
   commitsOverlay = _: _: {
diff --git a/third_party/overlays/patches/cbtemulator-uds.patch b/third_party/overlays/patches/cbtemulator-uds.patch
deleted file mode 100644
index a19255306f88..000000000000
--- a/third_party/overlays/patches/cbtemulator-uds.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-commit 1397e10225d8c6fd079a86fccd58fb5d0f4200bc
-Author: Florian Klink <flokli@flokli.de>
-Date:   Fri Mar 29 10:06:34 2024 +0100
-
-    feat(bigtable/emulator): allow listening on Unix Domain Sockets
-    
-    cbtemulator listening on unix domain sockets is much easier than trying
-    to allocate free TCP ports, especially if many cbtemulators are run at
-    the same time in integration tests.
-    
-    This adds an additional flag, address, which has priority if it's set,
-    rather than host:port.
-    
-    `NewServer` already takes a `laddr string`, so we simply check for it to
-    contain slashes, and if so, listen on unix, rather than TCP.
-
-diff --git a/bigtable/bttest/inmem.go b/bigtable/bttest/inmem.go
-index 556abc2a85..33e4bf2667 100644
---- a/bttest/inmem.go
-+++ b/bttest/inmem.go
-@@ -40,6 +40,7 @@ import (
- 	"math"
- 	"math/rand"
- 	"net"
-+	"os"
- 	"regexp"
- 	"sort"
- 	"strings"
-@@ -106,7 +107,15 @@ type server struct {
- // The Server will be listening for gRPC connections, without TLS,
- // on the provided address. The resolved address is named by the Addr field.
- func NewServer(laddr string, opt ...grpc.ServerOption) (*Server, error) {
--	l, err := net.Listen("tcp", laddr)
-+	var l net.Listener
-+	var err error
-+
-+	// If the address contains slashes, listen on a unix domain socket instead.
-+	if strings.Contains(laddr, "/") {
-+		l, err = net.Listen("unix", laddr)
-+	} else {
-+		l, err = net.Listen("tcp", laddr)
-+	}
- 	if err != nil {
- 		return nil, err
- 	}
-diff --git a/bigtable/cmd/emulator/cbtemulator.go b/bigtable/cmd/emulator/cbtemulator.go
-index 144c09ffb1..deaf69b717 100644
---- a/cmd/emulator/cbtemulator.go
-+++ b/cmd/emulator/cbtemulator.go
-@@ -27,8 +27,9 @@ import (
- )
- 
- var (
--	host = flag.String("host", "localhost", "the address to bind to on the local machine")
--	port = flag.Int("port", 9000, "the port number to bind to on the local machine")
-+	host    = flag.String("host", "localhost", "the address to bind to on the local machine")
-+	port    = flag.Int("port", 9000, "the port number to bind to on the local machine")
-+	address = flag.String("address", "", "address:port number or unix socket path to listen on. Has priority over host/port")
- )
- 
- const (
-@@ -42,7 +43,15 @@ func main() {
- 		grpc.MaxRecvMsgSize(maxMsgSize),
- 		grpc.MaxSendMsgSize(maxMsgSize),
- 	}
--	srv, err := bttest.NewServer(fmt.Sprintf("%s:%d", *host, *port), opts...)
-+
-+	var laddr string
-+	if *address != "" {
-+		laddr = *address
-+	} else {
-+		laddr = fmt.Sprintf("%s:%d", *host, *port)
-+	}
-+
-+	srv, err := bttest.NewServer(laddr, opts...)
- 	if err != nil {
- 		log.Fatalf("failed to start emulator: %v", err)
- 	}
-commit ce16f843d6c93159d86b3807c6d9ff66e43aac67
-Author: Florian Klink <flokli@flokli.de>
-Date:   Fri Mar 29 11:53:15 2024 +0100
-
-    feat(bigtable): clean up unix socket on close
-    
-    Call srv.Close when receiving an interrupt, and delete the unix domain
-    socket in that function.
-
-diff --git a/bigtable/bttest/inmem.go b/bigtable/bttest/inmem.go
-index 33e4bf2667..0dc96024b1 100644
---- a/bttest/inmem.go
-+++ b/bttest/inmem.go
-@@ -148,6 +148,11 @@ func (s *Server) Close() {
- 
- 	s.srv.Stop()
- 	s.l.Close()
-+
-+	// clean up unix socket
-+	if strings.Contains(s.Addr, "/") {
-+		_ = os.Remove(s.Addr)
-+	}
- }
- 
- func (s *server) CreateTable(ctx context.Context, req *btapb.CreateTableRequest) (*btapb.Table, error) {
-diff --git a/bigtable/cmd/emulator/cbtemulator.go b/bigtable/cmd/emulator/cbtemulator.go
-index deaf69b717..5a9e8f7a8c 100644
---- a/cmd/emulator/cbtemulator.go
-+++ b/cmd/emulator/cbtemulator.go
-@@ -18,9 +18,12 @@ cbtemulator launches the in-memory Cloud Bigtable server on the given address.
- package main
- 
- import (
-+	"context"
- 	"flag"
- 	"fmt"
- 	"log"
-+	"os"
-+	"os/signal"
- 
- 	"cloud.google.com/go/bigtable/bttest"
- 	"google.golang.org/grpc"
-@@ -51,11 +54,18 @@ func main() {
- 		laddr = fmt.Sprintf("%s:%d", *host, *port)
- 	}
- 
-+	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
-+	defer stop()
-+
- 	srv, err := bttest.NewServer(laddr, opts...)
- 	if err != nil {
- 		log.Fatalf("failed to start emulator: %v", err)
- 	}
- 
- 	fmt.Printf("Cloud Bigtable emulator running on %s\n", srv.Addr)
--	select {}
-+	select {
-+	case <-ctx.Done():
-+		srv.Close()
-+		stop()
-+	}
- }
diff --git a/third_party/overlays/patches/crate2nix-0001-Fix-Use-mkDerivation-with-src-instead-of-runCommand.patch b/third_party/overlays/patches/crate2nix-0001-Fix-Use-mkDerivation-with-src-instead-of-runCommand.patch
new file mode 100644
index 000000000000..fbc18860ac81
--- /dev/null
+++ b/third_party/overlays/patches/crate2nix-0001-Fix-Use-mkDerivation-with-src-instead-of-runCommand.patch
@@ -0,0 +1,109 @@
+From 96f66ec32e003c6c215aa2a644281289a71dae7d Mon Sep 17 00:00:00 2001
+From: Ilan Joselevich <personal@ilanjoselevich.com>
+Date: Sun, 4 Aug 2024 02:35:27 +0300
+Subject: [PATCH] Fix: Use mkDerivation with src instead of runCommand for test
+ derivation
+
+The problem with using runCommand and recreating the src directory with
+lndir is that it changes the file types of individual files, they will
+now be a symlink instead of a regular file. If you have a crate that tests
+that a file is of regular type then it will fail inside the crate2nix derivation.
+---
+ templates/nix/crate2nix/default.nix | 81 ++++++++-----------
+ 1 file changed, 35 insertions(+), 46 deletions(-)
+
+diff --git a/templates/nix/crate2nix/default.nix b/templates/nix/crate2nix/default.nix
+index c53925e..90e10c6 100644
+--- a/templates/nix/crate2nix/default.nix
++++ b/templates/nix/crate2nix/default.nix
+@@ -120,52 +120,41 @@ rec {
+               testPostRun
+             ]);
+         in
+-        pkgs.runCommand "run-tests-${testCrate.name}"
+-          {
+-            inherit testCrateFlags;
+-            buildInputs = testInputs;
+-          } ''
+-          set -e
+-
+-          export RUST_BACKTRACE=1
+-
+-          # recreate a file hierarchy as when running tests with cargo
+-
+-          # the source for test data
+-          # It's necessary to locate the source in $NIX_BUILD_TOP/source/
+-          # instead of $NIX_BUILD_TOP/
+-          # because we compiled those test binaries in the former and not the latter.
+-          # So all paths will expect source tree to be there and not in the build top directly.
+-          # For example: $NIX_BUILD_TOP := /build in general, if you ask yourself.
+-          # NOTE: There could be edge cases if `crate.sourceRoot` does exist but
+-          # it's very hard to reason about them.
+-          # Open a bug if you run into this!
+-          mkdir -p source/
+-          cd source/
+-
+-          ${pkgs.buildPackages.xorg.lndir}/bin/lndir ${crate.src}
+-
+-          # build outputs
+-          testRoot=target/debug
+-          mkdir -p $testRoot
+-
+-          # executables of the crate
+-          # we copy to prevent std::env::current_exe() to resolve to a store location
+-          for i in ${crate}/bin/*; do
+-            cp "$i" "$testRoot"
+-          done
+-          chmod +w -R .
+-
+-          # test harness executables are suffixed with a hash, like cargo does
+-          # this allows to prevent name collision with the main
+-          # executables of the crate
+-          hash=$(basename $out)
+-          for file in ${drv}/tests/*; do
+-            f=$testRoot/$(basename $file)-$hash
+-            cp $file $f
+-            ${testCommand}
+-          done
+-        '';
++        pkgs.stdenvNoCC.mkDerivation {
++          name = "run-tests-${testCrate.name}";
++
++          inherit (crate) src;
++
++          inherit testCrateFlags;
++
++          buildInputs = testInputs;
++
++          buildPhase = ''
++            set -e
++            export RUST_BACKTRACE=1
++
++            # build outputs
++            testRoot=target/debug
++            mkdir -p $testRoot
++
++            # executables of the crate
++            # we copy to prevent std::env::current_exe() to resolve to a store location
++            for i in ${crate}/bin/*; do
++              cp "$i" "$testRoot"
++            done
++            chmod +w -R .
++
++            # test harness executables are suffixed with a hash, like cargo does
++            # this allows to prevent name collision with the main
++            # executables of the crate
++            hash=$(basename $out)
++            for file in ${drv}/tests/*; do
++              f=$testRoot/$(basename $file)-$hash
++              cp $file $f
++              ${testCommand}
++            done
++          '';
++        };
+     in
+     pkgs.runCommand "${crate.name}-linked"
+       {
+-- 
+2.44.0
+
diff --git a/third_party/overlays/patches/crate2nix-run-tests-in-build-source.patch b/third_party/overlays/patches/crate2nix-run-tests-in-build-source.patch
deleted file mode 100644
index 52793270e6e8..000000000000
--- a/third_party/overlays/patches/crate2nix-run-tests-in-build-source.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From 7cf084f73f7d15fe0538a625182fa7179c083b3d Mon Sep 17 00:00:00 2001
-From: Raito Bezarius <masterancpp@gmail.com>
-Date: Tue, 16 Jan 2024 02:10:48 +0100
-Subject: [PATCH] fix(template): run tests in `/build/source` instead `/build`
-
-Previously, the source tree was located inline in `/build` during tests, this was a mistake
-because the crates more than often are built in `/build/source` as per the `sourceRoot` system.
-
-This can cause issues with test binaries hardcoding `/build/source/...` as their choice for doing things,
-causing them to be confused in the test phase which is relocated without rewriting the paths inside test binaries.
-
-We fix that by relocating ourselves in the right hierarchy.
-
-This is a "simple" fix in the sense that more edge cases could exist but they are hard to reason about
-because they would be crates using custom `sourceRoot`, i.e. having `crate.sourceRoot` set and then it becomes
-a bit hard to reproduce the hierarchy, you need to analyze whether the path is absolute or relative,
-
-If it's relative, you can just reuse it and reproduce that specific hierarchy.
-If it's absolute, you need to cut the "absolute" meaningless part, e.g. `$NIX_BUILD_TOP/` and proceed like
-it's a relative path IMHO.
----
- crate2nix/Cargo.nix                                  | 10 ++++++++++
- crate2nix/templates/nix/crate2nix/default.nix        | 10 ++++++++++
-
-diff --git a/Cargo.nix b/Cargo.nix
-index 6ef7a49..172ff34 100644
---- a/Cargo.nix
-+++ b/Cargo.nix
-@@ -2889,6 +2889,16 @@ rec {
-           # recreate a file hierarchy as when running tests with cargo
- 
-           # the source for test data
-+          # It's necessary to locate the source in $NIX_BUILD_TOP/source/
-+          # instead of $NIX_BUILD_TOP/
-+          # because we compiled those test binaries in the former and not the latter.
-+          # So all paths will expect source tree to be there and not in the build top directly.
-+          # For example: $NIX_BUILD_TOP := /build in general, if you ask yourself.
-+          # TODO(raitobezarius): I believe there could be more edge cases if `crate.sourceRoot`
-+          # do exist but it's very hard to reason about them, so let's wait until the first bug report.
-+          mkdir -p source/
-+          cd source/
-+
-           ${pkgs.buildPackages.xorg.lndir}/bin/lndir ${crate.src}
- 
-           # build outputs
-diff --git a/crate2nix/templates/nix/crate2nix/default.nix b/crate2nix/templates/nix/crate2nix/default.nix
-index e4fc2e9..dfb14c4 100644
---- a/templates/nix/crate2nix/default.nix
-+++ b/templates/nix/crate2nix/default.nix
-@@ -135,6 +135,16 @@ rec {
-           # recreate a file hierarchy as when running tests with cargo
- 
-           # the source for test data
-+          # It's necessary to locate the source in $NIX_BUILD_TOP/source/
-+          # instead of $NIX_BUILD_TOP/
-+          # because we compiled those test binaries in the former and not the latter.
-+          # So all paths will expect source tree to be there and not in the build top directly.
-+          # For example: $NIX_BUILD_TOP := /build in general, if you ask yourself.
-+          # TODO(raitobezarius): I believe there could be more edge cases if `crate.sourceRoot`
-+          # do exist but it's very hard to reason about them, so let's wait until the first bug report.
-+          mkdir -p source/
-+          cd source/
-+
-           ${pkgs.buildPackages.xorg.lndir}/bin/lndir ${crate.src}
- 
-           # build outputs
--- 
-2.43.0
-
diff --git a/third_party/overlays/patches/treefmt-fix-no-cache.patch b/third_party/overlays/patches/treefmt-fix-no-cache.patch
new file mode 100644
index 000000000000..2ad9d595e106
--- /dev/null
+++ b/third_party/overlays/patches/treefmt-fix-no-cache.patch
@@ -0,0 +1,43 @@
+From 601af097720079ea40db100b1dd6aefba4685e7c Mon Sep 17 00:00:00 2001
+From: Florian Klink <flokli@flokli.de>
+Date: Mon, 1 Jul 2024 17:34:08 +0300
+Subject: [PATCH] fix: only try opening the cache if cache is enabled
+
+Otherwise `--no-cache` still fails to open the cache.
+---
+ cli/format.go | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/cli/format.go b/cli/format.go
+index 492a4f3..8ccf578 100644
+--- a/cli/format.go
++++ b/cli/format.go
+@@ -118,9 +118,11 @@ func (f *Format) Run() (err error) {
+ 		f.formatters[name] = formatter
+ 	}
+ 
+-	// open the cache
+-	if err = cache.Open(f.TreeRoot, f.ClearCache, f.formatters); err != nil {
+-		return err
++	// open the cache if configured
++	if !f.NoCache {
++		if cache.Open(f.TreeRoot, f.ClearCache, f.formatters); err != nil {
++			return err
++		}
+ 	}
+ 
+ 	// create an app context and listen for shutdown
+@@ -148,7 +150,9 @@ func (f *Format) Run() (err error) {
+ 	f.processedCh = make(chan *walk.File, cap(f.filesCh))
+ 
+ 	// start concurrent processing tasks in reverse order
+-	eg.Go(f.updateCache(ctx))
++	if !f.NoCache {
++		eg.Go(f.updateCache(ctx))
++	}
+ 	eg.Go(f.applyFormatters(ctx))
+ 	eg.Go(f.walkFilesystem(ctx))
+ 
+-- 
+2.44.1
+
diff --git a/third_party/overlays/tvl.nix b/third_party/overlays/tvl.nix
index 23f56e2f98af..a7cc68b2d994 100644
--- a/third_party/overlays/tvl.nix
+++ b/third_party/overlays/tvl.nix
@@ -21,17 +21,6 @@ depot.nix.readTree.drvTargets {
     withAWS = false;
   });
 
-  # To match telega in emacs-overlay or wherever
-  tdlib = super.tdlib.overrideAttrs (_: {
-    version = "1.8.24";
-    src = self.fetchFromGitHub {
-      owner = "tdlib";
-      repo = "td";
-      rev = "d79bd4b69403868897496da39b773ab25c69f6af";
-      sha256 = "0bc5akzw12qwj45rzqkrhw65qlrn9q8pzmvc5aiqv4bvhkb1ghl0";
-    };
-  });
-
   home-manager = super.home-manager.overrideAttrs (_: {
     src = depot.third_party.sources.home-manager;
     version = "git-"
@@ -69,6 +58,17 @@ depot.nix.readTree.drvTargets {
           sha256 = "1mmlrd2zpcwiv8gh10y7lrpflnbmsycdascrxjr3bfcwa8yx7901";
         };
       };
+
+      # Override telega sources until MELPA updates in nixpkgs resume.
+      telega = esuper.telega.overrideAttrs (_: {
+        version = "0.8.291"; # unstable
+        src = self.fetchFromGitHub {
+          owner = "zevlg";
+          repo = "telega.el";
+          rev = "58b4963b292ceb723d665df100b519eb5a99c676";
+          sha256 = "1q3ydbm0jhrsyvvdn0mpmxvskq0l53jkh40a5hlx7i3qkinbhbry";
+        };
+      });
     })
   );
 
@@ -90,51 +90,14 @@ depot.nix.readTree.drvTargets {
     };
   }));
 
-  # https://github.com/googleapis/google-cloud-go/pull/9665
-  cbtemulator = super.cbtemulator.overrideAttrs (old: {
+  crate2nix = super.crate2nix.overrideAttrs (old: {
     patches = old.patches or [ ] ++ [
-      ./patches/cbtemulator-uds.patch
-    ];
-  });
-
-  crate2nix = super.rustPlatform.buildRustPackage rec {
-    pname = "crate2nix";
-    version = "0.13.0";
-
-    src = super.fetchFromGitHub {
-      owner = "nix-community";
-      repo = "crate2nix";
-      rev = "ceb06eb7e76afb9e01a5f069aae136f97df72730";
-      hash = "sha256-JTMe8GViCQt51WUiaaoIPmWtwEeeYrl6pBxo2DNuKig=";
-    };
-
-    patches = [
+      # TODO(Kranzes): Remove in next release.
+      ./patches/crate2nix-0001-Fix-Use-mkDerivation-with-src-instead-of-runCommand.patch
+      # https://github.com/nix-community/crate2nix/pull/301
       ./patches/crate2nix-tests-debug.patch
-      ./patches/crate2nix-run-tests-in-build-source.patch
     ];
-
-    sourceRoot = "${src.name}/crate2nix";
-
-    cargoHash = "sha256-dhlSXY1CJE+JJt+6Y7W1MVMz36nwr6ny543py1TcjyY=";
-
-    nativeBuildInputs = [ super.makeWrapper ];
-
-    # Tests use nix(1), which tries (and fails) to set up /nix/var inside the
-    # sandbox
-    doCheck = false;
-
-    postFixup = ''
-      wrapProgram $out/bin/crate2nix \
-          --suffix PATH ":" ${lib.makeBinPath (with self; [ cargo nix_latest nix-prefetch-git ])}
-
-      rm -rf $out/lib $out/bin/crate2nix.d
-      mkdir -p \
-        $out/share/bash-completion/completions \
-        $out/share/zsh/vendor-completions
-      $out/bin/crate2nix completions -s 'bash' -o $out/share/bash-completion/completions
-      $out/bin/crate2nix completions -s 'zsh' -o $out/share/zsh/vendor-completions
-    '';
-  };
+  });
 
   evans = super.evans.overrideAttrs (old: {
     patches = old.patches or [ ] ++ [
@@ -144,6 +107,25 @@ depot.nix.readTree.drvTargets {
     ];
   });
 
+  # https://github.com/NixOS/nixpkgs/pull/329415/files
+  grpc-health-check = super.rustPlatform.buildRustPackage {
+    pname = "grpc-health-check";
+    version = "unstable-2022-08-19";
+
+    src = super.fetchFromGitHub {
+      owner = "paypizza";
+      repo = "grpc-health-check";
+      rev = "f61bb5e10beadc5ed53144cc540d66e19fc510bd";
+      hash = "sha256-nKut9c1HHIacdRcmvlXe0GrtkgCWN6sxJ4ImO0CIDdo=";
+    };
+
+    cargoHash = "sha256-lz+815iE+oXBQ3PfqBO0QBpZY6x1SNR7OU7BjkRszzI=";
+
+    nativeBuildInputs = [ super.protobuf ];
+    # tests fail
+    doCheck = false;
+  };
+
   # Imports a patch that fixes usage of this package on versions
   # >=1.9. The patch has been proposed upstream, but so far with no
   # reactions from the maintainer:
@@ -152,4 +134,22 @@ depot.nix.readTree.drvTargets {
   tpm2-pkcs11 = super.tpm2-pkcs11.overrideAttrs (old: {
     patches = (old.patches or [ ]) ++ [ ./patches/tpm2-pkcs11-190-dbupgrade.patch ];
   });
+
+  # Dependency isn't supported by Python 3.12
+  html5validator = super.html5validator.override {
+    python3 = self.python311;
+  };
+
+  # macFUSE bump containing fix for https://github.com/osxfuse/osxfuse/issues/974
+  # https://github.com/NixOS/nixpkgs/pull/320197
+  fuse =
+    if super.stdenv.isDarwin then
+      super.fuse.overrideAttrs
+        (old: rec {
+          version = "4.8.0";
+          src = super.fetchurl {
+            url = "https://github.com/osxfuse/osxfuse/releases/download/macfuse-${version}/macfuse-${version}.dmg";
+            hash = "sha256-ucTzO2qdN4QkowMVvC3+4pjEVjbwMsB0xFk+bvQxwtQ=";
+          };
+        }) else super.fuse;
 }
diff --git a/third_party/radicle-explorer/0001-remove-dependency-on-plausible.patch b/third_party/radicle-explorer/0001-remove-dependency-on-plausible.patch
new file mode 100644
index 000000000000..0f4a6219b298
--- /dev/null
+++ b/third_party/radicle-explorer/0001-remove-dependency-on-plausible.patch
@@ -0,0 +1,78 @@
+From cc4718cbea1bd70de21a2be515a944802246ffc7 Mon Sep 17 00:00:00 2001
+From: Vincent Ambo <mail@tazj.in>
+Date: Sun, 15 Sep 2024 03:08:28 +0300
+Subject: [PATCH] remove dependency on plausible
+
+We don't need spyware, thanks.
+---
+ package-lock.json | 9 ---------
+ package.json      | 1 -
+ src/App.svelte    | 8 --------
+ 3 files changed, 18 deletions(-)
+
+diff --git a/package-lock.json b/package-lock.json
+index d52de6c0..d96e342f 100644
+--- a/package-lock.json
++++ b/package-lock.json
+@@ -29,7 +29,6 @@
+         "marked-katex-extension": "^5.1.1",
+         "marked-linkify-it": "^3.1.11",
+         "md5": "^2.3.0",
+-        "plausible-tracker": "^0.3.9",
+         "svelte": "^4.2.19",
+         "twemoji": "^14.0.2",
+         "zod": "^3.23.8"
+@@ -3697,14 +3696,6 @@
+         "url": "https://github.com/sponsors/jonschlinkert"
+       }
+     },
+-    "node_modules/plausible-tracker": {
+-      "version": "0.3.9",
+-      "resolved": "https://registry.npmjs.org/plausible-tracker/-/plausible-tracker-0.3.9.tgz",
+-      "integrity": "sha512-hMhneYm3GCPyQon88SZrVJx+LlqhM1kZFQbuAgXPoh/Az2YvO1B6bitT9qlhpiTdJlsT5lsr3gPmzoVjb5CDXA==",
+-      "engines": {
+-        "node": ">=10"
+-      }
+-    },
+     "node_modules/playwright": {
+       "version": "1.46.1",
+       "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz",
+diff --git a/package.json b/package.json
+index 6d569ad9..61e8d892 100644
+--- a/package.json
++++ b/package.json
+@@ -73,7 +73,6 @@
+     "marked-katex-extension": "^5.1.1",
+     "marked-linkify-it": "^3.1.11",
+     "md5": "^2.3.0",
+-    "plausible-tracker": "^0.3.9",
+     "svelte": "^4.2.19",
+     "twemoji": "^14.0.2",
+     "zod": "^3.23.8"
+diff --git a/src/App.svelte b/src/App.svelte
+index 8161c390..4281ba61 100644
+--- a/src/App.svelte
++++ b/src/App.svelte
+@@ -1,6 +1,4 @@
+ <script lang="ts">
+-  import Plausible from "plausible-tracker";
+-
+   import * as router from "@app/lib/router";
+   import { unreachable } from "@app/lib/utils";
+ 
+@@ -28,12 +26,6 @@
+ 
+   void router.loadFromLocation();
+ 
+-  if (import.meta.env.PROD) {
+-    const plausible = Plausible({ domain: "app.radicle.xyz" });
+-
+-    plausible.enableAutoPageviews();
+-  }
+-
+   $: document.documentElement.setAttribute("data-codefont", $codeFont);
+   $: document.documentElement.setAttribute("data-theme", $theme);
+ </script>
+-- 
+2.46.0
+
diff --git a/third_party/radicle-explorer/default.nix b/third_party/radicle-explorer/default.nix
new file mode 100644
index 000000000000..7bf7dc3798d9
--- /dev/null
+++ b/third_party/radicle-explorer/default.nix
@@ -0,0 +1,66 @@
+# radicle-explorer is the web UI for Radicle.
+#
+# They have an upstream Nix derivation, but it only works with experimental
+# features Nix and is quite messy, so this is a copy of the relevant parts.
+{ lib, pkgs, ... }:
+
+let
+  twemoji-assets = pkgs.fetchFromGitHub {
+    owner = "twitter";
+    repo = "twemoji";
+    rev = "v14.0.2";
+    hash = "sha256-YoOnZ5uVukzi/6bLi22Y8U5TpplPzB7ji42l+/ys5xI=";
+  };
+
+  httpdSrc = pkgs.radicle-httpd.src;
+in
+lib.fix (self: pkgs.buildNpmPackage rec {
+  pname = "radicle-explorer";
+  version = (builtins.fromJSON (builtins.readFile "${src}/package.json")).version;
+
+  # source should be synced with the httpd, which is already in nixpkgs
+  src = pkgs.fetchgit {
+    inherit (httpdSrc) url rev;
+    hash = "sha256:09m13238h6j7g02r6332ihgyyzbjx90pgz14rz29pgv7936h6il8";
+  };
+
+  # This might change during nixpkgs bumps and will need updating. Need to fix
+  # upstream so that there is a normal, callable derivation.
+  npmDepsHash = "sha256:1hbrzfjkfc0q8qk03yi6qb9zqm57h7hnkn7fl0yxkrzbrljaljaz";
+
+  patches = [
+    ./0001-remove-dependency-on-plausible.patch
+  ];
+
+  postPatch = ''
+    patchShebangs --build ./scripts
+    mkdir -p "public/twemoji"
+    cp -t public/twemoji -r -- ${twemoji-assets}/assets/svg/*
+    : >scripts/install-twemoji-assets
+  '';
+  dontConfigure = true;
+  doCheck = false;
+
+  installPhase = ''
+    runHook preInstall
+    mkdir -p "$out"
+    cp -r -t "$out" build/*
+    runHook postInstall
+  '';
+
+  # Override the build-time configuration with other preferred seeds which are
+  # displayed on the landing page.
+  passthru.withPreferredSeeds = seeds:
+    let
+      originalConfig = builtins.fromJSON (builtins.readFile "${src}/config/default.json");
+      config = originalConfig // {
+        preferredSeeds = seeds;
+      };
+      newConfig = pkgs.writeText "local.json" (builtins.toJSON config);
+    in
+    self.overrideAttrs (_: {
+      preBuild = ''
+        cp ${newConfig} config/local.json
+      '';
+    });
+})
diff --git a/third_party/rust-crates/default.nix b/third_party/rust-crates/default.nix
index 697e47cddefc..a473a8346a6b 100644
--- a/third_party/rust-crates/default.nix
+++ b/third_party/rust-crates/default.nix
@@ -292,130 +292,4 @@ depot.nix.readTree.drvTargets rec{
     sha256 = "1kd047p8jv6mhmfzddjvfa2nwkfrb3l1wml6lfm51n1cr06cc9lz";
   };
 
-  libz-sys = buildRustCrate {
-    pname = "libz-sys";
-    version = "1.1.2";
-    sha256 = "1y7v6bkwr4b6yaf951p1ns7mx47b29ziwdd5wziaic14gs1gwq30";
-    buildDependencies = [
-      cc
-      pkg-config
-    ];
-  };
-
-  libgit2-sys = buildRustCrate {
-    pname = "libgit2-sys";
-    version = "0.16.2+1.7.2";
-    sha256 = "0bs446idbmg8s13jvb0ck6qmrskcdn2mp3d4mn9ggxbmiw4ryd3g";
-    dependencies = [
-      libc
-      libz-sys
-    ];
-    libPath = "lib.rs";
-    libName = "libgit2_sys";
-    # TODO: this should be available via `pkgs.defaultCrateOverrides`,
-    # I thought that was included by default?
-    nativeBuildInputs = [ pkg-config ];
-    buildInputs = [ pkgs.zlib pkgs.libgit2 ];
-    buildDependencies = [
-      cc
-      pkg-config
-    ];
-    env.LIBGIT2_NO_VENDOR = "1";
-  };
-
-  matches = buildRustCrate {
-    pname = "matches";
-    version = "0.1.8";
-    sha256 = "03hl636fg6xggy0a26200xs74amk3k9n0908rga2szn68agyz3cv";
-    libPath = "lib.rs";
-  };
-
-  percent-encoding = buildRustCrate {
-    pname = "percent-encoding";
-    version = "2.1.0";
-    sha256 = "0i838f2nr81585ckmfymf8l1x1vdmx6n8xqvli0lgcy60yl2axy3";
-    libPath = "lib.rs";
-  };
-
-  form_urlencoded = buildRustCrate {
-    pname = "form_urlencoded";
-    version = "1.0.1";
-    sha256 = "0rhv2hfrzk2smdh27walkm66zlvccnnwrbd47fmf8jh6m420dhj8";
-    dependencies = [
-      matches
-      percent-encoding
-    ];
-  };
-
-  tinyvec_macros = buildRustCrate {
-    pname = "tinyvec_macros";
-    version = "0.1.0";
-    sha256 = "0aim73hyq5g8b2hs9gjq2sv0xm4xzfbwp5fdyg1frljqzkapq682";
-  };
-
-  tinyvec = buildRustCrate {
-    pname = "tinyvec";
-    version = "1.2.0";
-    sha256 = "1c95nma20kiyrjwfsk7hzd5ir6yy4bm63fmfbfb4dm9ahnlvdp3y";
-    features = [ "alloc" ];
-    dependencies = [
-      tinyvec_macros
-    ];
-  };
-
-  unicode-normalization = buildRustCrate {
-    pname = "unicode-normalization";
-    version = "0.1.17";
-    sha256 = "0w4s0avzlf7pzcclhhih93aap613398sshm6jrxcwq0f9lhis11c";
-    dependencies = [
-      tinyvec
-    ];
-  };
-
-  unicode-bidi = buildRustCrate {
-    pname = "unicode-bidi";
-    version = "0.3.5";
-    sha256 = "193jzlxj1dfcms2381lyd45zh4ywlicj9lzcfpid1zbkmfarymkz";
-    dependencies = [
-      matches
-    ];
-  };
-
-  idna = buildRustCrate {
-    pname = "idna";
-    version = "0.2.3";
-    sha256 = "0hwypd0fpym9lmd4bbqpwyr5lhrlvmvzhi1vy9asc5wxwkzrh299";
-    dependencies = [
-      matches
-      unicode-normalization
-      unicode-bidi
-    ];
-  };
-
-  url = buildRustCrate {
-    pname = "url";
-    version = "2.2.1";
-    sha256 = "1ci1djafh83qhpzbmxnr9w5gcrjs3ghf8rrxdy4vklqyji6fvn5v";
-    dependencies = [
-      form_urlencoded
-      idna
-      matches
-      percent-encoding
-    ];
-  };
-
-
-  git2 = buildRustCrate {
-    pname = "git2";
-    edition = "2018";
-    version = "0.18.1";
-    sha256 = "1d1wm8cn37svyxgvzfapwilkkc9d2x7fcrgciwn8b2pv9aqz102k";
-    dependencies = [
-      bitflags
-      libc
-      libgit2-sys
-      log
-      url
-    ];
-  };
 }
diff --git a/third_party/sources/sources.json b/third_party/sources/sources.json
index 5a6bae4866d3..96491698d9f2 100644
--- a/third_party/sources/sources.json
+++ b/third_party/sources/sources.json
@@ -5,10 +5,22 @@
         "homepage": "https://matrix.to/#/#agenix:nixos.org",
         "owner": "ryantm",
         "repo": "agenix",
-        "rev": "0.15.0",
-        "sha256": "01dhrghwa7zw93cybvx4gnrskqk97b004nfxgsys0736823956la",
+        "rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41",
+        "sha256": "1x8nd8hvsq6mvzig122vprwigsr3z2skanig65haqswn7z7amsvg",
         "type": "tarball",
-        "url": "https://github.com/ryantm/agenix/archive/0.15.0.tar.gz",
+        "url": "https://github.com/ryantm/agenix/archive/f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41.tar.gz",
+        "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
+    },
+    "gitignore.nix": {
+        "branch": "master",
+        "description": "Nix functions for filtering local git sources",
+        "homepage": "",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+        "sha256": "02wxkdpbhlm3yk5mhkhsp3kwakc16xpmsf2baw57nz1dg459qv8w",
+        "type": "tarball",
+        "url": "https://github.com/hercules-ci/gitignore.nix/archive/637db329424fd7e46cf4185293b9cc8c88c95394.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "home-manager": {
@@ -17,10 +29,10 @@
         "homepage": "https://nix-community.github.io/home-manager/",
         "owner": "nix-community",
         "repo": "home-manager",
-        "rev": "b787726a8413e11b074cde42704b4af32d95545c",
-        "sha256": "0amclig8lqn7ylb1r38yni4v4r1mf5m0qih7n2lvm8azjrybxfkr",
+        "rev": "a9c9cc6e50f7cbd2d58ccb1cd46a1e06e9e445ff",
+        "sha256": "1cxp9rgczr4rhhx1klwcr7a61khizq8hv63gvmy9gfsx7fp4h60a",
         "type": "tarball",
-        "url": "https://github.com/nix-community/home-manager/archive/b787726a8413e11b074cde42704b4af32d95545c.tar.gz",
+        "url": "https://github.com/nix-community/home-manager/archive/a9c9cc6e50f7cbd2d58ccb1cd46a1e06e9e445ff.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "impermanence": {
@@ -29,10 +41,10 @@
         "homepage": "",
         "owner": "nix-community",
         "repo": "impermanence",
-        "rev": "a33ef102a02ce77d3e39c25197664b7a636f9c30",
-        "sha256": "1mig6ns8l5iynsm6pfbnx2b9hmr592s1kqbw6gq1n25czdlcniam",
+        "rev": "63f4d0443e32b0dd7189001ee1894066765d18a5",
+        "sha256": "0xnshgwfg834dm9l14p2w3wmhjysjpqpgfk37im0vrk1qgva19g2",
         "type": "tarball",
-        "url": "https://github.com/nix-community/impermanence/archive/a33ef102a02ce77d3e39c25197664b7a636f9c30.tar.gz",
+        "url": "https://github.com/nix-community/impermanence/archive/63f4d0443e32b0dd7189001ee1894066765d18a5.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "naersk": {
@@ -41,10 +53,10 @@
         "homepage": "",
         "owner": "nmattia",
         "repo": "naersk",
-        "rev": "aeb58d5e8faead8980a807c840232697982d47b9",
-        "sha256": "185wg4p67krrjd8dx5h9pc381z7677nfzsdyp54kg3niqcf5wdzx",
+        "rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11",
+        "sha256": "0v6ncaqm8q2mdv1jhkjjwi1sx4firlhjxpw4wachkwkriyjnkz5g",
         "type": "tarball",
-        "url": "https://github.com/nmattia/naersk/archive/aeb58d5e8faead8980a807c840232697982d47b9.tar.gz",
+        "url": "https://github.com/nmattia/naersk/archive/3fb418eaf352498f6b6c30592e3beb63df42ef11.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "napalm": {
@@ -53,10 +65,10 @@
         "homepage": "",
         "owner": "nix-community",
         "repo": "napalm",
-        "rev": "edcb26c266ca37c9521f6a97f33234633cbec186",
-        "sha256": "0ai1ax380nnpz0mbgbc5vdzafyjilcmdj7kgv087x2vagpprb4yy",
+        "rev": "e1babff744cd278b56abe8478008b4a9e23036cf",
+        "sha256": "04h62p4hxw7fhclki7hcn739hhig3rh9q4njp24j7bm0dk2kj8h6",
         "type": "tarball",
-        "url": "https://github.com/nix-community/napalm/archive/edcb26c266ca37c9521f6a97f33234633cbec186.tar.gz",
+        "url": "https://github.com/nix-community/napalm/archive/e1babff744cd278b56abe8478008b4a9e23036cf.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "nixpkgs": {
@@ -65,10 +77,10 @@
         "homepage": "",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "fd281bd6b7d3e32ddfa399853946f782553163b5",
-        "sha256": "1hy81yj2dcg6kfsm63xcqf8kvigxglim1rcg1xpmy2rb6a8vqvsj",
+        "rev": "99dc8785f6a0adac95f5e2ab05cc2e1bf666d172",
+        "sha256": "11vz7dshwxszab91da1x98qdlmpxi0v7daz24jj3crpll68n93w0",
         "type": "tarball",
-        "url": "https://github.com/NixOS/nixpkgs/archive/fd281bd6b7d3e32ddfa399853946f782553163b5.tar.gz",
+        "url": "https://github.com/NixOS/nixpkgs/archive/99dc8785f6a0adac95f5e2ab05cc2e1bf666d172.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "nixpkgs-stable": {
@@ -77,10 +89,10 @@
         "homepage": "",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "72da83d9515b43550436891f538ff41d68eecc7f",
-        "sha256": "177sws22nqkvv8am76qmy9knham2adfh3gv7hrjf6492z1mvy02y",
+        "rev": "205fd4226592cc83fd4c0885a3e4c9c400efabb5",
+        "sha256": "1f5d2g1p6nfwycpmrnnmc2xmcszp804adp16knjvdkj8nz36y1fg",
         "type": "tarball",
-        "url": "https://github.com/NixOS/nixpkgs/archive/72da83d9515b43550436891f538ff41d68eecc7f.tar.gz",
+        "url": "https://github.com/NixOS/nixpkgs/archive/205fd4226592cc83fd4c0885a3e4c9c400efabb5.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "rust-overlay": {
@@ -89,10 +101,10 @@
         "homepage": "",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "41b3b080cc3e4b3a48e933b87fc15a05f1870779",
-        "sha256": "13xp3bsgwpld8bkh5sjkigxcy5nz336hyc9xssk58glpgf1sxddm",
+        "rev": "20c8461785d8f5af32d8d4d5c128589e23d7f033",
+        "sha256": "1zy2jcy2ika83dwcpxxvmimk317zimwn7hv8h3v43apqwssl0nxv",
         "type": "tarball",
-        "url": "https://github.com/oxalica/rust-overlay/archive/41b3b080cc3e4b3a48e933b87fc15a05f1870779.tar.gz",
+        "url": "https://github.com/oxalica/rust-overlay/archive/20c8461785d8f5af32d8d4d5c128589e23d7f033.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     },
     "rustsec-advisory-db": {
@@ -101,10 +113,10 @@
         "homepage": "https://rustsec.org",
         "owner": "RustSec",
         "repo": "advisory-db",
-        "rev": "0bc9a77248be5cb5f2b51fe6aba8ba451d74c6bb",
-        "sha256": "1fmgz6a2b63yy5cn2ghbqj8l0pdb2rwr5agr1m4mzaydlyypx26m",
+        "rev": "3cae2352cf82b5815b98aa309e0f4df6aa737cec",
+        "sha256": "0bba56sk4dlrf8rm3dmy9bxf95bq4rm1g3ppk4n2vfw0wzf7v7ap",
         "type": "tarball",
-        "url": "https://github.com/RustSec/advisory-db/archive/0bc9a77248be5cb5f2b51fe6aba8ba451d74c6bb.tar.gz",
+        "url": "https://github.com/RustSec/advisory-db/archive/3cae2352cf82b5815b98aa309e0f4df6aa737cec.tar.gz",
         "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
     }
 }
diff --git a/third_party/teleirc/default.nix b/third_party/teleirc/default.nix
new file mode 100644
index 000000000000..87915110024f
--- /dev/null
+++ b/third_party/teleirc/default.nix
@@ -0,0 +1,23 @@
+{ pkgs, lib, ... }:
+
+pkgs.buildGoModule rec {
+  name = "teleirc";
+  version = "2.3.0-4";
+
+  src = pkgs.fetchFromGitHub {
+    owner = "tvlfyi";
+    repo = "teleirc";
+    rev = "356ed1450840822172e7dff57965cc5371f63454";
+    sha256 = "0s6rlixks7lar9js4q1drg742cy2p4n8l4pmlzjmskl5d04c15gq";
+  };
+
+  vendorHash = "sha256:06f2wyxbphj73wknpp6dsn7rb4yhvdl6x0gj729cns7r4bsviscs";
+  ldflags = [ "-s" "-w" "-X" "main.version=${version}" ];
+  postInstall = "mv $out/bin/cmd $out/bin/teleirc";
+
+  meta = with lib; {
+    description = "IRC/Telegram bridge";
+    homepage = "https://docs.teleirc.com/en/latest/";
+    license = licenses.gpl3;
+  };
+}