Something went wrong. Try again.
A small configuration language for Zig: ZON with let, if and templates over a context, evaluated to a struct, always finishing.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144# SPDX-FileCopyrightText: © 2026 Jeffrey C. Ollie <jeff@ocjtech.us># SPDX-License-Identifier: MIT
{ description = "struthio: a small configuration language for Zig that evaluates to a struct";
inputs = { nixpkgs = { url = "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"; }; zon2nix = { url = "github:jcollie/zon2nix"; inputs = { nixpkgs.follows = "nixpkgs"; }; }; };
outputs = { nixpkgs, zon2nix, ... }: let inherit (nixpkgs) lib; makePackages = system: import nixpkgs { inherit system; }; forAllSystems = lib.genAttrs lib.systems.flakeExposed;
# The tree-sitter grammar's own files, without the rest of the # repository, so that editing the Zig does not rebuild it. treeSitterSource = lib.fileset.toSource { root = ./tree-sitter-struthio; fileset = ./tree-sitter-struthio; }; in { packages = forAllSystems ( system: let pkgs = makePackages system; in rec { struthio = pkgs.callPackage ./package.nix { }; default = struthio; # The Zig dependencies on their own, laid out as `zig build # --system` wants them, for a build that is not the package's. zig-deps = pkgs.callPackage ./build.zig.zon.nix { }; # The grammar compiled for an editor, with its queries beside it. tree-sitter-struthio = pkgs.tree-sitter.buildGrammar { language = "struthio"; version = "0.1.0"; src = treeSitterSource; }; } );
checks = forAllSystems ( system: let pkgs = makePackages system; in { # The parser in `src/` is generated from `grammar.js` and committed, # since that is where editors look for it, and so are the queries # rewritten for Helix. This regenerates both, fails if what is # committed differs, runs the corpus and highlighting tests, and # parses every golden program that the real parser accepts -- the # ones with a `.zon` beside them -- so that the grammar cannot fall # behind the language unnoticed. tree-sitter-struthio = pkgs.runCommandCC "tree-sitter-struthio-test" { nativeBuildInputs = [ pkgs.tree-sitter pkgs.nodejs ]; } '' export HOME=$TMPDIR cp -r --no-preserve=mode ${treeSitterSource} grammar cd grammar tree-sitter generate if ! diff -r ${treeSitterSource}/src src; then echo "src/ is out of date: run 'tree-sitter generate' in tree-sitter-struthio" >&2 exit 1 fi sh helix-queries.sh $TMPDIR/helix if ! diff -r queries/helix $TMPDIR/helix; then echo "queries/helix/ is out of date: run ./helix-queries.sh in tree-sitter-struthio" >&2 exit 1 fi tree-sitter test for zon in ${./tests/golden}/*.zon; do tree-sitter parse --quiet -p . "''${zon%.zon}.struthio" done touch $out ''; } );
devShells = forAllSystems ( system: let pkgs = makePackages system; in { default = pkgs.mkShell { name = "struthio"; nativeBuildInputs = [ pkgs.zig_0_17 pkgs.git-pages-cli pkgs.reuse # Generates and tests the grammar in tree-sitter-struthio/; # generating it runs grammar.js under Node. pkgs.tree-sitter pkgs.nodejs # Regenerates build.zig.zon.nix after a dependency changes: # nix develop -c zon2nix --17 --nix=build.zig.zon.nix build.zig.zon # It runs `zig env`, so it is wrapped to find this Zig. (pkgs.symlinkJoin { name = "zon2nix"; paths = [ zon2nix.packages.${system}.zon2nix ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/zon2nix \ --prefix PATH : ${lib.makeBinPath [ pkgs.zig_0_17 ]} ''; }) ] ++ lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs.kcov pkgs.perf ]; }; } ); };}