diff --git a/.gitignore b/.gitignore index bf1e36d6..ca47139e 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ docs/assets/js/tree-sitter.js .build build zig-* + +/result diff --git a/crates/cli/flake.nix b/crates/cli/flake.nix deleted file mode 100644 index fbab9ad7..00000000 --- a/crates/cli/flake.nix +++ /dev/null @@ -1,115 +0,0 @@ -{ - perSystem = - { - self', - pkgs, - lib, - src, - version, - crossTargets, - ... - }: - let - buildCliFor = - targetPkgs: - let - isCross = targetPkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform; - in - targetPkgs.rustPlatform.buildRustPackage { - inherit src version; - pname = "tree-sitter-cli"; - - nativeBuildInputs = [ - pkgs.pkg-config - pkgs.nodejs_22 - ] - ++ lib.optionals (!isCross) [ pkgs.installShellFiles ]; - - cargoLock.lockFile = ../../Cargo.lock; - - preBuild = '' - rm -rf test/fixtures - mkdir -p test/fixtures - cp -r ${self'.packages.test-grammars}/fixtures/* test/fixtures/ - chmod -R u+w test/fixtures - ''; - - preCheck = "export HOME=$TMPDIR"; - doCheck = !isCross; - - postInstall = lib.optionalString (!isCross) '' - installShellCompletion --cmd tree-sitter \ - --bash <($out/bin/tree-sitter complete --shell bash) \ - --zsh <($out/bin/tree-sitter complete --shell zsh) \ - --fish <($out/bin/tree-sitter complete --shell fish) - ''; - - meta = with lib; { - description = "Tree-sitter CLI - A tool for developing, testing, and using Tree-sitter parsers"; - longDescription = '' - Tree-sitter is a parser generator tool and an incremental parsing library. - It can build a concrete syntax tree for a source file and efficiently update - the syntax tree as the source file is edited. This package provides the CLI - tool for developing, testing, and using Tree-sitter parsers. - ''; - homepage = "https://tree-sitter.github.io/tree-sitter"; - changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}"; - license = licenses.mit; - maintainers = [ maintainers.amaanq ]; - platforms = platforms.all; - mainProgram = "tree-sitter"; - }; - }; - - crossPackages = lib.mapAttrs (name: targetPkgs: buildCliFor targetPkgs) crossTargets; - in - { - packages = { - cli = buildCliFor pkgs; - } - // (lib.mapAttrs' (name: pkg: lib.nameValuePair "cli-${name}" pkg) crossPackages) - // { - rust-fmt = - pkgs.runCommand "rust-fmt-check" - { - nativeBuildInputs = [ - pkgs.cargo - pkgs.rustfmt - ]; - } - '' - cd ${src} - cargo fmt --all --check - touch $out - ''; - - rust-clippy = pkgs.rustPlatform.buildRustPackage { - inherit src version; - - pname = "rust-clippy-check"; - - cargoLock.lockFile = ../../Cargo.lock; - - nativeBuildInputs = [ - pkgs.pkg-config - pkgs.clippy - pkgs.cmake - pkgs.clang - pkgs.libclang - ]; - - buildPhase = '' - export HOME=$TMPDIR - export LIBCLANG_PATH="${pkgs.libclang.lib}/lib" - cargo xtask clippy - ''; - - installPhase = '' - touch $out - ''; - - doCheck = false; - }; - }; - }; -} diff --git a/crates/cli/package.nix b/crates/cli/package.nix new file mode 100644 index 00000000..584b78e7 --- /dev/null +++ b/crates/cli/package.nix @@ -0,0 +1,60 @@ +{ + lib, + src, + rustPlatform, + version, + pkg-config, + nodejs_22, + test-grammars, + stdenv, + installShellFiles, +}: +let + isCross = stdenv.targetPlatform == stdenv.buildPlatform; +in +rustPlatform.buildRustPackage { + pname = "tree-sitter-cli"; + + inherit src version; + + nativeBuildInputs = [ + pkg-config + nodejs_22 + ] + ++ lib.optionals (!isCross) [ installShellFiles ]; + + cargoLock.lockFile = ../../Cargo.lock; + + preBuild = '' + rm -rf test/fixtures + mkdir -p test/fixtures + cp -r ${test-grammars}/fixtures/* test/fixtures/ + chmod -R u+w test/fixtures + ''; + + preCheck = "export HOME=$TMPDIR"; + doCheck = !isCross; + + postInstall = lib.optionalString (!isCross) '' + installShellCompletion --cmd tree-sitter \ + --bash <($out/bin/tree-sitter complete --shell bash) \ + --zsh <($out/bin/tree-sitter complete --shell zsh) \ + --fish <($out/bin/tree-sitter complete --shell fish) + ''; + + meta = { + description = "Tree-sitter CLI - A tool for developing, testing, and using Tree-sitter parsers"; + longDescription = '' + Tree-sitter is a parser generator tool and an incremental parsing library. + It can build a concrete syntax tree for a source file and efficiently update + the syntax tree as the source file is edited. This package provides the CLI + tool for developing, testing, and using Tree-sitter parsers. + ''; + homepage = "https://tree-sitter.github.io/tree-sitter"; + changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ amaanq ]; + platforms = lib.platforms.all; + mainProgram = "tree-sitter"; + }; +} diff --git a/docs/flake.nix b/docs/flake.nix deleted file mode 100644 index c752bf43..00000000 --- a/docs/flake.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - perSystem = - { - pkgs, - lib, - src, - version, - ... - }: - { - packages.docs = pkgs.stdenv.mkDerivation { - inherit src version; - - pname = "tree-sitter-docs"; - - nativeBuildInputs = [ - pkgs.mdbook - pkgs.mdbook-admonish - ]; - - buildPhase = '' - cd docs - mdbook build - ''; - - installPhase = '' - mkdir -p $out/share/doc - cp -r book $out/share/doc/tree-sitter - ''; - - meta = { - description = "Tree-sitter documentation"; - homepage = "https://tree-sitter.github.io/tree-sitter"; - license = lib.licenses.mit; - }; - }; - }; -} diff --git a/docs/package.nix b/docs/package.nix new file mode 100644 index 00000000..1d07631f --- /dev/null +++ b/docs/package.nix @@ -0,0 +1,33 @@ +{ + stdenv, + lib, + version, + mdbook, + mdbook-admonish, +}: +stdenv.mkDerivation { + inherit version; + + src = ./.; + pname = "tree-sitter-docs"; + + nativeBuildInputs = [ + mdbook + mdbook-admonish + ]; + + buildPhase = '' + mdbook build + ''; + + installPhase = '' + mkdir -p $out/share/doc + cp -r book $out/share/doc/tree-sitter + ''; + + meta = { + description = "Tree-sitter documentation"; + homepage = "https://tree-sitter.github.io/tree-sitter"; + license = lib.licenses.mit; + }; +} diff --git a/flake.lock b/flake.lock index 604baf74..2b1bddae 100644 --- a/flake.lock +++ b/flake.lock @@ -1,44 +1,5 @@ { "nodes": { - "fenix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ], - "rust-analyzer-src": "rust-analyzer-src" - }, - "locked": { - "lastModified": 1756795219, - "narHash": "sha256-tKBQtz1JLKWrCJUxVkHKR+YKmVpm0KZdJdPWmR2slQ8=", - "owner": "nix-community", - "repo": "fenix", - "rev": "80dbdab137f2809e3c823ed027e1665ce2502d74", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "fenix", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1756770412, - "narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "4524271976b625a4a605beefd893f270620fd751", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1756787288, @@ -55,44 +16,10 @@ "type": "github" } }, - "nixpkgs-lib": { - "locked": { - "lastModified": 1754788789, - "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", - "owner": "nix-community", - "repo": "nixpkgs.lib", - "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nixpkgs.lib", - "type": "github" - } - }, "root": { "inputs": { - "fenix": "fenix", - "flake-parts": "flake-parts", "nixpkgs": "nixpkgs" } - }, - "rust-analyzer-src": { - "flake": false, - "locked": { - "lastModified": 1756597274, - "narHash": "sha256-wfaKRKsEVQDB7pQtAt04vRgFphkVscGRpSx3wG1l50E=", - "owner": "rust-lang", - "repo": "rust-analyzer", - "rev": "21614ed2d3279a9aa1f15c88d293e65a98991b30", - "type": "github" - }, - "original": { - "owner": "rust-lang", - "ref": "nightly", - "repo": "rust-analyzer", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index fc5316e3..70d3c474 100644 --- a/flake.nix +++ b/flake.nix @@ -1,111 +1,80 @@ { description = "Tree-sitter - A parser generator tool and an incremental parsing library"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - fenix = { - url = "github:nix-community/fenix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; outputs = - inputs@{ flake-parts, ... }: - flake-parts.lib.mkFlake { inherit inputs; } { + inputs: + let + inherit (inputs.nixpkgs) lib; + inherit (inputs) self; systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + eachSystem = lib.genAttrs systems; + pkgsFor = inputs.nixpkgs.legacyPackages; - imports = [ - ./crates/cli/flake.nix - ./lib/flake.nix - ./lib/binding_web/flake.nix - ./docs/flake.nix - ]; + version = "0.26.0"; - perSystem = - { - self', - pkgs, - lib, - system, - ... - }: + fs = lib.fileset; + src = fs.toSource { + root = ./.; + fileset = fs.difference (fs.gitTracked ./.) ( + fs.unions [ + ./.envrc + ./flake.lock + ./FUNDING.json + ./README.md + ./Dockerfile + (fs.fileFilter (file: lib.strings.hasInfix ".git" file.name) ./.) + (fs.fileFilter (file: file.hasExt "nix") ./.) + ] + ); + }; + fixturesJson = lib.importJSON ./test/fixtures/fixtures.json; + + grammarHashes = { + bash = "sha256-vRaN/mNfpR+hdv2HVS1bzaW0o+HGjizRFsk3iinICJE="; + c = "sha256-gmzbdwvrKSo6C1fqTJFGxy8x0+T+vUTswm7F5sojzKc="; + cpp = "sha256-tP5Tu747V8QMCEBYwOEmMQUm8OjojpJdlRmjcJTbe2k="; + embedded-template = "sha256-nBQain0Lc21jOgQFfvkyq615ZmT8qdMxtqIoUcOcO3A="; + go = "sha256-y7bTET8ypPczPnMVlCaiZuswcA7vFrDOc2jlbfVk5Sk="; + html = "sha256-Pd5Me1twLGOrRB3pSMVX9M8VKenTK0896aoLznjNkGo="; + java = "sha256-OvEO1BLZLjP3jt4gar18kiXderksFKO0WFXDQqGLRIY="; + javascript = "sha256-2Jj/SUG+k8lHlGSuPZvHjJojvQFgDiZHZzH8xLu7suE="; + jsdoc = "sha256-Azzb2zBjAfwbEmAEO1YqhpaxtzbXmRjfIzRla2Hx+24="; + json = "sha256-DNZC2cTy1C8OaMOpEHM6NoRtOIbLaBf0CLXXWCKODlw="; + php = "sha256-jI7yzcoHS/tNxUqJI4aD1rdEZV3jMn1GZD0J+81Dyf0="; + python = "sha256-71Od4sUsxGEvTwmXX8hBvzqD55hnXkVJublrhp1GICg="; + ruby = "sha256-iu3MVJl0Qr/Ba+aOttmEzMiVY6EouGi5wGOx5ofROzA="; + rust = "sha256-y3sJURlSTM7LRRN5WGIAeslsdRZU522Tfcu6dnXH/XQ="; + typescript = "sha256-CU55+YoFJb6zWbJnbd38B7iEGkhukSVpBN7sli6GkGY="; + }; + + grammarSpecs = lib.listToAttrs ( + map (fixture: { + name = lib.elemAt fixture 0; + value = { + rev = lib.elemAt fixture 1; + sha256 = grammarHashes.${lib.elemAt fixture 0}; + }; + }) fixturesJson + ); + filesWithExtension = + ext: + fs.toSource { + root = ./.; + fileset = fs.fileFilter (file: (file.hasExt ext) && file.type == "regular") ./.; + }; + in + { + packages = eachSystem ( + system: let - version = "0.26.0"; - - fenix = inputs.fenix.packages.${system}; - rustToolchain = fenix.complete.withComponents [ - "cargo" - "clippy" - "rust-src" - "rustc" - "rustfmt" - ]; - - src = pkgs.lib.cleanSourceWith { - src = ./.; - filter = - name: type: - let - baseName = baseNameOf name; - in - !( - lib.elem baseName [ - "target" - "node_modules" - ".git" - ".direnv" - "flake.lock" - ] - || lib.hasPrefix "result" baseName - ); - }; - - fixturesJson = lib.importJSON ./test/fixtures/fixtures.json; - - grammarHashes = { - bash = "sha256-vRaN/mNfpR+hdv2HVS1bzaW0o+HGjizRFsk3iinICJE="; - c = "sha256-gmzbdwvrKSo6C1fqTJFGxy8x0+T+vUTswm7F5sojzKc="; - cpp = "sha256-tP5Tu747V8QMCEBYwOEmMQUm8OjojpJdlRmjcJTbe2k="; - embedded-template = "sha256-nBQain0Lc21jOgQFfvkyq615ZmT8qdMxtqIoUcOcO3A="; - go = "sha256-y7bTET8ypPczPnMVlCaiZuswcA7vFrDOc2jlbfVk5Sk="; - html = "sha256-Pd5Me1twLGOrRB3pSMVX9M8VKenTK0896aoLznjNkGo="; - java = "sha256-OvEO1BLZLjP3jt4gar18kiXderksFKO0WFXDQqGLRIY="; - javascript = "sha256-2Jj/SUG+k8lHlGSuPZvHjJojvQFgDiZHZzH8xLu7suE="; - jsdoc = "sha256-Azzb2zBjAfwbEmAEO1YqhpaxtzbXmRjfIzRla2Hx+24="; - json = "sha256-DNZC2cTy1C8OaMOpEHM6NoRtOIbLaBf0CLXXWCKODlw="; - php = "sha256-jI7yzcoHS/tNxUqJI4aD1rdEZV3jMn1GZD0J+81Dyf0="; - python = "sha256-71Od4sUsxGEvTwmXX8hBvzqD55hnXkVJublrhp1GICg="; - ruby = "sha256-iu3MVJl0Qr/Ba+aOttmEzMiVY6EouGi5wGOx5ofROzA="; - rust = "sha256-y3sJURlSTM7LRRN5WGIAeslsdRZU522Tfcu6dnXH/XQ="; - typescript = "sha256-CU55+YoFJb6zWbJnbd38B7iEGkhukSVpBN7sli6GkGY="; - }; - - grammarSpecs = lib.listToAttrs ( - map (fixture: { - name = lib.elemAt fixture 0; - value = { - rev = lib.elemAt fixture 1; - sha256 = grammarHashes.${lib.elemAt fixture 0}; - }; - }) fixturesJson - ); - - fetchGrammar = - name: rev: sha256: - pkgs.fetchFromGitHub { - owner = "tree-sitter"; - repo = "tree-sitter-${name}"; - inherit rev sha256; - }; - - testGrammars = lib.mapAttrs (name: spec: fetchGrammar name spec.rev spec.sha256) grammarSpecs; - + pkgs = pkgsFor.${system}; crossTargets = { aarch64-linux = pkgs.pkgsCross.aarch64-multiplatform; armv7l-linux = pkgs.pkgsCross.armv7l-hf-multiplatform; @@ -126,16 +95,26 @@ x86_64-darwin = pkgs.pkgsCross.x86_64-darwin; aarch64-darwin = pkgs.pkgsCross.aarch64-darwin; }); + in { - _module.args = { - inherit src version crossTargets; - }; + default = self.packages.${system}.cli; - packages = { - default = self'.packages.cli; + docs = pkgs.callPackage ./docs/package.nix { inherit version; }; - test-grammars = pkgs.stdenv.mkDerivation { + test-grammars = + let + fetchGrammar = + name: rev: sha256: + pkgs.fetchFromGitHub { + owner = "tree-sitter"; + repo = "tree-sitter-${name}"; + inherit rev sha256; + }; + + testGrammars = lib.mapAttrs (name: spec: fetchGrammar name spec.rev spec.sha256) grammarSpecs; + in + pkgs.stdenv.mkDerivation { inherit src version; pname = "test-grammars"; @@ -152,120 +131,219 @@ cp -r test/fixtures $out/fixtures ''; }; + + wasm-test-grammars = pkgs.callPackage ./lib/binding_web/wasm-test-grammars.nix { + inherit src version; + inherit (self.packages.${system}) cli test-grammars; }; - apps = { - default = self'.apps.cli; + web-tree-sitter = pkgs.callPackage ./lib/binding_web/package.nix { + inherit src version; + inherit (self.packages.${system}) wasm-test-grammars; + }; - cli = { - type = "app"; - program = "${self'.packages.cli}/bin/tree-sitter"; - meta.description = "Tree-sitter CLI for developing, testing, and using parsers"; - }; + lib = pkgs.callPackage ./lib/package.nix { + inherit src version; + }; - docs = { - type = "app"; - program = "${pkgs.writeShellScript "docs" '' + cli = pkgs.callPackage ./crates/cli/package.nix { + inherit src version; + inherit (self.packages.${system}) test-grammars; + }; + } + // (lib.mapAttrs' (arch: pkg: { + name = "cli-${arch}"; + value = pkg.callPackage ./crates/cli/package.nix { + inherit src version; + inherit (self.packages.${system}) test-grammars; + }; + }) crossTargets) + // (lib.mapAttrs' (arch: pkg: { + name = "lib-${arch}"; + value = pkg.callPackage ./lib/package.nix { + inherit src version; + }; + }) crossTargets) + ); + + apps = eachSystem ( + system: + let + pkgs = pkgsFor.${system}; + in + { + default = self.apps.${system}.cli; + + cli = { + type = "app"; + program = "${lib.getExe self.packages.${system}.cli}"; + meta.description = "Tree-sitter CLI for developing, testing, and using parsers"; + }; + + docs = { + type = "app"; + program = lib.getExe ( + pkgs.writeShellScriptBin "docs" '' echo "📚 Serving documentation at http://localhost:3000" - cd docs && ${pkgs.mdbook}/bin/mdbook serve - ''}"; - meta.description = "Serve Tree-sitter documentation locally"; - }; - - format = { - type = "app"; - program = toString ( - pkgs.writeShellScript "format-all" '' - set -e - echo "Formatting..." - echo "" - echo "→ Rust..." - ${pkgs.cargo}/bin/cargo fmt --all - echo "→ Nix..." - ${pkgs.nixfmt-rfc-style}/bin/nixfmt *.nix crates/cli/*.nix lib/*.nix lib/binding_web/*.nix docs/*.nix - echo "→ Web (TypeScript/JavaScript)..." - cd lib/binding_web && ${pkgs.nodejs_22}/bin/npm install --silent && ${pkgs.nodejs_22}/bin/npm run lint:fix - cd ../.. - echo "" - echo "Formatting complete" - '' - ); - meta.description = "Format all Rust and Nix code"; - }; - - lint = { - type = "app"; - program = toString ( - pkgs.writeShellScript "lint-all" '' - set -e - echo "Linting code..." - echo "" - echo "→ Checking Rust formatting..." - ${pkgs.cargo}/bin/cargo fmt --all --check - echo "→ Running clippy..." - ${pkgs.cargo}/bin/cargo clippy --workspace --all-targets -- -D warnings - echo "→ Checking Nix formatting..." - ${pkgs.nixfmt-rfc-style}/bin/nixfmt --check *.nix crates/cli/*.nix lib/*.nix lib/binding_web/*.nix docs/*.nix - echo "→ Checking Web code..." - cd lib/binding_web && ${pkgs.nodejs_22}/bin/npm install --silent && ${pkgs.nodejs_22}/bin/npm run lint - cd ../.. - echo "" - echo "Linting complete" - '' - ); - meta.description = "Run all linting checks"; - }; + cd docs && ${lib.getExe pkgs.mdbook} serve + '' + ); + meta.description = "Serve Tree-sitter documentation locally"; }; - checks = { - inherit (self'.packages) - cli - lib - web-tree-sitter - web-lint - rust-fmt - rust-clippy - ; - - nix-fmt = - pkgs.runCommand "nix-fmt-check" - { - nativeBuildInputs = [ pkgs.nixfmt-rfc-style ]; - } - '' - cd ${src} - nixfmt --check *.nix crates/cli/*.nix lib/*.nix lib/binding_web/*.nix docs/*.nix - touch $out - ''; + format = { + type = "app"; + program = lib.getExe ( + pkgs.writeShellScriptBin "format-all" '' + set -e + echo "Formatting..." + echo "" + echo "→ Rust..." + ${lib.getExe pkgs.cargo} fmt --all + echo "→ Nix..." + ${lib.getExe pkgs.nixfmt} ${filesWithExtension "nix"} + echo "→ Web (TypeScript/JavaScript)..." + cd lib/binding_web && ${pkgs.nodejs_22}/bin/npm install --silent && ${pkgs.nodejs_22}/bin/npm run lint:fix + cd ../.. + echo "" + echo "Formatting complete" + '' + ); + meta.description = "Format all Rust and Nix code"; }; - formatter = pkgs.nixfmt-rfc-style; + lint = { + type = "app"; + program = lib.getExe ( + pkgs.writeShellScriptBin "lint-all" '' + set -e + echo "Linting code..." + echo "" + echo "→ Checking Rust formatting..." + ${lib.getExe pkgs.cargo} fmt --all --check + echo "→ Running clippy..." + ${lib.getExe pkgs.cargo} clippy --workspace --all-targets -- -D warnings + echo "→ Checking Nix formatting..." + ${lib.getExe pkgs.nixfmt} --check ${filesWithExtension "nix"} + echo "→ Checking Web code..." + cd lib/binding_web && ${lib.getExe' pkgs.nodejs_22 "npm"} install --silent && ${lib.getExe' pkgs.nodejs_22 "npm"} run lint + cd ../.. + echo "" + echo "Linting complete" + '' + ); + meta.description = "Run all linting checks"; + }; + } + ); - devShells.default = pkgs.mkShell { - buildInputs = [ - pkgs.cargo - pkgs.rustc - pkgs.clippy - pkgs.rust-analyzer - pkgs.rustfmt - pkgs.cargo-cross + checks = eachSystem ( + system: + let + pkgs = pkgsFor.${system}; + in + { + inherit (self.packages.${system}) + cli + lib + web-tree-sitter + ; - pkgs.cmake - pkgs.gnumake - pkgs.pkg-config - pkgs.clang - pkgs.libclang + nix-fmt = pkgs.runCommandNoCC "nix-fmt-check" { } '' + ${lib.getExe self.formatter.${system}} --check ${filesWithExtension "nix"} + touch $out + ''; + rust-fmt = pkgs.runCommandNoCC "rust-fmt-check" { } '' + ${lib.getExe pkgs.rustfmt} --check + touch $out + ''; - pkgs.nodejs_22 - pkgs.nodePackages.typescript - pkgs.emscripten - pkgs.pkgsCross.wasi32.stdenv.cc + rust-clippy = pkgs.rustPlatform.buildRustPackage { + inherit src version; - pkgs.mdbook - pkgs.mdbook-admonish + pname = "rust-clippy-check"; - pkgs.git - pkgs.nixfmt-rfc-style + cargoLock.lockFile = ./Cargo.lock; + + nativeBuildInputs = with pkgs; [ + pkg-config + clippy + cmake + clang + libclang + ]; + + buildPhase = '' + export HOME=$TMPDIR + export LIBCLANG_PATH="${pkgs.libclang.lib}/lib" + cargo xtask clippy + ''; + + installPhase = '' + touch $out + ''; + + doCheck = false; + }; + + web-lint = pkgs.buildNpmPackage { + inherit src version; + + pname = "web-tree-sitter-lint"; + + npmDepsHash = "sha256-y0GobcskcZTmju90TM64GjeWiBmPFCrTOg0yfccdB+Q="; + + postPatch = '' + cp lib/binding_web/package{,-lock}.json . + ''; + + buildPhase = '' + cd lib/binding_web + npm run lint + ''; + + installPhase = '' + touch $out + ''; + + meta.description = "Lint check for web-tree-sitter TypeScript/JavaScript code"; + }; + } + ); + + formatter = eachSystem (system: pkgsFor.${system}.nixfmt); + + devShells = eachSystem ( + system: + let + pkgs = pkgsFor.${system}; + in + { + default = pkgs.mkShell { + buildInputs = with pkgs; [ + cargo + rustc + clippy + rust-analyzer + rustfmt + cargo-cross + + cmake + gnumake + pkg-config + clang + libclang + + nodejs_22 + nodePackages.typescript + emscripten + pkgsCross.wasi32.stdenv.cc + + mdbook + mdbook-admonish + + git + nixfmt ]; shellHook = '' @@ -311,9 +389,13 @@ echo "Version: ${version}" ''; - RUST_BACKTRACE = 1; - LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; + env = { + RUST_BACKTRACE = 1; + LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; + TREE_SITTER_WASI_SDK_PATH = "${pkgs.pkgsCross.wasi32.stdenv.cc}"; + }; }; - }; + } + ); }; } diff --git a/lib/binding_web/flake.nix b/lib/binding_web/flake.nix deleted file mode 100644 index 7ceb3fce..00000000 --- a/lib/binding_web/flake.nix +++ /dev/null @@ -1,158 +0,0 @@ -{ - perSystem = - { - self', - pkgs, - lib, - src, - version, - ... - }: - let - grammars = [ - "bash" - "c" - "cpp" - "embedded-template" - "html" - "javascript" - "json" - "python" - "rust" - "typescript" - ]; - - wasmTestGrammars = pkgs.stdenv.mkDerivation { - inherit src version; - - pname = "wasm-test-grammars"; - - nativeBuildInputs = [ - self'.packages.cli - pkgs.pkgsCross.wasi32.stdenv.cc - pkgs.nodejs_22 - ]; - - buildPhase = '' - export HOME=$TMPDIR - export TREE_SITTER_WASI_SDK_PATH=${pkgs.pkgsCross.wasi32.stdenv.cc} - export NIX_LDFLAGS="" - - cp -r ${self'.packages.test-grammars}/fixtures . - chmod -R u+w fixtures - - for grammar in ${lib.concatStringsSep " " grammars}; do - if [ -d "fixtures/grammars/$grammar" ]; then - echo "Building WASM for $grammar" - - if [ "$grammar" = "typescript" ]; then - tree-sitter build --wasm -o "tree-sitter-typescript.wasm" "fixtures/grammars/$grammar/typescript" - tree-sitter build --wasm -o "tree-sitter-tsx.wasm" "fixtures/grammars/$grammar/tsx" - else - tree-sitter build --wasm -o "tree-sitter-$grammar.wasm" "fixtures/grammars/$grammar" - fi - fi - done - ''; - - installPhase = '' - mkdir -p $out - for wasm in *.wasm; do - if [ -f "$wasm" ]; then - echo "Installing $wasm" - cp "$wasm" $out/ - fi - done - ''; - }; - in - { - packages = { - web-tree-sitter = pkgs.buildNpmPackage { - inherit src version; - - pname = "web-tree-sitter"; - - npmDepsHash = "sha256-y0GobcskcZTmju90TM64GjeWiBmPFCrTOg0yfccdB+Q="; - - nativeBuildInputs = [ - pkgs.rustPlatform.cargoSetupHook - pkgs.cargo - pkgs.pkg-config - pkgs.emscripten - ]; - - cargoDeps = pkgs.rustPlatform.importCargoLock { - lockFile = ../../Cargo.lock; - }; - - doCheck = true; - - postPatch = '' - cp lib/binding_web/package{,-lock}.json . - ''; - - buildPhase = '' - cd lib/binding_web - CJS=true npm run build - CJS=true npm run build:debug - npm run build:debug - npm run build - ''; - - checkPhase = '' - cd ../../ - mkdir -p target/release - - for grammar in ${wasmTestGrammars}/*.wasm; do - if [ -f "$grammar" ]; then - cp "$grammar" target/release/ - fi - done - - cd lib/binding_web && npm test - ''; - - meta = { - description = "web-tree-sitter - WebAssembly bindings to the Tree-sitter parsing library."; - longDescription = '' - web-tree-sitter provides WebAssembly bindings to the Tree-sitter parsing library. - It can build a concrete syntax tree for a source file and efficiently update - the syntax tree as the source file is edited. This package provides the WebAssembly bindings - and a JavaScript API for using them in web browsers - ''; - homepage = "https://tree-sitter.github.io/tree-sitter"; - changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}"; - license = lib.licenses.mit; - maintainers = [ lib.maintainers.amaanq ]; - platforms = lib.platforms.all; - }; - }; - - web-lint = pkgs.buildNpmPackage { - inherit src version; - - pname = "web-tree-sitter-lint"; - - npmDepsHash = "sha256-y0GobcskcZTmju90TM64GjeWiBmPFCrTOg0yfccdB+Q="; - - postPatch = '' - cp lib/binding_web/package{,-lock}.json . - ''; - - buildPhase = '' - cd lib/binding_web - npm run lint - ''; - - installPhase = '' - touch $out - ''; - - meta = { - description = "Lint check for web-tree-sitter TypeScript/JavaScript code"; - }; - }; - }; - }; -} diff --git a/lib/binding_web/package.nix b/lib/binding_web/package.nix new file mode 100644 index 00000000..83f286b5 --- /dev/null +++ b/lib/binding_web/package.nix @@ -0,0 +1,73 @@ +{ + wasm-test-grammars, + lib, + buildNpmPackage, + rustPlatform, + cargo, + pkg-config, + emscripten, + src, + version, +}: +buildNpmPackage { + inherit src version; + + pname = "web-tree-sitter"; + + npmDepsHash = "sha256-y0GobcskcZTmju90TM64GjeWiBmPFCrTOg0yfccdB+Q="; + + nativeBuildInputs = [ + rustPlatform.cargoSetupHook + cargo + pkg-config + emscripten + ]; + + cargoDeps = rustPlatform.importCargoLock { + lockFile = ../../Cargo.lock; + }; + + doCheck = true; + + postPatch = '' + cp lib/binding_web/package{,-lock}.json . + ''; + + buildPhase = '' + pushd lib/binding_web + + CJS=true npm run build + CJS=true npm run build:debug + npm run build:debug + npm run build + + popd + + mkdir -p target/release + + for grammar in ${wasm-test-grammars}/*.wasm; do + if [ -f "$grammar" ]; then + cp "$grammar" target/release/ + fi + done + ''; + + checkPhase = '' + cd lib/binding_web && npm test + ''; + + meta = { + description = "web-tree-sitter - WebAssembly bindings to the Tree-sitter parsing library."; + longDescription = '' + web-tree-sitter provides WebAssembly bindings to the Tree-sitter parsing library. + It can build a concrete syntax tree for a source file and efficiently update + the syntax tree as the source file is edited. This package provides the WebAssembly bindings + and a JavaScript API for using them in web browsers + ''; + homepage = "https://tree-sitter.github.io/tree-sitter"; + changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ amaanq ]; + platforms = lib.platforms.all; + }; +} diff --git a/lib/binding_web/wasm-test-grammars.nix b/lib/binding_web/wasm-test-grammars.nix new file mode 100644 index 00000000..536359d3 --- /dev/null +++ b/lib/binding_web/wasm-test-grammars.nix @@ -0,0 +1,67 @@ +{ + cli, + lib, + nodejs_22, + pkgsCross, + src, + stdenv, + test-grammars, + version, +}: +let + grammars = [ + "bash" + "c" + "cpp" + "embedded-template" + "html" + "javascript" + "json" + "python" + "rust" + "typescript" + ]; +in +stdenv.mkDerivation { + inherit src version; + + pname = "wasm-test-grammars"; + + nativeBuildInputs = [ + cli + pkgsCross.wasi32.stdenv.cc + nodejs_22 + ]; + + buildPhase = '' + export HOME=$TMPDIR + export TREE_SITTER_WASI_SDK_PATH=${pkgsCross.wasi32.stdenv.cc} + export NIX_LDFLAGS="" + + cp -r ${test-grammars}/fixtures . + chmod -R u+w fixtures + + for grammar in ${lib.concatStringsSep " " grammars}; do + if [ -d "fixtures/grammars/$grammar" ]; then + echo "Building WASM for $grammar" + + if [ "$grammar" = "typescript" ]; then + tree-sitter build --wasm -o "tree-sitter-typescript.wasm" "fixtures/grammars/$grammar/typescript" + tree-sitter build --wasm -o "tree-sitter-tsx.wasm" "fixtures/grammars/$grammar/tsx" + else + tree-sitter build --wasm -o "tree-sitter-$grammar.wasm" "fixtures/grammars/$grammar" + fi + fi + done + ''; + + installPhase = '' + mkdir -p $out + for wasm in *.wasm; do + if [ -f "$wasm" ]; then + echo "Installing $wasm" + cp "$wasm" $out/ + fi + done + ''; +} diff --git a/lib/flake.nix b/lib/flake.nix deleted file mode 100644 index cf49e4c0..00000000 --- a/lib/flake.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ - perSystem = - { - pkgs, - lib, - src, - version, - crossTargets, - ... - }: - let - buildLibFor = - targetPkgs: - let - isCross = targetPkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform; - in - targetPkgs.stdenv.mkDerivation { - inherit src version; - - pname = "tree-sitter"; - - nativeBuildInputs = [ - targetPkgs.cmake - targetPkgs.pkg-config - ]; - - sourceRoot = "source/lib"; - - cmakeFlags = [ - "-DBUILD_SHARED_LIBS=ON" - "-DCMAKE_INSTALL_LIBDIR=lib" - "-DCMAKE_INSTALL_INCLUDEDIR=include" - "-DTREE_SITTER_FEATURE_WASM=OFF" - ]; - - enableParallelBuilding = true; - - postInstall = '' - mkdir -p $out/{lib/pkgconfig,share/tree-sitter} - substituteInPlace $out/lib/pkgconfig/tree-sitter.pc \ - --replace-fail "\''${prefix}" "$out" 2>/dev/null - ''; - - meta = { - description = "Tree-sitter incremental parsing library"; - longDescription = '' - Tree-sitter is a parser generator tool and an incremental parsing library. - It can build a concrete syntax tree for a source file and efficiently update - the syntax tree as the source file is edited. This package provides the core - C library that can be used to parse source code using Tree-sitter grammars. - ''; - homepage = "https://tree-sitter.github.io/tree-sitter"; - changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}"; - license = lib.licenses.mit; - maintainers = [ lib.maintainers.amaanq ]; - platforms = lib.platforms.all; - }; - }; - - crossPackages = lib.mapAttrs (name: targetPkgs: buildLibFor targetPkgs) crossTargets; - in - { - packages = { - lib = buildLibFor pkgs; - } - // (lib.mapAttrs' (name: pkg: lib.nameValuePair "lib-${name}" pkg) crossPackages); - }; -} diff --git a/lib/package.nix b/lib/package.nix new file mode 100644 index 00000000..2b59ae9a --- /dev/null +++ b/lib/package.nix @@ -0,0 +1,49 @@ +{ + stdenv, + cmake, + pkg-config, + src, + version, + lib, +}: +stdenv.mkDerivation { + inherit src version; + pname = "tree-sitter"; + + nativeBuildInputs = [ + cmake + pkg-config + ]; + + sourceRoot = "source/lib"; + + cmakeFlags = [ + "-DBUILD_SHARED_LIBS=ON" + "-DCMAKE_INSTALL_LIBDIR=lib" + "-DCMAKE_INSTALL_INCLUDEDIR=include" + "-DTREE_SITTER_FEATURE_WASM=OFF" + ]; + + enableParallelBuilding = true; + + postInstall = '' + mkdir -p $out/{lib/pkgconfig,share/tree-sitter} + substituteInPlace $out/lib/pkgconfig/tree-sitter.pc \ + --replace-fail "\''${prefix}" "$out" 2>/dev/null + ''; + + meta = { + description = "Tree-sitter incremental parsing library"; + longDescription = '' + Tree-sitter is a parser generator tool and an incremental parsing library. + It can build a concrete syntax tree for a source file and efficiently update + the syntax tree as the source file is edited. This package provides the core + C library that can be used to parse source code using Tree-sitter grammars. + ''; + homepage = "https://tree-sitter.github.io/tree-sitter"; + changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}"; + license = lib.licenses.mit; + maintainers = [ lib.maintainers.amaanq ]; + platforms = lib.platforms.all; + }; +}