{ inputs = { nixpkgs.url = "github:nixos/nixpkgs/release-22.05"; flake-utils.url = "github:numtide/flake-utils/master"; rust-overlay = { url = "github:oxalica/rust-overlay/master"; inputs = { flake-utils.follows = "flake-utils"; nixpkgs.follows = "nixpkgs"; }; }; naersk = { url = "github:nmattia/naersk/master"; inputs.nixpkgs.follows = "nixpkgs"; }; }; description = "thulani discord bot"; outputs = { self, nixpkgs, flake-utils, ... } @ inputs: let buildToolchain = pkgs: pkgs.rust-bin.nightly."2022-11-20".minimal; deps = pkgs: with pkgs; [ openssl pkgconfig libopus postgresql ]; mkPkg = pkgs: let buildToolchain = buildToolchain pkgs; naersk = pkgs.callPackage inputs.naersk { cargo = buildToolchain; rustc = buildToolchain; }; inherit (pkgs) lib; in naersk.buildPackage { pname = "thulani"; version = self.rev or "dirty"; src = lib.cleanSource ./.; nativeBuildInputs = deps pkgs; remapPathPrefix = true; }; in (flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; overlays = [ (import inputs.rust-overlay) ]; }; devToolchain = (buildToolchain pkgs).override { extensions = [ "rust-src" "rust-analyzer" "clippy" "rust-docs" "rustfmt" ]; }; pkg = mkPkg pkgs; in { devShells.default = pkgs.mkShell { buildInputs = (with pkgs; [ devToolchain ]) ++ (deps pkgs); RUST_SRC_PATH = "${devToolchain}/lib/rustlib/src/rust"; }; packages.default = pkg; apps.default = { type = "app"; program = "${pkg}/bin/thulani"; }; }) // { overlays.default = final: prev: let withRust = (import inputs.rust-overlay) final prev; in { thulani = mkPkg withRust; }; nixosModules.default = { pkgs, lib, config, ... }: let cfg = config.services.thulani; in { options.services.thulani = with lib; with lib.types; { enable = mkEnableOption "thulani"; package = mkOption { description = "thulani derivation to use"; type = package; default = pkgs.thulani; }; environment = mkOption { description = "literal environment to include"; type = attrsOf str; default = {}; }; envFiles = mkOption { description = "environment files to include"; type = listOf path; default = []; }; user = mkOption { description = "user to run service as"; type = str; default = "thulani"; }; group = mkOption { description = "group to run service as"; type = str; default = "thulani"; }; postgres = mkOption { description = "local postgres server with automatic setup"; type = sumodule { enable = mkEnableOption "postgres"; db = mkOption { description = "db name"; type = str; default = "memes"; }; }; }; }; config = lib.mkIf cfg.enable { systemd.services.thulani = { description = "thulani bot"; wantedBy = [ "multi-user.target" ]; bindsTo = [ "network-online.target" ]; after = [ "network-online.target" ]; preStart = lib.mkIf (cfg.postgres.enable) (let invokePsql = "${pkgs.sudo}/bin/sudo -u ${config.services.postgresql.superUser} -- ${config.services.postgresql.package}/bin/psql"; in '' ${invokePsql} <