build: fix bot build, add generate commands binding app

This commit is contained in:
dusk 2025-01-04 00:18:10 +09:00
parent a6482d929c
commit 59bba77ae9
No known key found for this signature in database
3 changed files with 184 additions and 142 deletions

View file

@ -48,7 +48,6 @@ public class Context
_commandMessageService = provider.Resolve<CommandMessageService>(); _commandMessageService = provider.Resolve<CommandMessageService>();
CommandPrefix = message.Content?.Substring(0, commandParseOffset); CommandPrefix = message.Content?.Substring(0, commandParseOffset);
DefaultPrefix = prefixes[0]; DefaultPrefix = prefixes[0];
Parameters = new Parameters(message.Content?.Substring(commandParseOffset));
Rest = provider.Resolve<DiscordApiClient>(); Rest = provider.Resolve<DiscordApiClient>();
Cluster = provider.Resolve<Cluster>(); Cluster = provider.Resolve<Cluster>();
@ -87,7 +86,7 @@ public class Context
public readonly string CommandPrefix; public readonly string CommandPrefix;
public readonly string DefaultPrefix; public readonly string DefaultPrefix;
public readonly Parameters Parameters; public readonly ParametersFFI Parameters;
internal readonly IDatabase Database; internal readonly IDatabase Database;
internal readonly ModelRepository Repository; internal readonly ModelRepository Repository;

33
flake.lock generated
View file

@ -104,11 +104,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1734953472, "lastModified": 1735917398,
"narHash": "sha256-zWPAJFo7NNhSXbOc6YRAXbrWzcJGxNPtutKTTZz46Bs=", "narHash": "sha256-RkwVkqozmbYvwX63Q4GNkNCsPuHR8sUIax40J5A4l3A=",
"owner": "yusdacra", "owner": "yusdacra",
"repo": "nix-cargo-integration", "repo": "nix-cargo-integration",
"rev": "e71c873cf3b0dfa52e9550d580531e41eb4b4c6a", "rev": "aff54b572b75af13a6b31108ff7732d17674ad43",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -227,7 +227,8 @@
"process-compose": "process-compose", "process-compose": "process-compose",
"services": "services", "services": "services",
"systems": "systems", "systems": "systems",
"treefmt": "treefmt" "treefmt": "treefmt",
"uniffi-bindgen-cs": "uniffi-bindgen-cs"
} }
}, },
"rust-overlay": { "rust-overlay": {
@ -238,11 +239,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1734834660, "lastModified": 1735871325,
"narHash": "sha256-bm8V+Cu8rWJA+vKQnc94mXTpSDgvedyoDKxTVi/uJfw=", "narHash": "sha256-6Ta5E4mhSfCP6LdkzkG2+BciLOCPeLKuYTJ6lOHW+mI=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "b070e6030118680977bc2388868c4b3963872134", "rev": "a599f011db521766cbaf7c2f5874182485554f00",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -322,6 +323,24 @@
"repo": "treefmt-nix", "repo": "treefmt-nix",
"type": "github" "type": "github"
} }
},
"uniffi-bindgen-cs": {
"flake": false,
"locked": {
"lastModified": 1732196488,
"narHash": "sha256-zqNUUFd3OSAwmMh+hnN6AVpGnwu+ZJ1jjivbzN1k5Io=",
"ref": "refs/heads/main",
"rev": "fe5cd23943fd3aec335e2bb8f709ec1956992ae9",
"revCount": 115,
"submodules": true,
"type": "git",
"url": "https://github.com/NordSecurity/uniffi-bindgen-cs?tag=v0.8.3%2Bv0.25.0"
},
"original": {
"submodules": true,
"type": "git",
"url": "https://github.com/NordSecurity/uniffi-bindgen-cs?tag=v0.8.3%2Bv0.25.0"
}
} }
}, },
"root": "root", "root": "root",

290
flake.nix
View file

@ -16,6 +16,8 @@
nci.inputs.nixpkgs.follows = "nixpkgs"; nci.inputs.nixpkgs.follows = "nixpkgs";
nci.inputs.dream2nix.follows = "d2n"; nci.inputs.dream2nix.follows = "d2n";
nci.inputs.treefmt.follows = "treefmt"; nci.inputs.treefmt.follows = "treefmt";
uniffi-bindgen-cs.url = "git+https://github.com/NordSecurity/uniffi-bindgen-cs?tag=v0.8.3+v0.25.0&submodules=1";
uniffi-bindgen-cs.flake = false;
# misc # misc
treefmt.url = "github:numtide/treefmt-nix"; treefmt.url = "github:numtide/treefmt-nix";
treefmt.inputs.nixpkgs.follows = "nixpkgs"; treefmt.inputs.nixpkgs.follows = "nixpkgs";
@ -57,39 +59,58 @@
]; ];
runScript = cmd; runScript = cmd;
}; };
uniffi-bindgen-cs = config.nci.lib.buildCrate {
src = inp.uniffi-bindgen-cs;
cratePath = "bindgen";
# TODO: uniffi fails to build with our toolchain because the ahash dep that uniffi-bindgen-cs uses is too old and uses removed stdsimd feature
mkRustToolchain = pkgs: pkgs.cargo;
};
rustOutputs = config.nci.outputs; rustOutputs = config.nci.outputs;
composeCfg = config.process-compose."dev"; composeCfg = config.process-compose."dev";
in in
{ {
# _module.args.pkgs = import inp.nixpkgs {
# inherit system;
# config.permittedInsecurePackages = [ "dotnet-sdk-6.0.428" ];
# };
treefmt = { treefmt = {
projectRootFile = "flake.nix"; projectRootFile = "flake.nix";
programs.nixfmt.enable = true; programs.nixfmt.enable = true;
}; };
nci.toolchainConfig = {
channel = "nightly";
};
nci.projects."pluralkit-services" = { nci.projects."pluralkit-services" = {
path = ./.; path = ./.;
export = false; export = false;
}; };
# nci.crates."gateway" = { nci.crates."commands" = rec {
# depsDrvConfig.mkDerivation = { depsDrvConfig.env = {
# nativeBuildInputs = [ pkgs.protobuf ]; # we don't really need this since the lib is just used to generate the bindings
# }; doNotRemoveReferencesToVendorDir = true;
# drvConfig.mkDerivation = { };
# nativeBuildInputs = [ pkgs.protobuf ]; depsDrvConfig.mkDerivation = {
# }; # also not really needed
# }; dontPatchShebangs = true;
};
drvConfig = depsDrvConfig;
};
apps = {
generate-command-parser-bindings.program = pkgs.writeShellApplication {
name = "generate-command-parser-bindings";
runtimeInputs = [
(config.nci.toolchains.mkBuild pkgs)
self'.devShells.services.stdenv.cc
pkgs.csharpier
pkgs.coreutils
uniffi-bindgen-cs
];
text = ''
set -x
[ "''${1:-}" == "" ] && cargo build --package commands --release
uniffi-bindgen-cs "''${1:-target/debug/libcommands.so}" --library --out-dir="''${2:-./PluralKit.Bot}"
'';
};
};
# TODO: expose other rust packages after it's verified they build and work properly # TODO: expose other rust packages after it's verified they build and work properly
packages = lib.genAttrs ["gateway"] (name: rustOutputs.${name}.packages.release); packages = lib.genAttrs [ "gateway" "commands" ] (name: rustOutputs.${name}.packages.release);
# TODO: package the bot itself (dotnet) # TODO: package the bot itself (dotnet)
devShells = { devShells = {
@ -97,136 +118,139 @@
bot = (mkBotEnv "bash").env; bot = (mkBotEnv "bash").env;
}; };
process-compose."dev" = let process-compose."dev" =
dataDir = ".nix-process-compose"; let
pluralkitConfCheck = '' dataDir = ".nix-process-compose";
[[ -f "pluralkit.conf" ]] || (echo "pluralkit config not found, please copy pluralkit.conf.example to pluralkit.conf and edit it" && exit 1) pluralkitConfCheck = ''
''; [[ -f "pluralkit.conf" ]] || (echo "pluralkit config not found, please copy pluralkit.conf.example to pluralkit.conf and edit it" && exit 1)
sourceDotenv = ''
[[ -f ".env" ]] && echo "sourcing .env file..." && export "$(xargs < .env)"
'';
in {
imports = [ inp.services.processComposeModules.default ];
settings.log_location = "${dataDir}/log";
settings.environment = {
DOTNET_CLI_TELEMETRY_OPTOUT = "1";
NODE_OPTIONS = "--openssl-legacy-provider";
};
services.redis."redis" = {
enable = true;
dataDir = "${dataDir}/redis";
};
services.postgres."postgres" = {
enable = true;
dataDir = "${dataDir}/postgres";
initialScript.before = ''
CREATE DATABASE pluralkit;
CREATE USER postgres WITH password 'postgres';
GRANT ALL PRIVILEGES ON DATABASE pluralkit TO postgres;
ALTER DATABASE pluralkit OWNER TO postgres;
''; '';
}; sourceDotenv = ''
[[ -f ".env" ]] && echo "sourcing .env file..." && export "$(xargs < .env)"
'';
in
{
imports = [ inp.services.processComposeModules.default ];
settings.processes = settings.log_location = "${dataDir}/log";
let
procCfg = composeCfg.settings.processes; settings.environment = {
mkServiceInitProcess = DOTNET_CLI_TELEMETRY_OPTOUT = "1";
{ NODE_OPTIONS = "--openssl-legacy-provider";
name, };
inputs ? [ ],
... services.redis."redis" = {
}: enable = true;
let dataDir = "${dataDir}/redis";
shell = rustOutputs.${name}.devShell; };
in services.postgres."postgres" = {
{ enable = true;
dataDir = "${dataDir}/postgres";
initialScript.before = ''
CREATE DATABASE pluralkit;
CREATE USER postgres WITH password 'postgres';
GRANT ALL PRIVILEGES ON DATABASE pluralkit TO postgres;
ALTER DATABASE pluralkit OWNER TO postgres;
'';
};
settings.processes =
let
procCfg = composeCfg.settings.processes;
mkServiceInitProcess =
{
name,
inputs ? [ ],
...
}:
let
shell = rustOutputs.${name}.devShell;
in
{
command = pkgs.writeShellApplication {
name = "pluralkit-${name}-init";
runtimeInputs =
(with pkgs; [
coreutils
shell.stdenv.cc
])
++ shell.nativeBuildInputs
++ inputs;
text = ''
${sourceDotenv}
set -x
${pluralkitConfCheck}
exec cargo build --package ${name}
'';
};
};
in
{
### bot ###
pluralkit-bot-init = {
command = pkgs.writeShellApplication { command = pkgs.writeShellApplication {
name = "pluralkit-${name}-init"; name = "pluralkit-bot-init";
runtimeInputs = runtimeInputs = [
(with pkgs; [ pkgs.coreutils
coreutils pkgs.git
shell.stdenv.cc ];
])
++ shell.nativeBuildInputs
++ inputs;
text = '' text = ''
${sourceDotenv} ${sourceDotenv}
set -x set -x
${pluralkitConfCheck} ${pluralkitConfCheck}
exec cargo build --package ${name} ${self'.apps.generate-command-parser-bindings.program}
exec ${mkBotEnv "dotnet build -c Release -o obj/"}/bin/env
''; '';
}; };
}; };
in pluralkit-bot = {
{ command = pkgs.writeShellApplication {
### bot ### name = "pluralkit-bot";
pluralkit-bot-init = { runtimeInputs = [ pkgs.coreutils ];
command = pkgs.writeShellApplication { text = ''
name = "pluralkit-bot-init"; ${sourceDotenv}
runtimeInputs = [ set -x
pkgs.coreutils exec ${mkBotEnv "dotnet obj/PluralKit.Bot.dll"}/bin/env
pkgs.git '';
]; };
text = '' depends_on.pluralkit-bot-init.condition = "process_completed_successfully";
${sourceDotenv} depends_on.postgres.condition = "process_healthy";
set -x depends_on.redis.condition = "process_healthy";
${pluralkitConfCheck} depends_on.pluralkit-gateway.condition = "process_healthy";
exec ${mkBotEnv "dotnet build -c Release -o obj/"}/bin/env # TODO: add liveness check
''; ready_log_line = "Received Ready";
}; };
}; ### gateway ###
pluralkit-bot = { pluralkit-gateway-init = mkServiceInitProcess {
command = pkgs.writeShellApplication { name = "gateway";
name = "pluralkit-bot";
runtimeInputs = [ pkgs.coreutils ];
text = ''
${sourceDotenv}
set -x
exec ${mkBotEnv "dotnet obj/PluralKit.Bot.dll"}/bin/env
'';
}; };
depends_on.pluralkit-bot-init.condition = "process_completed_successfully"; pluralkit-gateway = {
depends_on.postgres.condition = "process_healthy"; command = pkgs.writeShellApplication {
depends_on.redis.condition = "process_healthy"; name = "pluralkit-gateway";
depends_on.pluralkit-gateway.condition = "process_healthy"; runtimeInputs = with pkgs; [
# TODO: add liveness check coreutils
ready_log_line = "Received Ready"; curl
}; gnugrep
### gateway ### ];
pluralkit-gateway-init = mkServiceInitProcess { text = ''
name = "gateway"; ${sourceDotenv}
}; set -x
pluralkit-gateway = { exec target/debug/gateway
command = pkgs.writeShellApplication { '';
name = "pluralkit-gateway"; };
runtimeInputs = with pkgs; [ depends_on.postgres.condition = "process_healthy";
coreutils depends_on.redis.condition = "process_healthy";
curl depends_on.pluralkit-gateway-init.condition = "process_completed_successfully";
gnugrep # configure health checks
]; # TODO: don't assume port?
text = '' liveness_probe.exec.command = ''curl -s -o /dev/null -w "%{http_code}" http://localhost:5000/stats | grep "302"'';
${sourceDotenv} liveness_probe.period_seconds = 5;
set -x readiness_probe.exec.command = procCfg.pluralkit-gateway.liveness_probe.exec.command;
exec target/debug/gateway readiness_probe.period_seconds = 5;
''; readiness_probe.initial_delay_seconds = 3;
}; };
depends_on.postgres.condition = "process_healthy"; # TODO: add the rest of the services
depends_on.redis.condition = "process_healthy";
depends_on.pluralkit-gateway-init.condition = "process_completed_successfully";
# configure health checks
# TODO: don't assume port?
liveness_probe.exec.command = ''curl -s -o /dev/null -w "%{http_code}" http://localhost:5000/stats | grep "302"'';
liveness_probe.period_seconds = 5;
readiness_probe.exec.command = procCfg.pluralkit-gateway.liveness_probe.exec.command;
readiness_probe.period_seconds = 5;
readiness_probe.initial_delay_seconds = 3;
}; };
# TODO: add the rest of the services };
};
};
}; };
}; };
} }