diff --git a/cliff.toml b/cliff.toml index 51fd829..bda6cec 100644 --- a/cliff.toml +++ b/cliff.toml @@ -55,9 +55,7 @@ postprocessors = [] conventional_commits = false filter_unconventional = false split_commits = false -commit_preprocessors = [ - { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }, -] +commit_preprocessors = [{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" }] filter_commits = false topo_order = false sort_commits = "newest" diff --git a/flake.nix b/flake.nix index 61b751e..0b2c313 100644 --- a/flake.nix +++ b/flake.nix @@ -22,16 +22,22 @@ let pkgs = import nixpkgs { inherit system; }; craneLib = crane.mkLib pkgs; - src = craneLib.cleanCargoSource ./.; - helix-grammar = pkgs.callPackage "${helix}/grammars.nix" { inherit pkgs; }; - rgit-grammar = pkgs.runCommand "consolidated-rgit-grammars" { } '' - mkdir -p $out - for file in ${helix-grammar}/*; do - ln -s "$file" "$out/libtree-sitter-$(basename "$file")" - done - ln -s "${helix}/languages.toml" "$out/languages.toml" - ln -s "${helix}/runtime/queries" "$out/queries" - ''; + cargoOnlySrc = craneLib.cleanCargoSource ./.; + src = pkgs.lib.fileset.toSource { + root = ./.; + fileset = pkgs.lib.fileset.unions [ + ./.cargo + ./Cargo.toml + ./Cargo.lock + ./tree-sitter-grammar-repository + ./src + ./statics + ./templates + ./themes + ./build.rs + ]; + }; + rgit-grammar = pkgs.callPackage ./grammars.nix { inherit helix; }; commonArgs = { inherit src; strictDeps = true; @@ -39,40 +45,23 @@ nativeBuildInputs = with pkgs; [ cmake clang ]; LIBCLANG_PATH = "${pkgs.clang.cc.lib}/lib"; ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; - TREE_SITTER_GRAMMAR_LIB_DIR = "${rgit-grammar}"; }; - cargoArtifacts = craneLib.buildDepsOnly commonArgs; - rgit = craneLib.buildPackage (commonArgs // { + cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { src = cargoOnlySrc; }); + buildArgs = commonArgs // { inherit cargoArtifacts; - doCheck = false; - src = pkgs.lib.fileset.toSource { - root = ./.; - fileset = pkgs.lib.fileset.unions [ - ./.cargo - ./Cargo.toml - ./Cargo.lock - ./tree-sitter-grammar-repository - ./src - ./statics - ./templates - ./themes - ./build.rs - ]; - }; - }); + buildInputs = [ rgit-grammar ] ++ commonArgs.buildInputs; + TREE_SITTER_GRAMMAR_LIB_DIR = rgit-grammar; + }; + rgit = craneLib.buildPackage (buildArgs // { doCheck = false; }); treefmt = treefmt-nix.lib.evalModule pkgs ./treefmt.nix; in { checks = { inherit rgit; - rgit-clippy = craneLib.cargoClippy (commonArgs // { - inherit cargoArtifacts; - cargoClippyExtraArgs = "--all --all-targets --all-features"; - }); - rgit-doc = craneLib.cargoDoc (commonArgs // { inherit cargoArtifacts; }); - rgit-audit = craneLib.cargoAudit { inherit src advisory-db; }; - rgit-test = craneLib.cargoNextest (commonArgs // { - inherit cargoArtifacts; + rgit-clippy = craneLib.cargoClippy buildArgs; + rgit-doc = craneLib.cargoDoc buildArgs; + rgit-audit = craneLib.cargoAudit { inherit advisory-db; src = cargoOnlySrc; }; + rgit-test = craneLib.cargoNextest (buildArgs // { partitions = 1; partitionType = "count"; }); @@ -174,7 +163,7 @@ }); nixConfig = { - extra-substituters = ["https://rgit.cachix.org"]; - extra-trusted-public-keys = ["rgit.cachix.org-1:3Wva/GHhrlhbYx+ObbEYQSYq1Yzk8x9OAvEvcYazgL0="]; + extra-substituters = [ "https://rgit.cachix.org" ]; + extra-trusted-public-keys = [ "rgit.cachix.org-1:3Wva/GHhrlhbYx+ObbEYQSYq1Yzk8x9OAvEvcYazgL0=" ]; }; } diff --git a/grammars.nix b/grammars.nix new file mode 100644 index 0000000..7436389 --- /dev/null +++ b/grammars.nix @@ -0,0 +1,132 @@ +# adapted from https://github.com/helix-editor/helix/blob/217818681ea9bbc7f995c87f8794c46eeb012b1c/grammars.nix +{ stdenv +, lib +, runCommand +, includeGrammarIf ? _: true +, grammarOverlays ? [ ] +, helix +, ... +}: +let + languagesConfig = builtins.fromTOML (builtins.readFile "${helix}/languages.toml"); + isGitGrammar = grammar: + builtins.hasAttr "source" grammar + && builtins.hasAttr "git" grammar.source + && builtins.hasAttr "rev" grammar.source; + isGitHubGrammar = grammar: lib.hasPrefix "https://github.com" grammar.source.git; + toGitHubFetcher = url: + let + match = builtins.match "https://github\.com/([^/]*)/([^/]*)/?" url; + in + { + owner = builtins.elemAt match 0; + repo = builtins.elemAt match 1; + }; + # If `use-grammars.only` is set, use only those grammars. + # If `use-grammars.except` is set, use all other grammars. + # Otherwise use all grammars. + useGrammar = grammar: + if languagesConfig?use-grammars.only then + builtins.elem grammar.name languagesConfig.use-grammars.only + else if languagesConfig?use-grammars.except then + !(builtins.elem grammar.name languagesConfig.use-grammars.except) + else true; + grammarsToUse = builtins.filter useGrammar languagesConfig.grammar; + gitGrammars = builtins.filter isGitGrammar grammarsToUse; + buildGrammar = grammar: + let + gh = toGitHubFetcher grammar.source.git; + sourceGit = builtins.fetchTree { + type = "git"; + url = grammar.source.git; + inherit (grammar.source) rev; + ref = grammar.source.ref or "HEAD"; + shallow = true; + }; + sourceGitHub = builtins.fetchTree { + type = "github"; + inherit (gh) owner; + inherit (gh) repo; + inherit (grammar.source) rev; + }; + source = + if isGitHubGrammar grammar + then sourceGitHub + else sourceGit; + in + stdenv.mkDerivation { + # see https://github.com/NixOS/nixpkgs/blob/fbdd1a7c0bc29af5325e0d7dd70e804a972eb465/pkgs/development/tools/parsing/tree-sitter/grammar.nix + + pname = "tree-sitter-${grammar.name}"; + version = grammar.source.rev; + + src = source; + sourceRoot = + if builtins.hasAttr "subpath" grammar.source then + "source/${grammar.source.subpath}" + else + "source"; + + dontConfigure = true; + + FLAGS = [ + "-Isrc" + "-g" + "-O3" + "-fPIC" + "-fno-exceptions" + "-Wl,-z,relro,-z,now" + ]; + + NAME = "libtree-sitter-${grammar.name}"; + + buildPhase = '' + runHook preBuild + + if [[ -e src/scanner.cc ]]; then + $CXX -c src/scanner.cc -o scanner.o $FLAGS + elif [[ -e src/scanner.c ]]; then + $CC -c src/scanner.c -o scanner.o $FLAGS + fi + + $CC -c src/parser.c -o parser.o $FLAGS + $CXX -shared -install_name $out/$NAME.so -o $NAME.so *.o + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + mkdir $out + mv $NAME.so $out/ + runHook postInstall + ''; + + # Strip failed on darwin: strip: error: symbols referenced by indirect symbol table entries that can't be stripped + fixupPhase = lib.optionalString stdenv.isLinux '' + runHook preFixup + $STRIP $out/$NAME.so + runHook postFixup + ''; + }; + grammarsToBuild = builtins.filter includeGrammarIf gitGrammars; + builtGrammars = builtins.map + (grammar: { + inherit (grammar) name; + value = buildGrammar grammar; + }) + grammarsToBuild; + extensibleGrammars = + lib.makeExtensible (self: builtins.listToAttrs builtGrammars); + overlayedGrammars = lib.pipe extensibleGrammars + (builtins.map (overlay: grammar: grammar.extend overlay) grammarOverlays); + grammarLinks = lib.mapAttrsToList + (name: artifact: "ln -s ${artifact}/libtree-sitter-${name}.so $out/libtree-sitter-${name}.so") + (lib.filterAttrs (n: v: lib.isDerivation v) overlayedGrammars); +in +runCommand "consolidated-rit-grammars" { } '' + mkdir -p $out + ${builtins.concatStringsSep "\n" grammarLinks} + ln -s "${helix}/languages.toml" "$out/languages.toml" + ln -s "${helix}/runtime/queries" "$out/queries" +''