CultLib/scripts/measure-reactive-document-performance.ps1
Meta Vens 95493862bd Split the Python runtime into cultcache-py, cultnet-py, cultmesh-py
One distribution named cultcache-py carried three libraries. Rust and
TypeScript layer them as cultcache < cultnet < cultmesh; Python now does
the same, one package per layer, module names unchanged so every
`from cultmesh_py import ...` keeps working.

Two imports ran against that layering and are resolved by moving code to
where the dependency direction says it lives, not by adding a shim:

- cultnet_py.interop_peer imported the Verse/peer catalog, authority
  lease, stream, and simulation-fact contracts from cultmesh_py. They are
  wire contracts a bare peer has to speak without owning a node, which is
  why cultnet-rs and cultnet-ts keep them in the net layer. They now live
  in cultnet_py.cultmesh_contracts; cultmesh_py re-exports them.
- cultcache_py.benchmark imported cultnet_py. It measures framed CultNet
  parse beside cache paths, so it and compare_csharp move to cultnet_py.
  verify checks all three packages and moves to cultmesh_py.

The single 6,693-line test module is split by what each test touches: a
test using any cultmesh_py name lands in cultmesh-py, else cultnet_py in
cultnet-py, else cultcache-py. Each suite runs with only its layer and the
layers below on the path, so a test that reaches up fails to import
rather than quietly binding the packages back together. 11 / 53 / 78 =
the same 142.

Workflows install all three; the publish job is one matrix over the
three packages keyed by tag prefix. The TS test harnesses put all three
src directories on PYTHONPATH. cultcache-py bumps to 0.2.0 because it no
longer contains cultnet_py or cultmesh_py; the new packages start at
0.1.0. Nothing was ever published, so no PyPI consumer moves.

  cultcache-py  11 tests, path: cultcache-py/src
  cultnet-py    53 tests, path: + cultnet-py/src
  cultmesh-py   78 tests, path: + cultmesh-py/src
  python -m cultmesh_py.verify -> ok, all five checks
  cultnet_py.interop_peer imports with cultmesh_py absent

Not run here: the cultnet-ts interop ring and cultcache-ts store matrix
need dotnet/kotlin peers; their PYTHONPATH change is four lines.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 13:10:47 +02:00

88 lines
2.9 KiB
PowerShell

param(
[switch] $Quick,
[switch] $SkipRuntimeBuild,
[string] $PythonPath = "",
[string] $NodePath = ""
)
$ErrorActionPreference = "Stop"
$root = Split-Path -Parent $PSScriptRoot
$nodeExecutable = if ([string]::IsNullOrWhiteSpace($NodePath)) {
(Get-Command node -ErrorAction Stop).Source
}
else {
[IO.Path]::GetFullPath($NodePath)
}
$pythonExecutable = if ([string]::IsNullOrWhiteSpace($PythonPath)) {
(Get-Command python -ErrorAction Stop).Source
}
else {
[IO.Path]::GetFullPath($PythonPath)
}
foreach ($executable in @($nodeExecutable, $pythonExecutable)) {
if (-not (Test-Path -LiteralPath $executable -PathType Leaf)) {
throw "Performance probe runtime not found: $executable"
}
}
if (-not $SkipRuntimeBuild) {
$typescript = Join-Path $root "node_modules\typescript\bin\tsc"
foreach ($dependency in @("cultcache-ts", "cultnet-ts", "cultmesh-ts")) {
$dependencyRoot = Join-Path $root "packages\$dependency"
if ($dependency -eq "cultnet-ts") {
& $nodeExecutable (Join-Path $dependencyRoot "tools\generate-swarm-contracts.mjs")
if ($LASTEXITCODE -ne 0) { throw "CultNet TypeScript contract generation failed." }
}
& $nodeExecutable $typescript -p (Join-Path $dependencyRoot "tsconfig.json") --pretty false
if ($LASTEXITCODE -ne 0) { throw "TypeScript performance dependency build failed: $dependency" }
}
}
$project = Join-Path $root "tools\GameCult.Mesh.PerformanceProbe\GameCult.Mesh.PerformanceProbe.csproj"
$buildArguments = @(
"build",
$project,
"--configuration", "Release",
"--verbosity", "quiet",
"/p:NoWarn=1591%3BCS8632"
)
& dotnet @buildArguments
if ($LASTEXITCODE -ne 0) {
throw "CultMesh reactive document performance probe build failed."
}
$arguments = @("run", "--project", $project, "--configuration", "Release", "--no-build")
if ($Quick) {
$arguments += @("--", "--quick")
}
& dotnet @arguments
if ($LASTEXITCODE -ne 0) {
throw "CultMesh C# reactive document performance probe failed."
}
$runtimeArguments = @()
if ($Quick) { $runtimeArguments += "--quick" }
& $nodeExecutable --expose-gc (Join-Path $root "scripts\measure-reactive-document-performance.mjs") @runtimeArguments
if ($LASTEXITCODE -ne 0) {
throw "CultMesh TypeScript reactive document performance probe failed."
}
$pythonSource = (@("cultcache-py", "cultnet-py", "cultmesh-py") | ForEach-Object { Join-Path $root "packages\$_\src" }) -join [IO.Path]::PathSeparator
$previousPythonPath = $env:PYTHONPATH
$env:PYTHONPATH = if ([string]::IsNullOrWhiteSpace($previousPythonPath)) {
$pythonSource
}
else {
$pythonSource + [IO.Path]::PathSeparator + $previousPythonPath
}
try {
& $pythonExecutable (Join-Path $root "packages\cultmesh-py\tools\reactive_performance_probe.py") @runtimeArguments
if ($LASTEXITCODE -ne 0) {
throw "CultMesh Python reactive document performance probe failed."
}
}
finally {
$env:PYTHONPATH = $previousPythonPath
}