{
  description = "Yama and Datman";

  inputs = {
    utils.url = "github:numtide/flake-utils";
    naersk.url = "github:nix-community/naersk";
  };

  outputs = { self, nixpkgs, utils, naersk }:
    utils.lib.eachDefaultSystem (system: let
      pkgs = nixpkgs.legacyPackages."${system}";
      naersk-lib = naersk.lib."${system}";

      rustComponents = naersk-lib.buildPackage {
        pname = "yama";
        root = ./.;

        buildInputs = with pkgs; [
          openssl
          pkgconfig
          sqlite
        ];
      };

      mysqlHelper = pkgs.poetry2nix.mkPoetryApplication {
        projectDir = ./datman-helper-mysql;
      };

      postgresHelper = pkgs.poetry2nix.mkPoetryApplication {
        projectDir = ./datman-helper-postgres;
      };

      # We want to produce a package with all of these together, with wrappers that let them
      # refer to each other by name (i.e. have each other on the path).
      # Datman needs the helpers on the path.
      # The helpers need lz4 on the path.
      allInOne = pkgs.stdenv.mkDerivation {
        name = "datman-aio";

        src = "${pkgs.emptyDirectory}";

        installPhase = ''
          # set -eu
          mkdir $out $out/bin
          ln -s ${rustComponents}/bin/{yama,datman} $out/bin
          ln -s ${mysqlHelper}/bin/datman-helper-mysql-{backup,restore} $out/bin
          ln -s ${postgresHelper}/bin/datman-helper-postgres-{backup,restore} $out/bin
          ln -s ${pkgs.lz4}/bin/lz4 $out/bin/
          runHook postInstall
        '';

        buildInputs = [ pkgs.makeWrapper ];

        postInstall = ''
          # set -eu
          for fn in $out/bin/{datman,yama,datman-helper-{mysql,postgres}-{backup,restore}}; do
            wrapProgram $fn --suffix PATH : $out/bin
          done
        '';
      };
    in rec {
      # `nix build`
      packages.yama = allInOne;

      defaultPackage = packages.yama;

      # NixOS Modules
#       nixosModules = {
#         yama = import ./nixos_modules/yama.nix self;
#       };

      # `nix run`
      apps.yama = utils.lib.mkApp {
        drv = rustComponents;
      };
      defaultApp = apps.yama;

      # `nix develop`
      devShell = pkgs.mkShell {
        nativeBuildInputs = with pkgs; [ rustc cargo ];
      };
    });
}