diff options
| author | Marcos Magueta <maguetamarcos@gmail.com> | 2024-10-16 00:00:34 -0300 |
|---|---|---|
| committer | Marcos Magueta <maguetamarcos@gmail.com> | 2024-10-16 00:00:34 -0300 |
| commit | 0d01055df0b99bb696fb6a2e480513cebf8890a3 (patch) | |
| tree | 9ffb06c9803c14b6782ae96a24d22873d4da21dc /flake.nix | |
| download | Sakura-0d01055df0b99bb696fb6a2e480513cebf8890a3.tar.gz Sakura-0d01055df0b99bb696fb6a2e480513cebf8890a3.zip | |
bootstrap project with flake and dune
Diffstat (limited to 'flake.nix')
| -rw-r--r-- | flake.nix | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..2d50b55 --- /dev/null +++ b/flake.nix @@ -0,0 +1,217 @@ +{ + description = "A compiler for a statically-typed relational programming language"; + + # Flake dependency specification + # + # To update all flake inputs: + # + # $ nix flake update --commit-lockfile + # + # To update individual flake inputs: + # + # $ nix flake lock --update-input <input> ... --commit-lockfile + # + inputs = { + # Convenience functions for writing flakes + flake-utils.url = "github:numtide/flake-utils"; + # Precisely filter files copied to the nix store + nix-filter.url = "github:numtide/nix-filter"; + }; + + outputs = { self, nixpkgs, flake-utils, nix-filter }: + # Construct an output set that supports a number of default systems + flake-utils.lib.eachDefaultSystem (system: + let + # Legacy packages that have not been converted to flakes + legacyPackages = nixpkgs.legacyPackages.${system}; + # OCaml packages available on nixpkgs + ocamlPackages = legacyPackages.ocamlPackages; + # Library functions from nixpkgs + lib = legacyPackages.lib; + + # Filtered sources (prevents unecessary rebuilds) + sources = { + ocaml = nix-filter.lib { + root = ./.; + include = [ + ".ocamlformat" + "dune-project" + (nix-filter.lib.inDirectory "bin") + (nix-filter.lib.inDirectory "lib") + (nix-filter.lib.inDirectory "test") + ]; + }; + + nix = nix-filter.lib { + root = ./.; + include = [ + (nix-filter.lib.matchExt "nix") + ]; + }; + }; + in + { + # Exposed packages that can be built or run with `nix build` or + # `nix run` respectively: + # + # $ nix build .#<name> + # $ nix run .#<name> -- <args?> + # + packages = { + # The package that will be built or run by default. For example: + # + # $ nix build + # $ nix run -- <args?> + # + default = self.packages.${system}.relational_engine; + + relational_engine = ocamlPackages.buildDunePackage { + pname = "relational_engine"; + version = "0.1.0"; + duneVersion = "3"; + src = sources.ocaml; + + buildInputs = [ + # Ocaml package dependencies needed to build go here. + ]; + + strictDeps = true; + + preBuild = '' + dune build relational_engine.opam + ''; + }; + }; + + # Flake checks + # + # $ nix flake check + # + checks = { + # Run tests for the `relational_engine` package + relational_engine = + let + # Patches calls to dune commands to produce log-friendly output + # when using `nix ... --print-build-log`. Ideally there would be + # support for one or more of the following: + # + # In Dune: + # + # - have workspace-specific dune configuration files + # + # In NixPkgs: + # + # - allow dune flags to be set in in `ocamlPackages.buildDunePackage` + # - alter `ocamlPackages.buildDunePackage` to use `--display=short` + # - alter `ocamlPackages.buildDunePackage` to allow `--config-file=FILE` to be set + patchDuneCommand = + let + subcmds = [ "build" "test" "runtest" "install" ]; + in + lib.replaceStrings + (lib.lists.map (subcmd: "dune ${subcmd}") subcmds) + (lib.lists.map (subcmd: "dune ${subcmd} --display=short") subcmds); + in + + self.packages.${system}.relational_engine.overrideAttrs + (oldAttrs: { + name = "check-${oldAttrs.name}"; + doCheck = true; + buildPhase = patchDuneCommand oldAttrs.buildPhase; + checkPhase = patchDuneCommand oldAttrs.checkPhase; + # skip installation (this will be tested in the `relational_engine-app` check) + installPhase = "touch $out"; + }); + + # Check Dune and OCaml formatting + dune-fmt = legacyPackages.runCommand "check-dune-fmt" + { + nativeBuildInputs = [ + ocamlPackages.dune_3 + ocamlPackages.ocaml + legacyPackages.ocamlformat + ]; + } + '' + echo "checking dune and ocaml formatting" + dune build \ + --display=short \ + --no-print-directory \ + --root="${sources.ocaml}" \ + --build-dir="$(pwd)/_build" \ + @fmt + touch $out + ''; + + # Check documentation generation + dune-doc = legacyPackages.runCommand "check-dune-doc" + { + ODOC_WARN_ERROR = "true"; + nativeBuildInputs = [ + ocamlPackages.dune_3 + ocamlPackages.ocaml + ocamlPackages.odoc + ]; + } + '' + echo "checking ocaml documentation" + dune build \ + --display=short \ + --no-print-directory \ + --root="${sources.ocaml}" \ + --build-dir="$(pwd)/_build" \ + @doc + touch $out + ''; + + # Check Nix formatting + nixpkgs-fmt = legacyPackages.runCommand "check-nixpkgs-fmt" + { nativeBuildInputs = [ legacyPackages.nixpkgs-fmt ]; } + '' + echo "checking nix formatting" + nixpkgs-fmt --check ${sources.nix} + touch $out + ''; + }; + + # Development shells + # + # $ nix develop .#<name> + # $ nix develop .#<name> --command dune build @test + # + # [Direnv](https://direnv.net/) is recommended for automatically loading + # development environments in your shell. For example: + # + # $ echo "use flake" > .envrc && direnv allow + # $ dune build @test + # + devShells = { + default = legacyPackages.mkShell { + # Development tools + packages = [ + # Source file formatting + legacyPackages.nixpkgs-fmt + legacyPackages.ocamlformat + # For `dune build --watch ...` + legacyPackages.fswatch + # For `dune build @doc` + ocamlPackages.odoc + # OCaml editor support + ocamlPackages.ocaml-lsp + # Nicely formatted types on hover + ocamlPackages.ocamlformat-rpc-lib + # Fancy REPL thing + ocamlPackages.utop + # Libraries + ocamlPackages.menhir + ocamlPackages.batteries + ]; + + # Tools from packages + inputsFrom = [ + self.packages.${system}.relational_engine + ]; + }; + }; + }); +} |
