Commit 128e9f5c authored by Nicolas Guichard's avatar Nicolas Guichard
Browse files

livegrep: init at 0-unstable-2026-01-06

This adds a package for [Livegrep](https://livegrep.com), a code
indexing and search tool.

The binaries are:
- codesearch: index builder and backend
- livegrep-reload HOST:PORT: reloads codesearch if started with -reload_rpc
- analyze-re REGEX: dumps infos about REGEX
- dump_file INDEX PATH: dumps infos about PATH in INDEX
- inspect-index INDEX: dumps infos about INDEX
- livegrep-github-reindex: builds an index from a GitHub repo
- livegrep-fetch-reindex: refreshes an index from its GitHub repo
- livegrep: web frontend
- lg: CLI tool to query the web frontend
parent c24541ae
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
Subject: [PATCH] Use patched rules_js and Nix-provided nodejs

By default aspect_rules_js brings a precompiled nodejs which uses a 
non-nixpkgs dynamic linker. Instead use nodejs from nixpkgs. This
requires a patched rules_js as specifying npm_path fails otherwise
(see the rules_js patch).

We also require a patched rules_js because it otherwise generates and
immediately executes scripts with `#!/usr/bin/env bash`.

---
 MODULE.bazel                   |  4 ++++
 nixpkgs-toolchains/BUILD.bazel | 13 +++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 nixpkgs-toolchains/BUILD.bazel

diff --git a/MODULE.bazel b/MODULE.bazel
index 4df2a500..b7525996 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -35,6 +35,10 @@ use_repo(
 )
 
 bazel_dep(name = "aspect_rules_js", version = "2.4.0")
+local_path_override(module_name = "aspect_rules_js", path = "@rules_js@")
+
+bazel_dep(name = "rules_nodejs", version = "6.3.0")
+register_toolchains("//nixpkgs-toolchains:nixpkgs_nodejs_toolchain")
 
 npm = use_extension(
     "@aspect_rules_js//npm:extensions.bzl",
diff --git a/nixpkgs-toolchains/BUILD.bazel b/nixpkgs-toolchains/BUILD.bazel
new file mode 100644
index 00000000..3b8a7940
--- /dev/null
+++ b/nixpkgs-toolchains/BUILD.bazel
@@ -0,0 +1,13 @@
+load("@rules_nodejs//nodejs:toolchain.bzl", "nodejs_toolchain")
+
+nodejs_toolchain(
+    name = "node_toolchain",
+    node_path = "@nodejs@/bin/node",
+    npm_path = "@nodejs@/bin/npm",
+)
+
+toolchain(
+    name = "nixpkgs_nodejs_toolchain",
+    toolchain = ":node_toolchain",
+    toolchain_type = "@rules_nodejs//nodejs:toolchain_type",
+)
-- 
2.53.0
+157 −0
Original line number Diff line number Diff line
{
  lib,
  stdenv,
  fetchFromGitHub,
  buildBazelPackage,
  bazel_7,
  nix-update-script,
  applyPatches,
  nodejs,
  cctools,
}:
let
  cc_tools = [
    "codesearch"
    "analyze-re"
    "dump-file"
    "inspect-index"
  ];

  go_tools = [
    "livegrep"
    "lg"
    "livegrep-fetch-reindex"
    "livegrep-github-reindex"
    "livegrep-reload"
  ];

  registry = fetchFromGitHub {
    owner = "bazelbuild";
    repo = "bazel-central-registry";
    rev = "0f256a72067e42d62bb568cc2619f98deed139e2";
    hash = "sha256-OcMLg0KiAQOJZLH8r+QkeQ9bxcEc4L0dCgyUv5PkLQk=";
  };

  rules_js = applyPatches {
    src = fetchFromGitHub {
      owner = "aspect-build";
      repo = "rules_js";
      rev = "v2.4.0";
      hash = "sha256-Z0Oq5FQ26KS+tLwawXs2Jgox0Cau4E76IwzNKyTK0Tk=";
    };

    patches = [
      ./rule-js-Fix-toolchain-with-npm_path.patch
    ];

    postPatch = ''
      patchShebangs --build \
        npm/private/lifecycle/bundle.sh \
        npm/private/lifecycle/min/node-gyp-bin/node-gyp \
        npm/private/noop.sh \
        npm/private/versions_mirror.sh \
        js/private/node_wrapper.sh \
        js/private/npm_wrapper.sh

      substituteInPlace \
        npm/private/utils.bzl \
        npm/private/lifecycle/lifecycle-hooks.js \
        npm/private/lifecycle/min/index.min.js \
        js/private/js_binary.sh.tpl \
        --replace-fail '#!/usr/bin/env bash' "#!$(type -p bash)"
    '';
  };

  bazelDepsHashByBuildAndHost = {
    x86_64-linux.x86_64-linux = "sha256-PastkoOioWqlmGFHZiZ2S1ahWZu1UBhqHIfD2M/ff6A=";
    aarch64-linux.aarch64-linux = "sha256-mNWnpmk/dNQYKnP3YbfK5ott0+41I+49aH6RhWEMOGM=";
  };
  bazelDepsHashByHost = bazelDepsHashByBuildAndHost.${stdenv.buildPlatform.system} or { };
  bazelDepsHash = bazelDepsHashByHost.${stdenv.hostPlatform.system} or "";
in
buildBazelPackage {
  pname = "livegrep";
  version = "2026-02-10";

  src = fetchFromGitHub {
    owner = "livegrep";
    repo = "livegrep";
    rev = "923d5ad71dfe60900e6c2017b2fa4a5ff902ad71";
    hash = "sha256-SYbJJuUX13otaGRsYLTp6XWU3BBNmtNIpUxyu11U+b0=";
  };

  patches = [
    ./livegrep-Use-patched-rules_js-and-nodejs-from-nixpkgs.patch
  ];

  postPatch = ''
    substituteInPlace nixpkgs-toolchains/BUILD.bazel --subst-var-by nodejs "${nodejs}"
    substituteInPlace MODULE.bazel --subst-var-by rules_js "${rules_js}"
  '';

  bazelFlags = [
    "--registry"
    "file://${registry}"
  ];

  env = lib.optionalAttrs stdenv.hostPlatform.isDarwin {
    LIBTOOL = "${cctools}/bin/libtool";
  };

  fetchAttrs = {
    preInstall = ''
      # Avoid bash and $out store paths leaking into the fixed-output derivation
      rm $bazelOut/external/aspect_rules_js~~npm~npm/_exists.sh
      rm -r $bazelOut/external/rules_shell~~sh_configure~local_config_shell

      # Remove some non-reproducible and unused files
      rm -r $bazelOut/external/gazelle~~non_module_deps~bazel_gazelle_go_repository_cache
      rm -r $bazelOut/external/gazelle~~non_module_deps~bazel_gazelle_go_repository_tools
    '';

    hash = bazelDepsHash;
  };

  bazel = bazel_7;

  bazelBuildFlags = [ "-c opt" ];
  bazelTargets =
    (builtins.map (tool: "//src/tools:${tool}") cc_tools)
    ++ (builtins.map (tool: "//cmd/${tool}") go_tools);

  buildAttrs = {
    installPhase = ''
      pushd "bazel-bin/src/tools"
      install -Dt "$out/bin" ${builtins.toString cc_tools}
      popd

      for go_tool in ${builtins.toString go_tools}; do
        install -D -t "$out/bin" "bazel-bin/cmd/$go_tool/''${go_tool}_/$go_tool"
      done

      mkdir -p "$out/bin/livegrep.runfiles/com_github_livegrep_livegrep"
      cp -Lr "bazel-bin/cmd/livegrep/livegrep_/livegrep.runfiles/_main/web" "$out/bin/livegrep.runfiles/com_github_livegrep_livegrep"
    '';
  };

  passthru = {
    inherit rules_js;
    updateScript = nix-update-script { };
  };

  strictDeps = true;
  __structuredAttrs = true;

  meta = {
    description = "Livegrep is a tool, partially inspired by Google Code Search, for interactive regex search of ~gigabyte-scale source repositories.";
    homepage = "http://livegrep.com/";
    downloadPage = "https://github.com/livegrep/livegrep";
    license = lib.licenses.bsd2;
    maintainers = with lib.maintainers; [ nicolas-guichard ];
    mainProgram = "livegrep";
    badPlatforms = [
      # Error in fail: Unable to find a CC toolchain using toolchain resolution
      lib.systems.inspect.patterns.isDarwin
    ];
  };
}
+26 −0
Original line number Diff line number Diff line
Subject: [PATCH] Fix for toolchain with npm_path

When specifying a toolchain with a npm_path, transitive_launcher_files
is None which leads to an error here.

Instead, don't set transitive_files at all.

---
 js/private/js_binary.bzl | 1 -
 1 file changed, 1 deletion(-)

diff --git a/js/private/js_binary.bzl b/js/private/js_binary.bzl
index 37627809..29e3bf62 100644
--- a/js/private/js_binary.bzl
+++ b/js/private/js_binary.bzl
@@ -555,7 +555,6 @@ def _create_launcher(ctx, log_prefix_rule_set, log_prefix_rule, fixed_args = [],
         include_npm_sources = ctx.attr.include_npm_sources,
     ).merge(ctx.runfiles(
         files = launcher_files,
-        transitive_files = transitive_launcher_files,
     ))
 
     return struct(
-- 
2.53.0