diff --git a/PluralKit.Bot/CommandSystem/Context/Context.cs b/PluralKit.Bot/CommandSystem/Context/Context.cs index 6a5eaf19..c212e2e5 100644 --- a/PluralKit.Bot/CommandSystem/Context/Context.cs +++ b/PluralKit.Bot/CommandSystem/Context/Context.cs @@ -48,7 +48,6 @@ public class Context _commandMessageService = provider.Resolve(); CommandPrefix = message.Content?.Substring(0, commandParseOffset); DefaultPrefix = prefixes[0]; - Parameters = new Parameters(message.Content?.Substring(commandParseOffset)); Rest = provider.Resolve(); Cluster = provider.Resolve(); @@ -87,7 +86,7 @@ public class Context public readonly string CommandPrefix; public readonly string DefaultPrefix; - public readonly Parameters Parameters; + public readonly ParametersFFI Parameters; internal readonly IDatabase Database; internal readonly ModelRepository Repository; diff --git a/flake.lock b/flake.lock index a13615a1..0e29c367 100644 --- a/flake.lock +++ b/flake.lock @@ -104,11 +104,11 @@ ] }, "locked": { - "lastModified": 1734953472, - "narHash": "sha256-zWPAJFo7NNhSXbOc6YRAXbrWzcJGxNPtutKTTZz46Bs=", + "lastModified": 1735917398, + "narHash": "sha256-RkwVkqozmbYvwX63Q4GNkNCsPuHR8sUIax40J5A4l3A=", "owner": "yusdacra", "repo": "nix-cargo-integration", - "rev": "e71c873cf3b0dfa52e9550d580531e41eb4b4c6a", + "rev": "aff54b572b75af13a6b31108ff7732d17674ad43", "type": "github" }, "original": { @@ -227,7 +227,8 @@ "process-compose": "process-compose", "services": "services", "systems": "systems", - "treefmt": "treefmt" + "treefmt": "treefmt", + "uniffi-bindgen-cs": "uniffi-bindgen-cs" } }, "rust-overlay": { @@ -238,11 +239,11 @@ ] }, "locked": { - "lastModified": 1734834660, - "narHash": "sha256-bm8V+Cu8rWJA+vKQnc94mXTpSDgvedyoDKxTVi/uJfw=", + "lastModified": 1735871325, + "narHash": "sha256-6Ta5E4mhSfCP6LdkzkG2+BciLOCPeLKuYTJ6lOHW+mI=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "b070e6030118680977bc2388868c4b3963872134", + "rev": "a599f011db521766cbaf7c2f5874182485554f00", "type": "github" }, "original": { @@ -322,6 +323,24 @@ "repo": "treefmt-nix", "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", diff --git a/flake.nix b/flake.nix index ac600aa4..238ae0e1 100644 --- a/flake.nix +++ b/flake.nix @@ -16,6 +16,8 @@ nci.inputs.nixpkgs.follows = "nixpkgs"; nci.inputs.dream2nix.follows = "d2n"; 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 treefmt.url = "github:numtide/treefmt-nix"; treefmt.inputs.nixpkgs.follows = "nixpkgs"; @@ -57,39 +59,58 @@ ]; 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; composeCfg = config.process-compose."dev"; in { - # _module.args.pkgs = import inp.nixpkgs { - # inherit system; - # config.permittedInsecurePackages = [ "dotnet-sdk-6.0.428" ]; - # }; - treefmt = { projectRootFile = "flake.nix"; programs.nixfmt.enable = true; }; - nci.toolchainConfig = { - channel = "nightly"; - }; nci.projects."pluralkit-services" = { path = ./.; export = false; }; - # nci.crates."gateway" = { - # depsDrvConfig.mkDerivation = { - # nativeBuildInputs = [ pkgs.protobuf ]; - # }; - # drvConfig.mkDerivation = { - # nativeBuildInputs = [ pkgs.protobuf ]; - # }; - # }; + nci.crates."commands" = rec { + depsDrvConfig.env = { + # we don't really need this since the lib is just used to generate the bindings + doNotRemoveReferencesToVendorDir = true; + }; + 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 - 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) devShells = { @@ -97,136 +118,139 @@ bot = (mkBotEnv "bash").env; }; - process-compose."dev" = let - dataDir = ".nix-process-compose"; - 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; + process-compose."dev" = + let + dataDir = ".nix-process-compose"; + 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.processes = - let - procCfg = composeCfg.settings.processes; - mkServiceInitProcess = - { - name, - inputs ? [ ], - ... - }: - let - shell = rustOutputs.${name}.devShell; - in - { + 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; + ''; + }; + + 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 { - name = "pluralkit-${name}-init"; - runtimeInputs = - (with pkgs; [ - coreutils - shell.stdenv.cc - ]) - ++ shell.nativeBuildInputs - ++ inputs; + name = "pluralkit-bot-init"; + runtimeInputs = [ + pkgs.coreutils + pkgs.git + ]; text = '' ${sourceDotenv} set -x ${pluralkitConfCheck} - exec cargo build --package ${name} + ${self'.apps.generate-command-parser-bindings.program} + exec ${mkBotEnv "dotnet build -c Release -o obj/"}/bin/env ''; }; }; - in - { - ### bot ### - pluralkit-bot-init = { - command = pkgs.writeShellApplication { - name = "pluralkit-bot-init"; - runtimeInputs = [ - pkgs.coreutils - pkgs.git - ]; - text = '' - ${sourceDotenv} - set -x - ${pluralkitConfCheck} - exec ${mkBotEnv "dotnet build -c Release -o obj/"}/bin/env - ''; + pluralkit-bot = { + command = pkgs.writeShellApplication { + 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"; + depends_on.postgres.condition = "process_healthy"; + depends_on.redis.condition = "process_healthy"; + depends_on.pluralkit-gateway.condition = "process_healthy"; + # TODO: add liveness check + ready_log_line = "Received Ready"; }; - }; - pluralkit-bot = { - command = pkgs.writeShellApplication { - name = "pluralkit-bot"; - runtimeInputs = [ pkgs.coreutils ]; - text = '' - ${sourceDotenv} - set -x - exec ${mkBotEnv "dotnet obj/PluralKit.Bot.dll"}/bin/env - ''; + ### gateway ### + pluralkit-gateway-init = mkServiceInitProcess { + name = "gateway"; }; - depends_on.pluralkit-bot-init.condition = "process_completed_successfully"; - depends_on.postgres.condition = "process_healthy"; - depends_on.redis.condition = "process_healthy"; - depends_on.pluralkit-gateway.condition = "process_healthy"; - # TODO: add liveness check - ready_log_line = "Received Ready"; - }; - ### gateway ### - pluralkit-gateway-init = mkServiceInitProcess { - name = "gateway"; - }; - pluralkit-gateway = { - command = pkgs.writeShellApplication { - name = "pluralkit-gateway"; - runtimeInputs = with pkgs; [ - coreutils - curl - gnugrep - ]; - text = '' - ${sourceDotenv} - set -x - exec target/debug/gateway - ''; + pluralkit-gateway = { + command = pkgs.writeShellApplication { + name = "pluralkit-gateway"; + runtimeInputs = with pkgs; [ + coreutils + curl + gnugrep + ]; + text = '' + ${sourceDotenv} + set -x + exec target/debug/gateway + ''; + }; + depends_on.postgres.condition = "process_healthy"; + 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; }; - depends_on.postgres.condition = "process_healthy"; - 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 }; - # TODO: add the rest of the services - }; - }; + }; }; }; }