diff --git a/.cargo/config.toml b/.cargo/config.toml index cd65da0b165..9fb5ae97e8a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -5,6 +5,7 @@ rustflags = ["--cfg", "tokio_unstable"] bump-versions = "run -p upgrade-version --" llm = "run --package xtask-llm-benchmark --bin llm_benchmark --" ci = "run -p ci --" +csharp = "run -p csharp-tools --" regen = "run -p regen --" smoketest = "ci smoketests --" smoketests = "smoketest" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d572566f4db..e6d732238c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,8 +132,7 @@ jobs: run: | dotnet pack -c Release crates/bindings-csharp/BSATN.Runtime dotnet pack -c Release crates/bindings-csharp/Runtime - cd sdks/csharp - ./tools~/write-nuget-config.sh ../.. + cargo csharp write-nuget-config sdks/csharp . # This step shouldn't be needed, but somehow we end up with caches that are missing librusty_v8.a. # ChatGPT suspects that this could be due to different build invocations using the same target dir, @@ -615,6 +614,11 @@ jobs: with: global-json-file: global.json + - name: Install Rust toolchain + uses: dsherret/rust-toolchain-file@v1 + - name: Set default rust toolchain + run: rustup default $(rustup show active-toolchain | cut -d' ' -f1) + - name: Override NuGet packages run: | dotnet pack crates/bindings-csharp/BSATN.Runtime @@ -626,8 +630,7 @@ jobs: # This means that (if version numbers match) we will test the local versions of the C# packages, even # if they're not pushed to NuGet. # See https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file for more info on the config file. - cd sdks/csharp - ./tools~/write-nuget-config.sh ../.. + cargo csharp write-nuget-config sdks/csharp . - name: Restore .NET solution working-directory: sdks/csharp @@ -640,11 +643,6 @@ jobs: sed -i "s|spacetimedb *=.*|spacetimedb = \{ path = \"../../../crates/bindings\" \}|" Cargo.toml cat Cargo.toml - - name: Install Rust toolchain - uses: dsherret/rust-toolchain-file@v1 - - name: Set default rust toolchain - run: rustup default $(rustup show active-toolchain | cut -d' ' -f1) - - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 with: @@ -683,7 +681,7 @@ jobs: - name: Check for changes run: | - tools/check-diff.sh demo/Blackholio/client-unity/Assets/Scripts/autogen || { + cargo ci check-diff demo/Blackholio/client-unity/Assets/Scripts/autogen || { echo 'Error: Bindings are dirty. Please run `demo/Blackholio/server-rust/generate.sh`.' exit 1 } @@ -760,6 +758,11 @@ jobs: with: global-json-file: global.json + - name: Install Rust toolchain + uses: dsherret/rust-toolchain-file@v1 + - name: Set default rust toolchain + run: rustup default $(rustup show active-toolchain | cut -d' ' -f1) + - name: Override NuGet packages run: | dotnet pack crates/bindings-csharp/BSATN.Runtime @@ -771,8 +774,7 @@ jobs: # This means that (if version numbers match) we will test the local versions of the C# packages, even # if they're not pushed to NuGet. # See https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file for more info on the config file. - cd sdks/csharp - ./tools~/write-nuget-config.sh ../.. + cargo csharp write-nuget-config sdks/csharp . - name: Restore .NET solution working-directory: sdks/csharp @@ -786,11 +788,6 @@ jobs: working-directory: sdks/csharp run: dotnet format --no-restore --verify-no-changes SpacetimeDB.ClientSDK.sln - - name: Install Rust toolchain - uses: dsherret/rust-toolchain-file@v1 - - name: Set default rust toolchain - run: rustup default $(rustup show active-toolchain | cut -d' ' -f1) - - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 with: @@ -831,9 +828,9 @@ jobs: - name: Check quickstart-chat bindings are up to date run: | - bash sdks/csharp/tools~/gen-quickstart.sh - tools/check-diff.sh templates/chat-console-cs/module_bindings || { - echo 'Error: quickstart-chat bindings have changed. Please run `sdks/csharp/tools~/gen-quickstart.sh`.' + cargo regen csharp quickstart + cargo ci check-diff templates/chat-console-cs/module_bindings || { + echo 'Error: quickstart-chat bindings have changed. Please run `cargo regen csharp quickstart`.' exit 1 } @@ -842,7 +839,7 @@ jobs: # working-directory: sdks/csharp # run: | # bash tools~/gen-client-api.sh - # "${GITHUB_WORKSPACE}"/tools/check-diff.sh src/SpacetimeDB/ClientApi || { + # cargo ci check-diff sdks/csharp/src/SpacetimeDB/ClientApi || { # echo 'Error: Client API bindings are dirty. Please run `sdks/csharp/tools~/gen-client-api.sh`.' # exit 1 # } @@ -855,8 +852,8 @@ jobs: - name: Run regression tests run: | bash sdks/csharp/tools~/run-regression-tests.sh - tools/check-diff.sh sdks/csharp/examples~/regression-tests || { - echo 'Error: Bindings are dirty. Please run `sdks/csharp/tools~/gen-regression-tests.sh`.' + cargo ci check-diff sdks/csharp/examples~/regression-tests || { + echo 'Error: Bindings are dirty. Please run `cargo regen csharp regression-tests`.' exit 1 } diff --git a/Cargo.lock b/Cargo.lock index 146f77caffa..f0d66b16b72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1549,6 +1549,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "csharp-tools" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap 4.5.50", + "duct", +] + [[package]] name = "css-module-lexer" version = "0.0.15" diff --git a/Cargo.toml b/Cargo.toml index d1488e186df..fde7fd5b19f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ members = [ "sdks/rust/tests/view-pk-client", "sdks/rust/tests/event-table-client", "tools/ci", + "tools/csharp-tools", "tools/upgrade-version", "tools/license-check", "tools/replace-spacetimedb", diff --git a/sdks/csharp/DEVELOP.md b/sdks/csharp/DEVELOP.md index ff56a1baf82..a12d3524155 100644 --- a/sdks/csharp/DEVELOP.md +++ b/sdks/csharp/DEVELOP.md @@ -12,7 +12,7 @@ When developing against a local clone of SpacetimeDB, you'll need to ensure that To develop against a local clone of SpacetimeDB at `../SpacetimeDB`, run the following command: ```sh -dotnet pack ../SpacetimeDB/crates/bindings-csharp/BSATN.Runtime && ./tools~/write-nuget-config.sh ../SpacetimeDB +dotnet pack ../SpacetimeDB/crates/bindings-csharp/BSATN.Runtime && cargo csharp write-nuget-config . --stdb-path ../SpacetimeDB ``` This will create a (`.gitignore`d) `nuget.config` file that uses the local build of the package, instead of the package on NuGet. @@ -99,4 +99,3 @@ We could deduplicate multiply-subscribed rows server-side, but this represents a There is also a class `MultiDictionaryDelta`. This represents a pre-processed batch of changes to a `MultiDictionary`. We prepare `MultiDictionaryDelta`s on a background thread and `Apply` them on the main thread. This allows us to do at least some work without blocking the main thread. Note that if multiple subscriptions are subscribed to a row, when a server-side transaction updates that row, exactly the right number of updates will be sent over the network, in a single `ServerMessage`. `MultiDictionary` and `MultiDictionaryDelta` rely on this guarantee for correct operation, and will throw exceptions in debug mode if it is not met. - diff --git a/sdks/csharp/tests~/README.md b/sdks/csharp/tests~/README.md index 95f9a400393..05a1edb4318 100644 --- a/sdks/csharp/tests~/README.md +++ b/sdks/csharp/tests~/README.md @@ -4,7 +4,7 @@ You can use `dotnet test` (either in this directory or in the project root direc # Using a different SpacetimeDB version To run tests using a local version of the `SpacetimeDB` repo, you can add a `nuget.config` file in the **root** of this repository. -The `tools/write-nuget-config.sh` script can generate the `nuget.config`. It takes one parameter: the path to the root SpacetimeDB repository (relative or absolute). +The `cargo csharp write-nuget-config` command can generate `NuGet.Config`. It takes one or more directories where `NuGet.Config` should be written. Use `--stdb-path` to point at a different SpacetimeDB repository. Then, you need to `dotnet pack` the `BSATN.Runtime` package in the `SpacetimeDB` repo. @@ -13,7 +13,7 @@ Lastly, before running `dotnet test`, you should `dotnet nuget locals all --clea Example: ```bash $ export SPACETIMEDB_REPO_PATH="../SpacetimeDB" -$ tools/write-nuget-config.sh "${SPACETIMEDB_REPO_PATH}" +$ cargo csharp write-nuget-config . --stdb-path "${SPACETIMEDB_REPO_PATH}" $ ( cd "${SPACETIMEDB_REPO_PATH}"/crates/bindings-csharp/BSATN.Runtime && dotnet pack ) $ dotnet nuget locals all --clear $ dotnet test diff --git a/sdks/csharp/tools~/gen-quickstart.sh b/sdks/csharp/tools~/gen-quickstart.sh deleted file mode 100755 index 1e216fcf556..00000000000 --- a/sdks/csharp/tools~/gen-quickstart.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -ueo pipefail - -SDK_PATH="$(dirname "$0")/.." -SDK_PATH="$(realpath "$SDK_PATH")" -STDB_PATH="$SDK_PATH/../.." - -cargo build --manifest-path "$STDB_PATH/crates/standalone/Cargo.toml" -cargo run --manifest-path "$STDB_PATH/crates/cli/Cargo.toml" -- generate -y -l csharp -o "$STDB_PATH/templates/chat-console-cs/module_bindings" --module-path "$STDB_PATH/templates/chat-console-cs/spacetimedb" diff --git a/sdks/csharp/tools~/gen-regression-tests.sh b/sdks/csharp/tools~/gen-regression-tests.sh deleted file mode 100755 index 8936971cd5a..00000000000 --- a/sdks/csharp/tools~/gen-regression-tests.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -ueo pipefail - -SDK_PATH="$(dirname "$0")/.." -SDK_PATH="$(realpath "$SDK_PATH")" -STDB_PATH="$SDK_PATH/../.." - -cargo build --manifest-path "$STDB_PATH/crates/standalone/Cargo.toml" -cargo run --manifest-path "$STDB_PATH/crates/cli/Cargo.toml" -- generate -y -l csharp -o "$SDK_PATH/examples~/regression-tests/client/module_bindings" --module-path "$SDK_PATH/examples~/regression-tests/server" -cargo run --manifest-path "$STDB_PATH/crates/cli/Cargo.toml" -- generate -y -l csharp -o "$SDK_PATH/examples~/regression-tests/republishing/client/module_bindings" --module-path "$SDK_PATH/examples~/regression-tests/republishing/server-republish" -cargo run --manifest-path "$STDB_PATH/crates/cli/Cargo.toml" -- generate -y -l csharp -o "$SDK_PATH/examples~/regression-tests/procedure-client/module_bindings" --module-path "$STDB_PATH/modules/sdk-test-procedure" diff --git a/sdks/csharp/tools~/run-regression-tests.sh b/sdks/csharp/tools~/run-regression-tests.sh index 168eeab668a..2784403bf1f 100644 --- a/sdks/csharp/tools~/run-regression-tests.sh +++ b/sdks/csharp/tools~/run-regression-tests.sh @@ -10,7 +10,7 @@ STDB_PATH="$SDK_PATH/../.." SPACETIMEDB_SERVER_URL="${SPACETIMEDB_SERVER_URL:-local}" # Regenerate Bindings -"$SDK_PATH/tools~/gen-regression-tests.sh" +cargo regen csharp regression-tests # Build and run SpacetimeDB server cargo build --manifest-path "$STDB_PATH/crates/standalone/Cargo.toml" diff --git a/sdks/csharp/tools~/update-against-stdb.sh b/sdks/csharp/tools~/update-against-stdb.sh index 58c0b8b649a..e4ae41a6f4b 100644 --- a/sdks/csharp/tools~/update-against-stdb.sh +++ b/sdks/csharp/tools~/update-against-stdb.sh @@ -8,15 +8,13 @@ STDB_PATH="$1" SDK_PATH="$(dirname "$0")/.." SDK_PATH="$(realpath "$SDK_PATH")" -"$SDK_PATH/tools~/write-nuget-config.sh" "$STDB_PATH" +cargo csharp write-nuget-config "$SDK_PATH" "$STDB_PATH" --stdb-path "$STDB_PATH" "$SDK_PATH/tools~/gen-client-api.sh" -"$SDK_PATH/tools~/gen-quickstart.sh" -"$SDK_PATH/tools~/gen-regression-tests.sh" +cargo regen csharp quickstart +cargo regen csharp regression-tests dotnet nuget locals all --clear dotnet pack "$STDB_PATH/crates/bindings-csharp" rm -rf "$SDK_PATH/packages" dotnet pack dotnet test pushd "$SDK_PATH"; git checkout -- 'packages/*.meta' 'packages/**/*.meta' packages/.gitignore; popd - - diff --git a/sdks/csharp/tools~/write-nuget-config.sh b/sdks/csharp/tools~/write-nuget-config.sh deleted file mode 100755 index 69286284ad8..00000000000 --- a/sdks/csharp/tools~/write-nuget-config.sh +++ /dev/null @@ -1,84 +0,0 @@ -set -ueo pipefail - -SPACETIMEDB_REPO_PATH="$(readlink -f "$1")" - -cd "$(dirname "$(readlink -f "$0")")" -cd .. - -# Write out the nuget config file to `nuget.config`. This causes the spacetimedb-csharp-sdk repository -# to be aware of the local versions of the `bindings-csharp` packages in SpacetimeDB, and use them if -# available. -# See https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file for more info on the config file, -# and https://tldp.org/LDP/abs/html/here-docs.html for more info on this bash feature. -cat >NuGet.Config < - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EOF - -cat >"${SPACETIMEDB_REPO_PATH}/NuGet.Config" < - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EOF - -echo "Wrote sdks/csharp/NuGet.Config contents:" -cat NuGet.Config diff --git a/tools/check-diff.sh b/tools/check-diff.sh deleted file mode 100755 index eafd78f41b1..00000000000 --- a/tools/check-diff.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# Keep in mind that this is also used from the private repo. - -SUBDIR="${1:-.}" # Default to '.' (the whole repo) if no argument given - -# We have a comment in every generated file that has the version and git hash, so these would change with every commit. -# We ignore them to avoid having to regen files for every commit unrelated to code gen. - -PATTERN='^// This was generated using spacetimedb cli version.*' - -git diff --exit-code --ignore-matching-lines="$PATTERN" -- "$SUBDIR" diff --git a/tools/ci/README.md b/tools/ci/README.md index 9b71b406fef..562b66d91ba 100644 --- a/tools/ci/README.md +++ b/tools/ci/README.md @@ -228,6 +228,18 @@ Usage: version-upgrade-check - `--help`: Print help +### `check-diff` + +**Usage:** +```bash +Usage: check-diff [SUBDIR] +``` + +**Options:** + +- `subdir`: Subdirectory to check. Defaults to the whole repository +- `--help`: Print help + ### `docs` **Usage:** diff --git a/tools/ci/src/main.rs b/tools/ci/src/main.rs index 2454ea3349f..312d80021ac 100644 --- a/tools/ci/src/main.rs +++ b/tools/ci/src/main.rs @@ -15,7 +15,7 @@ mod ci_docs; mod smoketest; mod util; -use util::ensure_repo_root; +use util::{bail_if_diff, ensure_repo_root, has_git_diff}; /// SpacetimeDB CI tasks /// @@ -159,6 +159,12 @@ enum CiCmd { TypescriptTest, /// Verifies that the repository version upgrade tool still works. VersionUpgradeCheck, + /// Checks for uncommitted diffs, ignoring generated SpacetimeDB CLI version comments. + CheckDiff { + /// Subdirectory to check. Defaults to the whole repository. + #[arg(default_value = ".")] + subdir: PathBuf, + }, /// Builds the docs site. Docs, } @@ -190,7 +196,9 @@ fn tracked_rs_files_under(path: &str) -> Result> { } fn run_publish_checks() -> Result<()> { - cmd!("bash", "-lc", "test -d venv || python3 -m venv venv").run()?; + if !Path::new("venv").is_dir() { + cmd!("python3", "-m", "venv", "venv").run()?; + } cmd!("venv/bin/pip3", "install", "argparse", "toml").run()?; let crates = cmd!( @@ -223,13 +231,7 @@ fn run_typescript_tests() -> Result<()> { cmd!("pnpm", "build").dir("crates/bindings-typescript").run()?; cmd!("pnpm", "test").dir("crates/bindings-typescript").run()?; cmd!("pnpm", "generate").dir("templates/chat-react-ts").run()?; - let diff_status = cmd!( - "bash", - "tools/check-diff.sh", - "templates/chat-react-ts/src/module_bindings" - ) - .run()?; - if !diff_status.status.success() { + if has_git_diff(Path::new("templates/chat-react-ts/src/module_bindings"))? { bail!("Bindings are dirty. Please generate bindings again and commit them to this branch."); } cmd!("pnpm", "build").dir("templates/chat-react-ts").run()?; @@ -334,7 +336,7 @@ fn main() -> Result<()> { "--test-threads=1", ) .run()?; - cmd!("bash", "tools/check-diff.sh").run()?; + bail_if_diff(Path::new("."))?; cmd!( "cargo", "run", @@ -344,7 +346,7 @@ fn main() -> Result<()> { "regen-csharp-moduledef", ) .run()?; - cmd!("bash", "tools/check-diff.sh", "crates/bindings-csharp").run()?; + bail_if_diff(Path::new("crates/bindings-csharp"))?; cmd!("dotnet", "test", "-warnaserror") .dir("crates/bindings-csharp") .run()?; @@ -536,6 +538,10 @@ fn main() -> Result<()> { run_version_upgrade_check()?; } + Some(CiCmd::CheckDiff { subdir }) => { + bail_if_diff(&subdir)?; + } + Some(CiCmd::Docs) => { run_docs_build()?; } diff --git a/tools/ci/src/smoketest.rs b/tools/ci/src/smoketest.rs index 456c13caa32..7a23876df2e 100644 --- a/tools/ci/src/smoketest.rs +++ b/tools/ci/src/smoketest.rs @@ -179,9 +179,8 @@ fn run_smoketest(server: Option, dotnet: bool, args: Vec) -> Res let status = cmd.args(&args).status()?; ensure!(status.success(), "Tests failed"); - let diff_status = cmd!("bash", "tools/check-diff.sh", "crates/smoketests").run()?; ensure!( - diff_status.status.success(), + !util::has_git_diff(Path::new("crates/smoketests"))?, "There is a diff in the smoketests directory." ); Ok(()) diff --git a/tools/ci/src/util.rs b/tools/ci/src/util.rs index ac35a7a465b..4e2ee0157ab 100644 --- a/tools/ci/src/util.rs +++ b/tools/ci/src/util.rs @@ -1,7 +1,8 @@ #![allow(clippy::disallowed_macros)] -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use std::path::Path; +use std::process::Command; pub fn ensure_repo_root() -> Result<()> { if !Path::new("Cargo.toml").exists() { @@ -9,3 +10,23 @@ pub fn ensure_repo_root() -> Result<()> { } Ok(()) } + +pub fn has_git_diff(subdir: &Path) -> Result { + let pattern = r"^// This was generated using spacetimedb cli version.*"; + let status = Command::new("git") + .args(["diff", "--exit-code"]) + .arg(format!("--ignore-matching-lines={pattern}")) + .arg("--") + .arg(subdir) + .status() + .with_context(|| format!("failed to spawn `git diff` for {}", subdir.display()))?; + + Ok(!status.success()) +} + +pub fn bail_if_diff(subdir: &Path) -> Result<()> { + if has_git_diff(subdir)? { + bail!("{} is dirty.", subdir.display()); + } + Ok(()) +} diff --git a/tools/csharp-tools/Cargo.toml b/tools/csharp-tools/Cargo.toml new file mode 100644 index 00000000000..e50c68179c0 --- /dev/null +++ b/tools/csharp-tools/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "csharp-tools" +version = "0.1.0" +edition.workspace = true + +[dependencies] +anyhow.workspace = true +clap.workspace = true +duct.workspace = true diff --git a/tools/csharp-tools/src/lib.rs b/tools/csharp-tools/src/lib.rs new file mode 100644 index 00000000000..8a65d8040a3 --- /dev/null +++ b/tools/csharp-tools/src/lib.rs @@ -0,0 +1,89 @@ +#![allow(clippy::disallowed_macros)] + +use anyhow::{Context, Result}; +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; + +pub fn workspace_dir() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(2) + .expect("tools/csharp-tools should be two levels below the workspace root") + .to_path_buf() +} + +pub fn sdk_dir() -> PathBuf { + workspace_dir().join("sdks/csharp") +} + +fn canonicalize_existing(path: &Path) -> Result { + path.canonicalize() + .with_context(|| format!("failed to canonicalize {}", path.display())) +} + +fn render_nuget_config(bsatn_source: &Path, runtime_source: &Path) -> String { + format!( + r#" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"#, + bsatn_source.display(), + runtime_source.display(), + ) +} + +pub fn write_nuget_configs(target_dirs: &[PathBuf], spacetimedb_repo_path: Option<&Path>, quiet: bool) -> Result<()> { + let spacetimedb_repo_path = match spacetimedb_repo_path { + Some(path) => canonicalize_existing(path)?, + None => workspace_dir(), + }; + + let config_contents = render_nuget_config( + &spacetimedb_repo_path.join("crates/bindings-csharp/BSATN.Runtime/bin/Release"), + &spacetimedb_repo_path.join("crates/bindings-csharp/Runtime/bin/Release"), + ); + + for target_dir in target_dirs { + let target_dir = canonicalize_existing(target_dir)?; + let config_path = target_dir.join("NuGet.Config"); + fs::write(&config_path, &config_contents) + .with_context(|| format!("failed to write {}", config_path.display()))?; + + if !quiet { + println!("Wrote {} contents:", config_path.display()); + print!("{}", fs::read_to_string(&config_path)?); + } + } + + Ok(()) +} diff --git a/tools/csharp-tools/src/main.rs b/tools/csharp-tools/src/main.rs new file mode 100644 index 00000000000..4b2b3f50d13 --- /dev/null +++ b/tools/csharp-tools/src/main.rs @@ -0,0 +1,42 @@ +use anyhow::Result; +use clap::{Parser, Subcommand}; +use std::path::PathBuf; + +#[derive(Parser)] +#[command(name = "csharp-tools", bin_name = "cargo csharp", about = "C# SDK maintenance tasks")] +struct Cli { + #[command(subcommand)] + command: Command, +} + +#[derive(Subcommand)] +enum Command { + /// Write NuGet.Config files that point at local SpacetimeDB C# packages. + WriteNugetConfig { + /// Directories where NuGet.Config should be written. + #[arg(required = true)] + target_dirs: Vec, + /// Path to the SpacetimeDB repository whose C# packages should be used. + #[arg(long, alias = "spacetimedb-repo-path")] + stdb_path: Option, + /// Do not print the generated SDK NuGet.Config contents. + #[arg(long)] + quiet: bool, + }, +} + +fn main() -> Result<()> { + let cli = Cli::parse(); + + match cli.command { + Command::WriteNugetConfig { + target_dirs, + stdb_path, + quiet, + } => { + csharp_tools::write_nuget_configs(&target_dirs, stdb_path.as_deref(), quiet)?; + } + } + + Ok(()) +} diff --git a/tools/regen/src/csharp.rs b/tools/regen/src/csharp.rs index f8ac31f0335..9ea5c283d92 100644 --- a/tools/regen/src/csharp.rs +++ b/tools/regen/src/csharp.rs @@ -21,48 +21,99 @@ fn sdk_dir() -> PathBuf { workspace_dir().join("sdks/csharp") } +fn cli_manifest() -> PathBuf { + workspace_dir().join("crates/cli/Cargo.toml") +} + +fn standalone_manifest() -> PathBuf { + workspace_dir().join("crates/standalone/Cargo.toml") +} + fn path_arg(path: &Path) -> String { path.to_string_lossy().into_owned() } -fn render_nuget_config(bsatn_source: &Path, runtime_source: &Path) -> String { - format!( - r#" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"#, - bsatn_source.display(), - runtime_source.display(), +pub fn regen_regression_tests() -> Result<()> { + let sdk = sdk_dir(); + let workspace = workspace_dir(); + + cmd!("cargo", "build", "--manifest-path", path_arg(&standalone_manifest())).run()?; + + cmd!( + "cargo", + "run", + "--manifest-path", + path_arg(&cli_manifest()), + "--", + "generate", + "-y", + "-l", + "csharp", + "-o", + path_arg(&sdk.join("examples~/regression-tests/client/module_bindings")), + "--module-path", + path_arg(&sdk.join("examples~/regression-tests/server")), + ) + .run()?; + cmd!( + "cargo", + "run", + "--manifest-path", + path_arg(&cli_manifest()), + "--", + "generate", + "-y", + "-l", + "csharp", + "-o", + path_arg(&sdk.join("examples~/regression-tests/republishing/client/module_bindings")), + "--module-path", + path_arg(&sdk.join("examples~/regression-tests/republishing/server-republish")), + ) + .run()?; + cmd!( + "cargo", + "run", + "--manifest-path", + path_arg(&cli_manifest()), + "--", + "generate", + "-y", + "-l", + "csharp", + "-o", + path_arg(&sdk.join("examples~/regression-tests/procedure-client/module_bindings")), + "--module-path", + path_arg(&workspace.join("modules/sdk-test-procedure")), + ) + .run()?; + + Ok(()) +} + +pub fn regen_quickstart() -> Result<()> { + let workspace = workspace_dir(); + + cmd!("cargo", "build", "--manifest-path", path_arg(&standalone_manifest())).run()?; + + cmd!( + "cargo", + "run", + "--manifest-path", + path_arg(&cli_manifest()), + "--", + "generate", + "-y", + "-l", + "csharp", + "-o", + path_arg(&workspace.join("templates/chat-console-cs/module_bindings")), + "--module-path", + path_arg(&workspace.join("templates/chat-console-cs/spacetimedb")), ) + .run()?; + + Ok(()) } fn overlay_unity_meta_skeleton(pkg_id: &str) -> Result<()> { @@ -197,14 +248,15 @@ pub fn regen_dlls() -> Result<()> { .run()?; let nuget_config_dir = tempfile::tempdir()?; - let nuget_config_path = nuget_config_dir.path().join("nuget.config"); - fs::write( - &nuget_config_path, - render_nuget_config( - &workspace.join("crates/bindings-csharp/BSATN.Runtime/bin/Release"), - &workspace.join("crates/bindings-csharp/Runtime/bin/Release"), - ), - )?; + let nuget_config_path = nuget_config_dir.path().join("NuGet.Config"); + cmd!( + "cargo", + "csharp", + "write-nuget-config", + path_arg(nuget_config_dir.path()), + "--quiet", + ) + .run()?; clear_restored_package_dirs(BSATN_PACKAGE_ID)?; clear_restored_package_dirs(RUNTIME_PACKAGE_ID)?; diff --git a/tools/regen/src/main.rs b/tools/regen/src/main.rs index 48aa55a305c..9151adb1992 100644 --- a/tools/regen/src/main.rs +++ b/tools/regen/src/main.rs @@ -21,6 +21,10 @@ enum Command { #[derive(Subcommand)] enum CsharpCommand { + /// Regenerate C# regression test bindings. + RegressionTests, + /// Regenerate C# quickstart bindings. + Quickstart, /// Regenerate C# DLL and NuGet package artifacts for Unity workflows. Dlls, } @@ -30,6 +34,8 @@ fn main() -> Result<()> { match cli.command { Command::Csharp { command } => match command { + CsharpCommand::RegressionTests => csharp::regen_regression_tests()?, + CsharpCommand::Quickstart => csharp::regen_quickstart()?, CsharpCommand::Dlls => csharp::regen_dlls()?, }, }