nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 129 lines 3.8 kB view raw
1{ 2 stdenv, 3 nodejs, 4 tree-sitter, 5 jq, 6 lib, 7}: 8 9{ 10 language, 11 version, 12 src, 13 meta ? { }, 14 generate ? false, 15 ... 16}@args: 17 18stdenv.mkDerivation ( 19 { 20 pname = "tree-sitter-${language}"; 21 22 inherit version src; 23 24 nativeBuildInputs = [ 25 jq 26 ] 27 ++ lib.optionals generate [ 28 nodejs 29 tree-sitter 30 ]; 31 32 CFLAGS = [ 33 "-Isrc" 34 "-O2" 35 ]; 36 CXXFLAGS = [ 37 "-Isrc" 38 "-O2" 39 ]; 40 41 stripDebugList = [ "parser" ]; 42 43 # Tree-sitter grammar packages contain a `tree-sitter.json` file at their 44 # root. This provides package metadata that can be used to infer build 45 # details. 46 # 47 # See https://tree-sitter.github.io/tree-sitter/cli/init.html for spec. 48 configurePhase = '' 49 runHook preConfigure 50 if [[ -e tree-sitter.json ]]; then 51 # Check nix package version matches grammar source 52 NIX_VERSION=${lib.head (lib.splitString "+" version)} 53 SRC_VERSION=$(jq -r '.metadata.version' tree-sitter.json) 54 if [[ "$NIX_VERSION" != "$SRC_VERSION" ]]; then 55 nixErrorLog "grammar version ($NIX_VERSION) differs from source ($SRC_VERSION)" 56 fi 57 58 # Check language name matches source 59 GRAMMAR=$(jq -c 'first(.grammars[] | select(.name == env.language))' tree-sitter.json) 60 if [[ -z "$GRAMMAR" ]]; then 61 GRAMMAR=$(jq -c 'first(.grammars[]) // {}' tree-sitter.json) 62 NAME=$(jq -r '.name' <<< "$GRAMMAR") 63 SRC_LANGS=$(jq -r '[.grammars[].name] | join(", ")' tree-sitter.json) 64 nixErrorLog "grammar name ($language) not found in source grammars ($SRC_LANGS), continuing with $NAME" 65 fi 66 67 # Move to the appropriate working directory for build 68 cd -- $(jq -r '.path // "."' <<< $GRAMMAR) 69 else 70 # Older grammars may not contain this file. The tree-sitter CLI provides 71 # a warning rather than fail unless ABI > 14. Mirror that behaviour 72 # while older grammars age out. 73 nixWarnLog "grammar source is missing tree-sitter.json" 74 fi 75 runHook postConfigure 76 ''; 77 78 # Optionally regenerate the parser source from the defined grammar. In most 79 # cases this should not be required as convention is to have this checked 80 # in to the source repo. 81 preBuild = lib.optionalString generate '' 82 tree-sitter generate 83 ''; 84 85 # When both scanner.{c,cc} exist, we should not link both since they may be the same but in 86 # different languages. Just randomly prefer C++ if that happens. 87 buildPhase = '' 88 runHook preBuild 89 if [[ -e src/scanner.cc ]]; then 90 $CXX -fPIC -c src/scanner.cc -o scanner.o $CXXFLAGS 91 elif [[ -e src/scanner.c ]]; then 92 $CC -fPIC -c src/scanner.c -o scanner.o $CFLAGS 93 fi 94 $CC -fPIC -c src/parser.c -o parser.o $CFLAGS 95 rm -rf parser 96 $CXX -shared -o parser *.o 97 runHook postBuild 98 ''; 99 100 installPhase = '' 101 runHook preInstall 102 mkdir $out 103 mv parser $out/ 104 if [[ -d queries ]]; then 105 cp -r queries $out 106 fi 107 runHook postInstall 108 ''; 109 110 # Merge default meta attrs with any explicitly defined on the source. 111 meta = { 112 description = "Tree-sitter grammar for ${language}"; 113 } 114 // (lib.optionalAttrs (src ? meta.homepage) { 115 homepage = src.meta.homepage; 116 }) 117 // meta; 118 } 119 # FIXME: neovim and nvim-treesitter currently rely on passing location rather 120 # than a src attribute with a correctly positioned root (e.g. for grammars in 121 # monorepos). Use this if present for now. 122 // (lib.optionalAttrs (args ? location && args.location != null) { 123 setSourceRoot = "sourceRoot=$(echo */${args.location})"; 124 }) 125 // removeAttrs args [ 126 "generate" 127 "meta" 128 ] 129)