Files
SpacetimeDB/smoketests/tests/csharp_module.py
Piotr Sarnacki 647be7e9c0 spacetime init rewrite (#3366)
This is a draft of the new functionality for `spacetime init`. In order
to run it with built-in templates you have to set the path to the config
file:

```
export SPACETIMEDB_CLI_TEMPLATES_FILE=crates/cli/.init-templates.json
```

In the future it will fetch the list from GH.

A few notes:

* the previous functionality of `spacetime init` does not work at the
moment
* the code needs a bit more cleanup and tests before merging
* there is a bit of a mix in how we generate empty server and client
projects. For Rust we use the existing way of generating. For TypeScript
we clone an empty project from the repo. I wanted to play with both ways
of doing things, and I'm still not sure which is better. Generation in
Rust means that the generated code will match the CLI version and not
necessarily whatever is in Git. On the other hand, for the builtin
templates we will be fetching the newest version from GH, which I guess
might also not what we want, ie. we probably want only stable templates.
More discussion is needed here
* we use `spacetimedb` directory for the server files
* I don't particularly like the inability to disable interactive mode
easily. We discussed disabling it by default if all of the required
arguments are passed, but I don't think it's feature proof. For example,
if someone relies on a non-interactive mode, and we add a new required
argument, instead of printing a message `missing --foo`, we will
automatically launch interactive mode, which is harder to debug. That's
why I think I'd prefer to implement `--non-interactive` argument
* it's kind of hard to keep the legacy behaviour. If you don't pass any
arguments, we go into interactive mode. In the legacy version, we would
print required arguments. If someone passes `--lang` or `--project-path`
explicitly, I guess we could run the legacy workflow, but not sure if
it's worth it, as the command was marked as unstable anyway
* the project path defaults to the project name, but I think we should
probably replace change whitespaces to dashes, or at least ask for the
project path with the project name being the default (or both)

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Signed-off-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2025-10-30 04:26:08 +00:00

82 lines
3.1 KiB
Python

from .. import run_cmd, STDB_DIR, requires_dotnet, spacetime
import unittest
import tempfile
from pathlib import Path
import shutil
import subprocess
import xml.etree.ElementTree as xml
@requires_dotnet
class CreateProject(unittest.TestCase):
def test_build_csharp_module(self):
"""
Ensure that the CLI is able to create and compile a csharp project. This test does not depend on a running spacetimedb instance. Skips if dotnet 8.0 is not available
"""
bindings = Path(STDB_DIR) / "crates" / "bindings-csharp"
try:
run_cmd("dotnet", "nuget", "locals", "all", "--clear", cwd=bindings, capture_stderr=True)
run_cmd("dotnet", "workload", "install", "wasi-experimental", "--skip-manifest-update", cwd=STDB_DIR / "modules")
run_cmd("dotnet", "pack", cwd=bindings, capture_stderr=True)
with tempfile.TemporaryDirectory() as tmpdir:
spacetime(
"init",
"--non-interactive",
"--lang=csharp",
"--project-path",
tmpdir,
"csharp-project",
)
server_path = Path(tmpdir) / "spacetimedb"
packed_projects = ["BSATN.Runtime", "Runtime"]
config = xml.Element("configuration")
sources = xml.SubElement(config, "packageSources")
mappings = xml.SubElement(config, "packageSourceMapping")
def add_mapping(source, pattern):
mapping = xml.SubElement(mappings, "packageSource", key=source)
xml.SubElement(mapping, "package", pattern=pattern)
for project in packed_projects:
# Add local build directories as NuGet repositories.
path = bindings / project / "bin" / "Release"
project = f"SpacetimeDB.{project}"
xml.SubElement(sources, "add", key=project, value=str(path))
# Add strict package source mappings to ensure that
# SpacetimeDB.* packages are used from those directories
# and never from nuget.org.
#
# This prevents bugs where we silently used an outdated
# version which led to tests passing when they shouldn't.
add_mapping(project, project)
# Add fallback for other packages.
add_mapping("nuget.org", "*")
xml.indent(config)
config = xml.tostring(config, encoding="unicode", xml_declaration=True)
print("Writing `nuget.config` contents:")
print(config)
config_path = server_path / "nuget.config"
with open(config_path, "w") as f:
f.write(config)
run_cmd("dotnet", "publish", cwd=server_path, capture_stderr=True)
except subprocess.CalledProcessError as e:
print(e)
print("output:")
print(e.output)
raise e