summary refs log tree commit diff
path: root/pkgs/development/tools/parsing/tree-sitter/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/development/tools/parsing/tree-sitter/default.nix')
-rw-r--r--pkgs/development/tools/parsing/tree-sitter/default.nix154
1 files changed, 111 insertions, 43 deletions
diff --git a/pkgs/development/tools/parsing/tree-sitter/default.nix b/pkgs/development/tools/parsing/tree-sitter/default.nix
index 51af3acdacd..60704fdd780 100644
--- a/pkgs/development/tools/parsing/tree-sitter/default.nix
+++ b/pkgs/development/tools/parsing/tree-sitter/default.nix
@@ -1,8 +1,25 @@
-{ lib, stdenv
-, fetchgit, fetchFromGitHub, fetchurl
-, writeShellScript, runCommand, which
-, rustPlatform, jq, nix-prefetch-git, xe, curl, emscripten
+{ lib
+, stdenv
+, fetchgit
+, fetchFromGitHub
+, fetchurl
+, writeShellScript
+, runCommand
+, which
+, formats
+, rustPlatform
+, jq
+, nix-prefetch-git
+, xe
+, curl
+, emscripten
+, Security
 , callPackage
+, linkFarm
+
+, enableShared ? !stdenv.hostPlatform.isStatic
+, enableStatic ? stdenv.hostPlatform.isStatic
+, webUISupport ? false
 }:
 
 # TODO: move to carnix or https://github.com/kolloch/crate2nix
@@ -11,60 +28,111 @@ let
   # 1) change all these hashes
   # 2) nix-build -A tree-sitter.updater.update-all-grammars
   # 3) run the ./result script that is output by that (it updates ./grammars)
-  version = "0.16.4";
-  sha256 = "1m0zxz7h4w2zny7yhrlxwqvizcf043cizg7ca5dn3h9k16adcxil";
-  cargoSha256 = "0hxm73diwiybljm6yy3vmwfdpg33b4rlg0h7afq4xgccq2vkwafs";
+  version = "0.20.0";
+  sha256 = "0hrcisvw44fjxix09lfbrz7majaj6njbnr6c92a6a5748p2jvyng";
+  cargoSha256 = "029db3yy6nj18vxfvj0ra568a9k4x7znfj08spvzl5sxfbx6442r";
 
   src = fetchFromGitHub {
     owner = "tree-sitter";
     repo = "tree-sitter";
-    rev = version;
+    rev = "v${version}";
     inherit sha256;
     fetchSubmodules = true;
   };
 
   update-all-grammars = import ./update.nix {
-    inherit writeShellScript nix-prefetch-git curl jq xe src;
+    inherit writeShellScript nix-prefetch-git curl jq xe src formats lib;
   };
 
-  fetchGrammar = (v: fetchgit {inherit (v) url rev sha256 fetchSubmodules; });
+  fetchGrammar = (v: fetchgit { inherit (v) url rev sha256 fetchSubmodules; });
 
   grammars =
-    runCommand "grammars" {} (''
-       mkdir $out
-     '' + (lib.concatStrings (lib.mapAttrsToList
-            (name: grammar: "ln -s ${fetchGrammar grammar} $out/${name}\n")
-            (import ./grammars))));
-
-  builtGrammars = let
-    change = name: grammar:
-      callPackage ./library.nix {
-        language = name; inherit version; source = fetchGrammar grammar;
-      };
-  in
-    # typescript doesn't have parser.c in the same place as others
-    lib.mapAttrs change (removeAttrs (import ./grammars) ["typescript"]);
-
-in rustPlatform.buildRustPackage {
+    runCommand "grammars" { } (''
+      mkdir $out
+    '' + (lib.concatStrings (lib.mapAttrsToList
+      (name: grammar: "ln -s ${fetchGrammar grammar} $out/${name}\n")
+      (import ./grammars))));
+
+  builtGrammars =
+    let
+      change = name: grammar:
+        callPackage ./grammar.nix { } {
+          language = name;
+          inherit version;
+          source = fetchGrammar grammar;
+          location = if grammar ? location then grammar.location else null;
+        };
+      grammars' = (import ./grammars);
+      grammars = grammars' //
+        { tree-sitter-ocaml = grammars'.tree-sitter-ocaml // { location = "ocaml"; }; } //
+        { tree-sitter-ocaml-interface = grammars'.tree-sitter-ocaml // { location = "interface"; }; } //
+        { tree-sitter-typescript = grammars'.tree-sitter-typescript // { location = "typescript"; }; } //
+        { tree-sitter-tsx = grammars'.tree-sitter-typescript // { location = "tsx"; }; };
+    in
+    lib.mapAttrs change grammars;
+
+  # Usage:
+  # pkgs.tree-sitter.withPlugins (p: [ p.tree-sitter-c p.tree-sitter-java ... ])
+  #
+  # or for all grammars:
+  # pkgs.tree-sitter.withPlugins (_: allGrammars)
+  # which is equivalent to
+  # pkgs.tree-sitter.withPlugins (p: builtins.attrValues p)
+  withPlugins = grammarFn:
+    let
+      grammars = grammarFn builtGrammars;
+    in
+    linkFarm "grammars"
+      (map
+        (drv:
+          let
+            name = lib.strings.getName drv;
+          in
+          {
+            name =
+              (lib.strings.removePrefix "tree-sitter-"
+                (lib.strings.removeSuffix "-grammar" name))
+              + stdenv.hostPlatform.extensions.sharedLibrary;
+            path = "${drv}/parser";
+          }
+        )
+        grammars);
+
+  allGrammars = builtins.attrValues builtGrammars;
+
+in
+rustPlatform.buildRustPackage {
   pname = "tree-sitter";
   inherit src version cargoSha256;
 
-  nativeBuildInputs = [ emscripten which ];
-
-  postPatch = ''
-    # needed for the tests
-    rm -rf test/fixtures/grammars
-    ln -s ${grammars} test/fixtures/grammars
+  buildInputs =
+    lib.optionals stdenv.isDarwin [ Security ];
+  nativeBuildInputs =
+    [ which ]
+    ++ lib.optionals webUISupport [ emscripten ];
+
+  postPatch = lib.optionalString (!webUISupport) ''
+    # remove web interface
+    sed -e '/pub mod web_ui/d' \
+        -i cli/src/lib.rs
+    sed -e 's/web_ui,//' \
+        -e 's/web_ui::serve(&current_dir.*$/println!("ERROR: web-ui is not available in this nixpkgs build; enable the webUISupport"); std::process::exit(1);/' \
+        -i cli/src/main.rs
   '';
 
   # Compile web assembly with emscripten. The --debug flag prevents us from
   # minifying the JavaScript; passing it allows us to side-step more Node
   # JS dependencies for installation.
-  preBuild = ''
-    HOME=/tmp
+  preBuild = lib.optionalString webUISupport ''
     bash ./script/build-wasm --debug
   '';
 
+  postInstall = ''
+    PREFIX=$out make install
+    ${lib.optionalString (!enableShared) "rm $out/lib/*.so{,.*}"}
+    ${lib.optionalString (!enableStatic) "rm $out/lib/*.a"}
+  '';
+
   # test result: FAILED. 120 passed; 13 failed; 0 ignored; 0 measured; 0 filtered out
   doCheck = false;
 
@@ -72,11 +140,15 @@ in rustPlatform.buildRustPackage {
     updater = {
       inherit update-all-grammars;
     };
-    inherit grammars;
-    inherit builtGrammars;
+    inherit grammars builtGrammars withPlugins allGrammars;
+
+    tests = {
+      # make sure all grammars build
+      builtGrammars = lib.recurseIntoAttrs builtGrammars;
+    };
   };
 
-  meta = {
+  meta = with lib; {
     homepage = "https://github.com/tree-sitter/tree-sitter";
     description = "A parser generator tool and an incremental parsing library";
     longDescription = ''
@@ -90,11 +162,7 @@ in rustPlatform.buildRustPackage {
       * Robust enough to provide useful results even in the presence of syntax errors
       * Dependency-free so that the runtime library (which is written in pure C) can be embedded in any application
     '';
-    license = lib.licenses.mit;
-    maintainers = with lib.maintainers; [ Profpatsch ];
-    # Darwin needs some more work with default libraries
-    # Aarch has test failures with how tree-sitter compiles the generated C files
-    broken = stdenv.isDarwin || stdenv.isAarch64;
+    license = licenses.mit;
+    maintainers = with maintainers; [ Profpatsch ];
   };
-
 }